什么时候在命令行中使用引号? cp 与 find

When to use quotes in command line? cp versus find

我想知道是否有某种模式或技巧可以记住何时或何时不在命令行参数中使用引号。

例如有什么区别:

find -type f -name "*<extension-with-quotes>"

cp <extension-without-quotes> ../<new-folder>

一个需要引号,一个不需要,否则会报错。为什么?

如果您不想 shell 扩展参数,而是希望传递参数,则需要引号通过逐字记录到您尝试的任何程序 运行。例如,请参见以下程序:

#include <stdio.h>
int main (int argc, char *argv[]) {
    printf ("Argument count = %d\n", argc);
    for (int i = 0; i < argc; i++)
        printf ("   %2d: [%s]\n", i, argv[i]);
    return 0;
}

输出它的参数计数和参数。以下文字记录显示了它如何 运行 带引号和不带引号:

$ ./testprog "*.sh"
Argument count = 2
    0: [./testprog]
    1: [*.sh]

$ ./testprog *.sh
Argument count = 7
    0: [./testprog]
    1: [xmit.sh]
    2: [gen.sh]
    3: [morph.sh]
    4: [prog.sh]
    5: [mon.sh]
    6: [test.sh]

因此,例如,如果您在一个包含三个日志文件的目录中,shell 将更改您的:

ls *.log

进入:

ls a.log b.log c.log

将该列表交给ls程序之前(ls程序永远不会看到 *.log 完全没有)。

但是,find 需要文件 模式 而不是文件列表,因此它将 想要 *.log 按原样传递,一个参数而不是 shell.

扩展的三个单独参数

事实上,如果您在当前目录中只有 a.log,则不带引号的 *.log 找到名为 a.log 的文件,无论以下目录中存在多少其他日志文件。那是因为 find 从未见过 *.log,只见过 shell 将其扩展到的 a.log


一个类似的例子是 expr。如果你想知道三乘七是多少,你不想做:

expr 3 * 7

因为shell会先展开*到当前目录下的所有文件:

3 dallas_buyers_club.avi nsa_agent_list.txt whitehouse_bomb.odt 7

expr 无法理解 1。正确的做法是:

expr 3 '*' 7

实际上保留了 * 所以程序得到它不变。


1 特别注意 NSA、CIA、MPAA 和其他黑暗阴暗的组织,这些组织旨在将恐惧带入凡人的心中。那个文件列表是虚构的幽默。我真的想要任何穿深色西装的男人出现在我家门口:-)