【问题标题】:Does putting a command in single quotes have any effect in a bash script?将命令放在单引号中是否对 bash 脚本有任何影响?
【发布时间】:2020-06-02 16:06:41
【问题描述】:

我偶然发现了一个脚本,作者将每个外部命令(不是内置命令或函数)都放在单引号中。由于我以前从未见过这种编码风格,我想知道以下两个示例之间有什么区别:

'cat' $myfile

对比

cat $myfile

请忽略作者选择不引用保存文件名的变量这一事实。我肯定会把它放在双引号中,并且我知道变量周围引号的影响。我只是对命令周围的引号是否有任何影响感兴趣。这两个示例都可以正常工作,但我的理解是单引号在这里是多余的。对吗?

谢谢!

【问题讨论】:

  • 我只在 shell 脚本中看到路径中有空格的命令使用引号,这在 Win10 中使用 Bash 时经常发生。也许这是作者养成的习惯。但在这种情况下是多余的。

标签: bash shell quotes


【解决方案1】:

是的,它有效果,但主要是出于一个非常神秘的原因:

考虑一下这个奇怪的结构

alias cat='echo x'
cat foo # would output x foo
'cat' foo # Would output the content of the file foo

将它放在引号内会导致 bash 不运行别名。也可以使用

command cat foo # Also outputs the file foo

不同之处在于,将命令放在引号中只会跳过别名定义,而使用command 也会跳过函数定义。由于脚本中通常不启用别名,因此很少使用引号。

【讨论】:

  • 谢谢!这解释了一切。(好吧,除了为什么作者关心这种极端情况但不引用可能不太可信的用户输入衍生的变量的问题......但我没有问那个,所以;))
【解决方案2】:

在大多数情况下,引用没有空格或特殊字符的字符串严格等同于根本不引用。

但是,在某些情况下,引用会有所不同。

防止别名

许多 Linux 发行版会自动为 lsgrep 等程序设置别名,例如:

alias ls='ls --color=auto'
alias grep='grep --color=auto'

如果调用引用的命令,别名不会被扩展:

ls / # shows the root files and folders with colors
'ls' / # shows the root files and folders without any color

即使命令被部分引用也不使用别名:

'l's / # shows the root files and folders without any color

(不过,我强烈建议不要这样做)

保留关键字

某些关键字不能被引用。例如,这将起作用:

time cat $myfile

但这会失败:

'time' cat $myfile

-bash: time: command not found

波浪号扩展

波浪号~ 可用于访问主目录。单独指向当前用户的主目录:

ls ~

当直接跟用户名时,它指向该用户的主目录:

ls ~root

引用波浪号时,目录不会展开,shell 会尝试查找包含波浪号的文件:

ls '~'

ls: 无法访问~: 没有这样的文件或目录

测试

[[ ]] 操作符可以使用test 命令,如-f-e 等,但不能引用该指令。

[[ -e /tmp ]] && echo /tmp exists || echo /tmp is missing

/tmp 存在

[[ '-e' /tmp ]] && echo /tmp exists || echo /tmp is missing

-bash:需要条件二元运算符

-bash: `/tmp' 附近的语法错误

结论

在很多情况下,引用确实会产生影响。我认为第一种情况是您的作者编写代码的原因。

PS。这个列表并不详尽,我特别省略了空格、星号、管道、& 号等情况,因为我假设你已经知道为什么有人要引用它们。

【讨论】:

  • 感谢您的广泛回答。 user1934428 已经涵盖了别名情况,正如您所说,这可能是作者选择这样做的原因。有问题的命令都是基本的 unix/GNU 工具,例如 cat、date、mkdir 等。因此,您列出的其他示例在这里不适用。
  • @Timo 如果作者引用了关键字,则保留关键字可能适用于您的案例,例如如果出于某种原因他想实现自己的timeread 程序,那么引用这些调用将确保调用他的实现而不是内置命令。
猜你喜欢
  • 2022-07-21
  • 2016-01-22
  • 1970-01-01
  • 2020-04-06
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
相关资源
最近更新 更多