Usage of dash (-) in place of a filename
For a command, if using -
as an argument in place of a file name will mean STDIN or STDOUT.
-
But in this example, it creates a file with the name
-
:echo hello > -
How can I make
-
in this example mean STDOUT? -
Conversely, how can I make
-
mean a file named-
in examples such as:cat -
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 < -
).
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.
-
Instead of
echo hello > -
, you can useecho 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.
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.
-
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 |
-
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 ./-
The ‘-‘ approach has a lot of problems. First of all it requires an interpretation of the ‘-‘ character and many programs don’t perform such interpretation. And furthermore, there are some programs that interpret an hyphen as a delimiter marking the end of command line options. The programs are written to work with filename arguments, the ‘-‘ approach is an hack, nice but weak.
The best way is:
$ echo hello > /dev/fd/1
/dev/stdout
is a symbolik link of /dev/fd/1
Special characters have mostly two meanings:
ASCII numeric chart.
Scripting or symbolic.
It’s possible that a single character represents a string, or act as a string. as my understanding.
in C language fopen()
function takes two arguments first file stream and the second mode in which file will be open. the mode is a string. even if it’s single character.
cat > "-" works.