在Linux中,“-”运算符实际上是做什么用的?

4

我看到-操作符在不同的命令中有不同的行为。

例如,

cd - 

cds命令用于返回上一个目录,而

vim -

从标准输入中读取数据

因此我想知道为什么这里的-运算符表现出两种不同的方式。有人能指向一些详细的-运算符文档吗?

4个回答

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

非常感谢您详细的回答。我应该如何知道不同(标准)命令如何使用它?如果程序决定如何使用它,为什么不能使用其他符号,如“!”或“#”? - Pavan Manjunath
@Stacker:每个好的程序都有良好的文档。应该记录如何调用程序以及命令行接受什么参数。在vim中,我承认这并不容易,但你可以在:help --找到它(多么令人困惑,但是:help -会跳转到正常模式下的-命令)。 - Benoit

3

破折号本身是一个简单的命令参数。它的含义取决于命令。最常见的两种意义是“标准输入”或(较少)“标准输出”。“上一个目录”的含义只有在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 - )

第一个tar命令中的-cf和-选项分别表示“创建存档”和“输出文件是标准输出”,-T -选项表示“从标准输入读取文件和/或目录列表”。
第二个tar命令中的-xf和-选项分别表示“提取存档”和“输入文件是标准输入”。实际上,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会特殊处理任何绝对文件名——它会删除前导斜杠——而相对名称被视为相对于当前目录。)

1

这取决于它所使用的程序。对不同的程序来说,它意味着不同的事情。


0

我认为不同的程序使用不同的约定。man页面显示每个程序如何解释“-”,这里是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.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接