在bash中执行命令替换的首选方法是什么?
我总是这样做:
echo "Hello, `whoami`."
但是最近,我经常看到它写得像这样:
echo "Hello, $(whoami)."
首选语法是什么?为什么?或者他们几乎可以互换?
我倾向于赞成第一个,只是因为我的文本编辑器似乎知道它是什么,并且适当地进行了语法高亮。
我读过here,在每种情况下,转义字符的行为都有所不同,但我不清楚哪种行为更可取,或者它只取决于具体情况。
附带问题:在一个脚本中使用两个表单是不好的做法,例如在嵌套命令替换时?
答案 0 :(得分:148)
这里有几个问题/问题,所以我会重复海报文本的每一部分,引用块,然后回复我。
首选语法是什么?为什么?或者他们几乎可以互换?
我想说$(some_command)
表单比`some_command`
表单更受欢迎。第二种形式,使用一对反引号(“”字符,也称为反引号和重音符号),是历史的方式。第一种形式,使用美元符号和括号,是一种较新的POSIX形式,这意味着它可能是一种更标准的方式。反过来,我认为这意味着它更可能与不同的shell和不同的* nix实现一起正常工作。
更喜欢第一种(POSIX)形式的另一个原因是它更容易阅读,特别是在嵌套命令替换时。另外,使用反引号形式,反引号字符必须在嵌套(内部)命令替换中进行反斜杠转义。
使用POSIX表单,您不需要这样做。
至于它们是否可以互换,我会说,一般来说,它们是可以互换的,除了你提到的转义字符的例外情况。但是,我不知道也不能说所有现代贝壳和所有现代* nix都支持这两种形式。我怀疑他们这样做,尤其是旧贝壳/旧款* nixes。如果我是你,如果没有在计划运行已完成的脚本的任何shell / * nix实现上对每个表单运行几个快速,简单的测试,我就不会依赖于可互换性。
我倾向于赞成第一个,只是因为我的文本编辑器似乎知道它是什么,并且适当地进行了语法高亮。
很遗憾你的编辑似乎不支持POSIX表格;也许你应该检查你的编辑器是否有支持POSIX方式的更新。可能是远射,但是谁知道呢?或者,也许你应该考虑尝试不同的编辑器。
GGG,你正在使用什么文本编辑器?
我在这里读到,在每种情况下,转义字符的行为都有所不同,但我不清楚哪种行为更可取,或者它只取决于具体情况。
我会说这取决于你想要完成的事情;换句话说,您是否使用转义字符以及命令替换。
附带问题:在一个脚本中使用两个表单是不好的做法,例如嵌套命令替换时?
嗯,这可能会让脚本更容易阅读(从字面上讲),但更难理解!有人在阅读你的剧本(或者你,六个月后读它!)可能会想知道为什么你不只是坚持一种形式或另一种形式 - 除非你在评论中提出一些关于你为什么这样做的说明。另外,在一个脚本中混合两个表单会使该脚本不太可能是可移植的:为了使脚本正常工作,正在执行它的shell必须支持两种形式,而不仅仅是一种形式或另一种形式。
为了使shell脚本易于理解,我个人更喜欢在任何一个脚本中坚持使用一种形式或另一种形式,除非有一个很好的技术理由不这样做。而且,我更喜欢旧版本的POSIX表格;再次,除非有一个很好的技术理由不这样做。
有关命令替换主题以及执行此操作的两种不同形式的更多信息,我建议您参考O'Reilly一书中的“经典Shell脚本”第二版中的命令替换部分,作者:Robbins和Beebe 。在该部分中,作者声明命令替换的POSIX表单“建议用于所有新开发”。我对这本书没有经济利益;它只是我对shell脚本的一个(和爱),虽然它更适用于中间或高级shell脚本,而不是真正用于开始shell脚本。
-B。
答案 1 :(得分:41)
您可以阅读bash manual的差异。在大多数情况下,它们是可以互换的。
有一点需要提及的是,您应该将backquote
转义为嵌套命令:
$ echo $(echo hello $(echo word))
hello word
$ echo `echo hello \`echo word\``
hello word
答案 2 :(得分:8)
反引号与古代shell相兼容,因此需要可移植的脚本(例如GNU autoconf片段)应该更喜欢它们。
$()
形式在眼睛上更容易一些,尤其是经过几次逃脱后。