Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the '-' operator actually do in Linux?

I see the - operator behaving in different ways with different commands.

For example,

cd - 

cds to the previous directory, whereas,

vim -

reads from stdin

So I want to know why the - operator is behaving in 2 different ways here. Can someone point me to some detailed documentation of the - operator?

like image 481
Pavan Manjunath Avatar asked Dec 10 '22 01:12

Pavan Manjunath


2 Answers

It is not an operator, it is an argument. When you write a program in C or C++ it comes as argv[1] (when it is the first argument) and you can do whatever you like with it.

By convention, many programs use - as a placeholder for stdin where an input file name is normally required, and stdout where an output file name is expected. But cd does not require reading a file stream, why should it need stdin or stdout?

Extra: here below is the excerpt from vim's main.c that parses arguments that begin with -: if there is no additional character it activates STDIN input.

    else if (argv[0][0] == '-' && !had_minmin)
    {
        want_argument = FALSE;
        c = argv[0][argv_idx++];
#ifdef VMS
        ...
#endif
        switch (c)
        {
        case NUL:       /* "vim -"  read from stdin */
                /* "ex -" silent mode */
        if (exmode_active)
            silent_mode = TRUE;
        else
        {
            if (parmp->edit_type != EDIT_NONE)
            mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
            parmp->edit_type = EDIT_STDIN;
            read_cmd_fd = 2;    /* read from stderr instead of stdin */
        }
like image 196
Benoit Avatar answered Dec 25 '22 04:12

Benoit


The dash on its own is a simple command argument. Its meaning is command dependent. Its two most usual meanings are 'standard input' or (less often) 'standard output'. The meaning of 'previous directory' is unique to the cd shell built-in (and it only means that in some shells, not all shells).

cat file1 - file2 | troff ...

This means read file1, standard input, and file2 in that sequence and send the output to troff.

An extreme case of using - to mean 'standard input' or 'standard output' comes from (GNU) tar:

generate_file_list ... |
tar -cf - -T - |
( cd /some/where/else; tar -xf - )

The -cf - options in the first tar mean 'create an archive' and 'the output file is standard output'; the -T - option means 'read the list of files and/or directories from standard input'.

The -xf - options in the second tar mean 'extract an archive' and 'the input file is standard input'. In fact, GNU tar has an option -C /some/where/else which means it does the cd itself, so the whole command could be:

generate_file_list ... |
tar -cf - -T - |
tar -xf - -C /some/where/else

The net effect of this is to copy the files named by the generate_file_list command from under the 'current directory' to /some/where/else, preserving the directory structure. (The 'current directory' has to be taken with a small pinch of salt; any absolute file names are given special treatment by GNU tar — it removes the leading slash — and relative names are taken as relative to the current directory.)

like image 30
Jonathan Leffler Avatar answered Dec 25 '22 04:12

Jonathan Leffler