' - '运算符在Linux中实际上做了什么?

时间:2012-03-12 09:50:01

标签: linux bash shell unix

我看到-运算符使用不同的命令以不同的方式运行。

例如,

cd - 

cds到上一个目录,而

vim -

stdin

读取

所以我想知道为什么-运算符在这里以两种不同的方式运行。有人能指出我对-运算符的详细文档吗?

4 个答案:

答案 0 :(得分:11)

它不是运营商,而是一个论点。当你用C或C ++编写程序时,它来自argv[1](当它是第一个参数时),你可以用它做任何你想做的事。

按照惯例,许多程序使用-作为stdin的占位符,其中通常需要输入文件名,而stdout则需要输出文件名。但cd不需要读取文件流,为什么需要stdin或stdout?

额外:下面是vim main.c的摘录,用于解析以-开头的参数:如果没有其他字符,则会激活STDIN输入。

    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 */
        }

答案 1 :(得分:2)

破折号本身就是一个简单的命令参数。它的含义取决于命令。它的两个最常见的含义是“标准输入”或(不太常见)“标准输出”。 'previous directory'的含义对于内置的cd shell是唯一的(它只表示在某些shell中,而不是所有shell)。

cat file1 - file2 | troff ...

这意味着在该序列中阅读file1,标准输入和file2,并将输出发送到troff

使用-表示“标准输入”或“标准输出”的极端情况来自(GNU)tar

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

第一个-cf -中的tar选项表示'创建存档','输出文件是标准输出'; -T -选项意味着'从标准输入中读取文件和/或目录列表'。

第二个-xf -中的tar选项意味着'提取存档'和'输入文件是标准输入'。事实上,GNU tar有一个选项-C /some/where/else,这意味着它自己执行cd,所以整个命令可能是:

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

这样做的结果是将generate_file_list命令命名的文件从“当前目录”复制到/some/where/else,保留了目录结构。 ('当前目录'必须使用少量盐;任何绝对文件名都由GNU tar给予特殊处理 - 它删除了前导斜杠 - 并且相对名称被视为相对于当前目录。)

答案 2 :(得分:1)

这取决于它所使用的程序。它对不同的程序意味着不同的东西。

答案 3 :(得分:0)

我认为不同的程序使用不同的约定。联机帮助页显示了每个程序的解释 - 这里是man bash

-
    At shell startup, set to the absolute pathname used to invoke the shell
    or shell script being executed as passed in the environment or argument list.
    Subsequently, expands to the last argument to the previous command, after expansion.
    Also set to the full pathname used to invoke each command executed and placed 
    in the environment exported to that command. When checking mail, this parameter
    holds the name of the mail file currently being checked. 

man vim

 - The file to edit is read from stdin.  Commands are read from stderr, 
    which should be a tty.