在Shell中,“quote”命令

命令quote的用途是什么?我没有找到任何关于它的信息,它不在/bin文件夹中的可执行文件之列,也不能在Bash内置命令中找到。看起来它只会打印出第一个参数,就像echo命令一样,没有其他功能。

"它只是添加引号" - Hakeem Wahab
1刚刚闲逛时,我发现了一个叫做shell-quote的实用工具,它类似于quote,但在ssh和调试bash脚本等方面有一些用途。想着将其作为脚注包含在这里。'http://linux.die.net/man/1/shell-quote' - Joe
感觉就像是个什么鬼,一个如此常见的词“quote”,竟然被用于如此晦涩的目的……没有任何前缀来标记它为“内部”,也没有文档,除非你深入挖掘发行版高级自动完成机制的实现细节。我觉得这有点令人不安。 - hyde
对于那些母语不是英语的人来说,这变得更加晦涩难懂。就像我一样,例如。 :) - whtyger
3个回答

这是什么?
我注意到这个命令在我的shell(fish,友好的交互式shell)中不起作用。似乎它只在bash(Ubuntu的默认shell)中起作用。
chocobai@pc ~> /bin/bash 
chocobai@pc:~$ quote asdf
'asdf'chocobai@pc:~$ 

chocobai@pc:~$ type quote
quote is a function.
quote ()
{ 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

它是用来做什么的?可以用于什么目的?

它添加引号但不换行。它还以适合bash的方式转义单引号。在脚本中,它可以用于引用变量或其他类型的字符串,非常有用。例如,在具有空格的路径/参数中,您需要使用它。尽管还有其他方法可以实现这一点。

真奇怪,我在网络上找不到任何关于它的文档。但是嗯,很容易看出它的作用。


3which在交互式shell和脚本中都是无用的。请使用type代替。type quote会告诉你它是一个函数,甚至显示函数定义。运行help type以了解更多关于type内建命令的信息。 - geirha
你说得对,谢谢。我看到上面的答案也使用了type来找出它是什么。嗯,多亏了“which”,我知道它不是在/bin/或其他地方的可执行文件,因为它没有返回任何路径。我觉得这还是有点用的。但你说得对,我会加上type命令。 - verpfeilt
2在我的Ubuntu 12.04中,这个功能实际上是在/etc/bash_completion中描述的,默认情况下由~/.bashrc引用,而不是由/etc/bash.bashrc引用,其中关于/etc/bash_completion的部分被注释掉了。此外,在Ubuntu 12.04中不存在/usr/share/bash-completion/文件夹。 - whtyger

quote 是一个函数,它在我的 Debian 系统上被定义(但我猜在 Ubuntu 上也是一样的),它位于文件 /usr/share/bash-completion/bash_completion 中,该文件本身由 Bash 启动时的 /etc/bash.bashrc 引用。

我从不使用这个函数!如果您需要引用一些东西以便能够安全地被 shell 使用,请使用带有 %q 修饰符的 printf,例如:

printf '%q\n' "Hello my friend I like 'single quotes' as well as \"double quotes\""

实际上,即使很少使用这个功能,我们作为用户通常会有更好的高级策略。这个“引用”功能只在一些我们不想了解的模糊内容中内部使用。这个“引用”函数可能是特定于供应商/发行版(即Debian)的,可能根本无法移植,甚至可能在将来的版本中发生变化。
编辑:我刚在一个Ubuntu 12.04系统上进行了检查,发现“引用”函数定义在/etc/bash_completion中,由/etc/bash.bashrc引用,并且/etc/profile又引用了/etc/bash.bashrc。
我是如何确定的呢?使用了一点启发式方法。
  • 检查/etc/profile中是否出现quote:

    grep '\bquote\b' /etc/profile
    

    没有。进行下一步。

  • /etc/profile所源码的文件有哪些?

    grep '[[:space:]]\.[[:space:]]' /etc/profile
    

    我有$i(需要查看源代码以了解其源自何处,但在此情况下,它是文件/etc/profile.d/*.sh(如果存在且可读)和/etc/bash.bashrc。查看/etc/bash.bashrc

  • /etc/bash.bashrc中是否存在quote?是/否等等...

quote实际上可以转义单引号,因此在shell中可用。对于这种用例,它的效果与printf %q一样好用。 - Flimm
@Flimm 使用需自负风险! - gniourf_gniourf
@gniourf_gniourf 我认为 printf %q 的处理方式对波浪号()不正确。请尝试以下命令:`my_str='/.bashrc'; echo '预期结果:' "$my_str"; bash -c "echo ' 引用:' $(引用 "$my_str")"; bash -c "echo 'printf %q:' $(printf '%q\n' "$my_str")"。您将会看到类似于 预期结果: ~/.bashrc引用: ~/.bashrcprintf %q: /home/your_username/.bashrc` 的输出。 - Rockallite
1@Rockallite:我刚刚尝试了一下,结果和预期一样有效... - gniourf_gniourf
1如果你想直接跳到源代码,你可以使用(shopt -s extdebug; declare -F quote),它会告诉你函数的名称、定义的行号以及定义所在的文件名。 - wjandrea

quote是一个函数:

quote () 
{ 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

这个函数在bash初始化文件的某个地方定义。更准确地说,如果你使用的是Ubuntu 13.04,你可以在/usr/share/bash-completion/bash_completion的第142行找到它。
使用以下命令来检查它:
type quote

它的目的显然清楚。

1它的功能很明确 - 但为什么你想做这个可能不明确。为了避免误解:它将用于获取一个变量,比如$INPUT,该变量可能包含空格、引号或其他字符,并返回一个被bash确保仅作为单个参数处理的字符串。 - Ben XO