
Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: March 18, 2024
In this tutorial, we’ll see what the “-” character is about and what purpose it serves. We’ll take a look at the most common use-cases where the use of “-” makes more sense than alternative approaches.
The “-” character means different things to different commands on the Linux terminal. There is no universal convention for using the “-” character with the Linux commands. However, on the most commonly used shells like bash and zsh, the “-” character is used to specify a standard input or a standard output for a command. It’s a command-specific convention for many Linux utilities.
On the other hand, other tools or commands on Linux might have a different use-case for the “-” character. For instance, we use the “-” with the git command to specify a repository branch. For other tools that expect a file as an input, like tar, the “-” character is used to treat the output of another command as the contents of an input file. Hence, we do not need to specify a file path to the command.
Most of the commands on Linux treat the string “-” as a synonym for stdin or stdout. So, for instance, when we use the cat command with a naked “-“, it will read from stdin:
$ cat -
I am being echoed.
I am being echoed.
The “-” in the above command is actually an alias for /dev/stdin. Therefore, we can also replace the “-” with /dev/stdin, and nothing will change:
$ cat /dev/stdin
Echo this.
Echo this.
So, it begs the question, what is /dev/stdin? Well, /dev/stdin is a symbolic link to /proc/self/fd/0. The /proc/self/fd/0, in turn, is a symbolic link to the standard input of our current shell process, which is our terminal. For that reason, we’re able to input text to the cat command using our terminal.
Similarly, we can use the tar command to extract a tarball and print it to stdout. The contents of the tarball printed to stdout will act as input to the tar command, which will untar the contents and write them to the disk as shown in the following snippet:
$ <htop-2.2.0.tar.gz | tar -xzf -
Let’s break it down:
Another practical use-case of using tar with “-” is when we want to download a remote file and extract it once it is downloaded. We can use curl to print the text or binary output of the downloaded file to the stdout. Then, we can pipe whatever is printed to the stdout to tar and specify the contents of the stdout as stdin:
$ curl -L https://github.com/hishamhm/htop/archive/refs/tags/2.2.0.tar.gz --output - | tar zxf -
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 130 100 130 0 0 135 0 --:--:-- --:--:-- --:--:-- 135
100 168k 0 168k 0 0 77436 0 --:--:-- 0:00:02 --:--:-- 309k
$ ls -lF
drwxr-xr-x hey hey 4.0 KB Wed Dec 1 22:41:43 2021 htop-2.2.0/
In the same way, we can also use “-” to specify a standard output for a specific command. In our curl example, we used “-” to print the binary output of the remote file to our standard output:
$ curl -L https://github.com/hishamhm/htop/archive/refs/tags/2.2.0.tar.gz --output -
E�P��7�&�3Dq�"!GKvL�[f>��GY6as<Hl�'�)2'AS�*��~맊VT#a;�}x܍ҋ�zN
�8YWslw>���bmLf-~r+�����ju��WTr
��υ<��u�kIM�wyfٚ9~a9
...
As we can see, we explicitly told the curl command to output the contents of the binary file because, by default, curl will not print binary contents to stdout. Like stdin, when “-” is used in the context of stdout, it’s an alias for /dev/stdout.
So, one might wonder why we print the binary output to our standard output. Well, we can do a lot of useful tasks with it. In our next example, we’ll write a command that basically downloads a picture using curl and then creates a favicon out of the image using ImageMagick. Once the image is resized, we’ll convert it to base64 and POST the result to an endpoint. We’ll do all these tasks only by reading and writing to stdin and stdout, without having to save the contents in a file on the disk:
$ curl https://upload.wikimedia.org/wikipedia/commons/4/45/Linux-for-workgroups-boot.jpg --output - \
| convert - -resize 16x16 png:- \
| base64\
| curl -X POST --data @- -H 'Content-Type: text/plain' https://example.com/favicon
Let’s break it down:
As we can see, we used the “-” for both stdin and stdout. It’s up to the command itself to interpret it accordingly. Of course, we can replace “-” with /dev/stdin and /dev/stdout, and the result will be the same.
As we know, the “-” means different things to different commands. In the case of git, we can use it as an argument to the git checkout command to check out the previous active branch or detached HEAD. For instance, if we have a Git repository and two branches on the repository, we can switch between those two branches by using “-“:
$ git branch -a
*master
dev
$ git checkout dev
$ git branch -a
master
*dev
$ git checkout -
$ git branch -a
*master
dev
Similarly, as with the git command, we can also use “-” as an argument to the cd command to switch between the current and the previous directory.
Let’s see it in action:
$ pwd
/home/hey/github
$ cd TestApp
$ pwd
/home/hey/github/TestApp
$ cd -
$ pwd
/home/hey/github
$ cd -
$ pwd
/home/hey/github/TestApp
Our shell stores the old path in an environment variable known as $OLDPWD. Therefore, the “-” parameter acts as an alias for $OLDPWD:
$ echo $OLDPWD
/home/hey/github/TestApp
$ cd $OLDPWD
$ pwd
/home/hey/github/TestApp
$ echo $OLDPWD
/home/hey/github
As we saw, it’s up to each tool or command to interpret the “-” parameter. However, many other tools use the “-” parameter for different purposes. The most common and reliable way to find out whether a tool has support for the “-” parameter is to go through its official manpages.
In this article, we looked at the meaning of using “-” in the Linux command-line and how it is interpreted by the most common commands. We also saw a few use cases where we can use “-” to read from stdin and write to stdout.
Finally, we saw how to use “-” with git and cd commands.