You’ve probably started an application from the terminal at some point, but did you notice that it keeps your terminal occupied until you close the application? That can be pretty annoying. Sometimes, though, it’s useful to launch applications this way—I explain how I do it effectively.
Some people use menus, others use launchers—I personally launch all applications, like Firefox, from the terminal. This habit goes back to my earliest days using Linux (about 15 years ago), when I didn’t know how to create shortcuts. Over time, I grew accustomed to launching applications this way, and since I always have a terminal window open, it just makes sense. Plus, I’m too lazy to set up and maintain a launcher configuration. With the terminal, I can fuzzy search my applications like a launcher, but with the added benefit of editing commands before launching them.
First, Understand Nohup and the Background Operator
When you open an application from the terminal and then close the terminal, the application will often close too—which probably isn’t what you want. On Linux, when one application starts another, it forks the process, so the original application becomes the parent.
When you kill the parent process, all of its child processes are also typically terminated. You can try it yourself: type the following command in a terminal, wait for it to start, and then close the terminal window.
firefox
To keep the child processes running after you close the terminal, we’ll use a time-tested tool called nohup.
Nohup
The nohup command makes a process ignore the hang-up signal (SIGHUP), allowing it to continue running even after the user logs out or the terminal session ends.
Now that we have a way to keep our process running after the terminal is closed, it’s worth noting that nohup will automatically write output to a nohup.out file in the current directory. Unless you want these files scattered throughout your file system, you’ll need to address this behavior. You can either discard all output or redirect it to a specific file for logging.
To ignore all output, simply redirect everything to /dev/null, which acts as a black hole for unwanted data:
nohup firefox &>/dev/null
Now, if you close the terminal, Firefox will keep running. However, this setup sends all logs to the void. Alternatively, you can redirect output to a log file instead:
nohup firefox &>/tmp/firefox.log
Now, if there’s a problem with Firefox, you can read the log file.
Background Operator
When you run nohup with Firefox, it takes over your command line, which means you can’t run other commands. This isn’t ideal if you want to use the same terminal for other things. That’s where the background operator comes in.
The background operator is simply an ampersand placed at the end of the command, allowing you to keep using the terminal while the application runs. Give it a try:
firefox &
If you close your terminal now, you’ll notice that it also closes the application. This is because, while the background operator puts your application in the background, it still obeys the SIGHUP signal—so closing the terminal stops the process. That’s why we use nohup as well.
One useful feature of the background operator is that you can bring a process back to the foreground. After sending Firefox to the background, type fg to bring it to the foreground again.
Using nohup with the Background Operator
By using nohup with the background operator, your application runs entirely in the background, letting you keep working in your terminal or even close it—your process will continue running uninterrupted.
nohup firefox &>/tmp/firefox.log &
Use Mnemonic Aliases
A shell alias works like a nickname for a command. For instance, you can set the letter f to launch Firefox, so you only have to type f in the terminal to open it. If this is new to you, you should read our post on how to create shell aliases.
In the world of shell customization, it’s common to use mnemonic aliases—short, memorable combinations of letters that represent longer commands. For example, you might create Firefox shortcuts that launch the browser with specific arguments:
alias ffaa="firefox about:about"
alias ffac="firefox about:config"
alias ffnt="firefox --new-tab"
alias ffp="firefox --profile"
alias ffsm="firefox --safe-mode"
By ordering the aliases alphabetically, it’s easier to see which aliases have already been used.
You may want to use nohup and the background operator to launch Firefox.
Use Fuzzy Shell History
The most useful shell utility you’ll ever install is a fuzzy history tool. Atuin is an application that does just that, and it works anywhere. I personally use zsh-fzf-history-search, which is a Zsh plugin, but both are almost identical.
If you spend time laboriously typing out a long command, it makes sense to have a quick way to execute it again. I often spend a minute or two constructing a complex command, then use fuzzy shell history to run it hundreds of times over months or even years.
If you take away just one thing: use a fuzzy shell history plugin or application. I recommend Atuin. If you’re interested, we have an introduction to Atuin.
A Flat File of Commands
The idea behind fuzzy shell history is simple—it collects your shell history, removes a few unnecessary details, and sends the result to a program called FZF. We shall do something similar, except we will use FZF to pick our commands from a plain old text file so we can execute them.
FZF is designed to help you quickly select items from long lists. It’s an essential tool that’s part of any advanced shell toolkit, and if you want to improve your terminal skills, I highly recommend learning how to use it. FZF is easy to pick up and includes many advanced features for more experienced users.
The following is the simplest example that demonstrates how FZF can be used to search through multiple lines of text:
echo "foo\nbar" | fzf
When you start typing, FZF narrows down the list dynamically, updating the options in real time. Once you make a selection, FZF prints your chosen entry. Most users send that choice to another command for further processing. For example, with echo “foo\nbar” | fzf | tr ‘[:lower:]’ ‘[:upper:]’, your selected word is converted to uppercase.
Now we want to build and search over our own command list. First, create a file with commands in it:
echo "ls -al\ndir" > ~/.commands
Then add the following function to your .bashrc file. If you don’t know what that is, we have an article that explains what the .bashrc file is:
fe() {
  eval "$(fzf <"${HOME}/.commands" || return)"
}
Reload your shell with source ~/.bashrc, and run fe (fuzzy execute). When you select a command, it executes automatically. You are free to add any commands to the “~/.commands” text file.
If you’re on Zsh, you have the luxury of being able to edit the commands before executing them. In your .zshrc file put:
fe() {
  print -z "$(fzf <"${HOME}/.commands" || return)"
}
Now when you run this, it will populate your command line first, and you can edit it or simply hit return to run it.
Now that you know how to fully send commands to the background, you can safely launch applications from the terminal without cluttering your workspace with multiple terminal windows. You can add these commands—along with nohup and the background operator—to your command file or your shell history to rapidly launch applications. For commands with complex parameters, aliases are useful.
I use all of these principles to quickly launch applications from the terminal. While dedicated launchers are a much better solution, sometimes you just want to run something directly in the terminal for convenience. Now it’s easier than ever.