Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

For a command, if using - as an argument in place of a file name will mean STDIN or STDOUT.

  1. But in this example, it creates a file with the name -:

    echo hello > -
    

    How can I make - in this example mean STDOUT?

  2. Conversely, how can I make - mean a file named - in examples such as:

    cat -
    
share|improve this question

4 Answers 4

up vote 24 down vote accepted

Using - as a filename to mean stdin/stdout is a convention that a lot of programs use. It is not a special property of the filename. The kernel does not recognise - as special so any system calls referring to - as a filename will use - literally as the filename.

With bash redirection, - is not recognised as a special filename, so bash will use that as the literal filename.

When cat sees the string - as a filename, it treats it as a synonym for stdin. To get around this, you need to alter the string that cat sees in such a way that it still refers to a file called -. The usual way of doing this is to prefix the filename with a path - ./-, or /home/Tim/-. This technique is also used to get around similar issues where command line options clash with filenames, so a file referred to as ./-e does not appear as the -e command line option to a program, for example.

share|improve this answer
5  
It's worth adding that /dev/stdin and /dev/stdout are universally available and can be used in place of the - convention. –  jmtd Jul 22 '11 at 9:00
    
Also in the cat case, using redirection instead of listing the argument might help: cat <-; however, it would be hard to mix and match that with concatenating more than one file at a time. –  jmtd Jul 22 '11 at 9:02
2  
@jmtd: /dev/std{in,out} are not universally available. Not all unixes have it. –  camh Jul 22 '11 at 10:37
    
Interesting, I assumed they were part of POSIX (but can't confirm). They're present at least on Linux, the BSDs and Solaris. Can you give an example of a modern UNIX that lacks them? –  jmtd Aug 2 '11 at 8:51
  1. Instead of echo hello > -, you can use echo hello > /dev/stdout.

    While '-' is a convention that has to be implemented by each program wanting to support it, /dev/stdin, /dev/stdout and /dev/stderr are, when supported by the OS (at least Solaris, Linux and BSDs do), independent of the application and then will work as you intend.

share|improve this answer

As for 1, the program has to support it. You can't just arbitrarily use it. As for 2, redirect input from (e.g., cat < -).

share|improve this answer

As camh mentioned, - is just a naming convention used by some programs. If you want to refer to these streams with a file descriptor the shell will recognize, jiliagre was correct in having you use the name /dev/stdin or /dev/stdout instead. Those file names should work any place a normal file name would work.

  1. That being said, your first example is kind of silly. Any output that would be caught by the redirect operator to write to a file is already ON standard-output, so redirecting it and writing it back to where it came from is useless. The behavior you use there is the pipe, not a redirect:

    echo hello |
    
  2. In your second example you simply need to give can some indication that you want a litteral file of that name, not the internal alias it has. You can do this easiest by specifying a path to the file like this:

    cat ./-
    
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.