将命令放在单引号中对 bash 脚本有任何影响吗?
Does putting a command in single quotes have any effect in a bash script?
我偶然发现了一个脚本,作者在其中将每个外部命令(不是内置命令或函数)放在单引号中。由于我以前从未见过这种编码风格,我想知道以下两个示例之间有什么区别:
'cat' $myfile
对比
cat $myfile
请忽略作者选择不引用保存文件名的变量这一事实。我肯定会把它放在双引号中,我知道变量周围引号的影响。我只对命令周围的引号是否有任何影响感兴趣。这两个例子都很好,但据我所知,单引号在这里是多余的。对吗?
谢谢!
是的,它有效果,但主要是出于一个非常神秘的原因:
考虑一下这个奇怪的结构
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
也会跳过函数定义。由于脚本中通常不启用别名,因此很少使用引号。
在大多数情况下,引用没有空格或特殊字符的字符串等同于根本不引用。
但是,在某些情况下引用会有所不同。
防止别名
许多 linux 发行版自动为 ls
或 grep
等程序设置别名,例如:
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: cannot access ~: No such file or directory
测试
[[ ]]
运算符可以使用test
命令,例如-f
、-e
等,但是指令不能被引用。
[[ -e /tmp ]] && echo /tmp exists || echo /tmp is missing
/tmp exists
[[ '-e' /tmp ]] && echo /tmp exists || echo /tmp is missing
-bash: conditional binary operator expected
-bash: syntax error near `/tmp'
结论
在很多情况下,引用确实会有所作为。我觉得第一种情况是你作者写代码的原因。
PS。此列表并不详尽,我特别省略了空格、星号、竖线、& 符号等情况,因为我假设您已经知道为什么有人要引用它们。
我偶然发现了一个脚本,作者在其中将每个外部命令(不是内置命令或函数)放在单引号中。由于我以前从未见过这种编码风格,我想知道以下两个示例之间有什么区别:
'cat' $myfile
对比
cat $myfile
请忽略作者选择不引用保存文件名的变量这一事实。我肯定会把它放在双引号中,我知道变量周围引号的影响。我只对命令周围的引号是否有任何影响感兴趣。这两个例子都很好,但据我所知,单引号在这里是多余的。对吗?
谢谢!
是的,它有效果,但主要是出于一个非常神秘的原因:
考虑一下这个奇怪的结构
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
也会跳过函数定义。由于脚本中通常不启用别名,因此很少使用引号。
在大多数情况下,引用没有空格或特殊字符的字符串等同于根本不引用。
但是,在某些情况下引用会有所不同。
防止别名
许多 linux 发行版自动为 ls
或 grep
等程序设置别名,例如:
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: cannot access ~: No such file or directory
测试
[[ ]]
运算符可以使用test
命令,例如-f
、-e
等,但是指令不能被引用。
[[ -e /tmp ]] && echo /tmp exists || echo /tmp is missing
/tmp exists
[[ '-e' /tmp ]] && echo /tmp exists || echo /tmp is missing
-bash: conditional binary operator expected
-bash: syntax error near `/tmp'
结论
在很多情况下,引用确实会有所作为。我觉得第一种情况是你作者写代码的原因。
PS。此列表并不详尽,我特别省略了空格、星号、竖线、& 符号等情况,因为我假设您已经知道为什么有人要引用它们。