45

cd - can switch between current dir and previous dir.

It seems that I have seen - used as arguments to other commands before, though I don't remember if - means the same as with cd.

I found that - doesn't work with ls.

Is - used only with cd?

Tim
  • 101,790
  • 8
    Something to keep in mind is that cd is a builtin, not an external command (nor would it have any way of even working as one). cd - is thus a shell-level feature. – fluffy Jul 28 '14 at 08:23
  • 6
    I use all the time git checkout - to switch to the previous branch – wim Jul 28 '14 at 12:37
  • @fluffy: Are - used with other builtins in the same way? – Tim Jul 28 '14 at 12:40
  • For some of the directory-handling builtins like pushd, yes. Otherwise, the meaning of "the previous directory" is not a terribly useful default. – fluffy Jul 28 '14 at 19:35
  • 1
    Perhaps you're thinking of the '~-' feature of bash (which is interpreted as $OLDPWD). That can be used with 'ls' in the manner you describe. – abonet Aug 03 '14 at 14:29

7 Answers7

46

- is defined in POSIX Utility Syntax Guidelines as standard input:

Guideline 13:
For utilities that use operands to represent files to be opened for either 
reading or writing, the '-' operand should be used to mean only standard input 
(or standard output when it is clear from context that an output file is being 
specified) or a file named -.

You can see this definition for utilities which operate with files for reading or writing. cd does not belong to these utilities, so - in cd does not follow this guideline.

Besides, POSIX also defined - has own meaning with cd:

-
    When a <hyphen> is used as the operand, this shall be equivalent to the 
    command:

    cd "$OLDPWD" && pwd

    which changes to the previous working directory and then writes its name.
cuonglm
  • 153,898
36

cd - is actually shorthand for cd "$OLDPWD" && pwd, where $OLDPWD is set each time you change directories to the directory you were just in.

Handling of - depends on the application. Some applications use - to signify STDIN, e.g. grep, awk

Other applications may use - as a shorthand for anything they choose, as Michael's answer specifies, with su, - is shorthand for --login

cuonglm
  • 153,898
Lawrence
  • 2,302
  • yes indeed there's no rule for that. – Kiwy Jul 28 '14 at 07:55
  • 2
    @Kiwy: With POSIX, there is a rule for that, see my answer. – cuonglm Jul 29 '14 at 16:30
  • To be precise, there's a general rule, but it has many exceptions. There are also lots of commands that predate the rule, or old implementations that have not been updated to conform to the rule. – Barmar Jul 30 '14 at 20:48
23

The POSIX utility syntax guidelines (specifically #13) specify that for utilities that expect a file name to read from, - means standard input, and for utilities that expect a file name to write to, - means standard output. For example, cat somefile - copies the content of somefile to its standard output, followed by what it reads on its standard input.

This guideline doesn't apply to the cd command since it doesn't read or write to a file. cd does something different: the argument - means “the previous directory”. The command cd - is equivalent to cd "$OLDPWD" && pwd. This behavior is specific to the cd command, and to directly inspired commands such as pushd.

Note that - is an operand, not an option. Only arguments that begin with - and are not just - or -- are options. The main implication of being an operand is that -- doesn't affect its special meaning. For example, cd -- -P changes to a subdirectory called -P, but cd -- - is the same as cd -, it doesn't change to a directory called -. Similarly, cat -- - doesn't read from a file called - but from standard input.

19

Though Michael mentions that su and other applications can use - to mean whatever they want (read from stdin is common), Git does use - in a fashion similar to how cd does, for changing branches.

$ git status
On branch master

$ git checkout foobar
$ git status
On branch foobar

$ git checkout -
$ git status
On branch master
dotancohen
  • 15,864
18

Any program can use - as an argument, to mean whatever they want. One common example is su, which uses - as shorthand for --login. The only convention I can think of is that programs that read from files frequently use - to mean "read from stdin", but it's entirely up to the program

Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • Are there standard or nonstandard conventions for using special symbols as arguments? – Tim Jul 28 '14 at 05:40
2

Adding my two cents here. I use '-' to tell the ps2pdf tool to read from standard input, as several people have suggested previously:

man -t ls | ps2pdf - ls.pdf

The above one-liner creates a pdf version of the man page for ls in the current directory.
Hope someone finds it useful :).

gacanepa
  • 303
2

As answered by gnouc, - has its own meaning in cd.

However, you can replicate the behavior of - in other programs using ~-. For example:

cd /etc
cd /
ls ~-             #lists the contents of the /etc directory
vim ~-/fstab      #opens the file /etc/fstab in vim