命令替换:修订间差异
Morninghut(留言 | 贡献) 通过翻译页面“Command substitution”创建 |
Morninghut(留言 | 贡献) 小 添加更多引用细节 |
||
第1行: | 第1行: | ||
命令替换是一个实现命令交互的方法。它将一个命令的输出作为参数传给另一个命令。命令替换最初出现在 1979 年 [[Version 7 Unix|Unix 7]] 的 [[Bourne shell]]<ref>{{Cite web|title=The A-Z of Programming Languages: Bourne shell, or sh|url=https://www.arnnet.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/|access-date= |
命令替换是一个实现命令交互的方法。它将一个命令的输出作为参数传给另一个命令。命令替换最初出现在 1979 年 [[Version 7 Unix|Unix 7]] 的 [[Bourne shell]]<ref>{{Cite web|author=Dahdah, Howard|date=2009-03-05|title=The A-Z of Programming Languages: Bourne shell, or sh, An in-depth interview with Steve Bourne, creator of the Bourne shell, or sh|url=https://www.arnnet.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/|access-date=|website=Computerworld}}</ref> 中。这之后在所有的 [[Unix shell]] 中都有它的存在。这一特性后来也被其他[[编程语言]]采用,包括 [[Perl]]、[[PHP]]、[[Ruby]]、[[PowerShell|Powershell]] 以及微软的 [[命令提示字元|CMD.exe]] 中的 FOR 和 ( ) 命令。 |
||
== 语法和解析方式 == |
== 语法和解析方式 == |
||
第10行: | 第10行: | ||
</syntaxhighlight>存在对于语法和解析方式的不同观点和反对意见。 |
</syntaxhighlight>存在对于语法和解析方式的不同观点和反对意见。 |
||
尽管命令替换的语法易于输入(这对交互式命令处理器来说很重要),但由于这种语法下的左右分隔符相同<ref>{{Cite web|last=Jerry Peek|first=Tim O'Reilly & Mike Loukides|date=1998-08-04|title=UNIX Power Tools|url=http://www.c3.hu/docs/oreilly/unix/upt/ch45_31.htm|access-date=2023-05-07|website=1-56592-260-3|language= |
尽管命令替换的语法易于输入(这对交互式命令处理器来说很重要),但由于这种语法下的左右分隔符相同<ref>{{Cite web|last=Jerry Peek|first=Tim O'Reilly & Mike Loukides|date=1998-08-04|title=UNIX Power Tools|url=http://www.c3.hu/docs/oreilly/unix/upt/ch45_31.htm|access-date=2023-05-07|website=1-56592-260-3|language=}}</ref>,因此在遇到嵌套使用时很难使用。[[KornShell|Kornshell]](ksh)<ref>{{Cite book|edition=Second edition|chapter=Learning the Korn shell|url=https://www.worldcat.org/oclc/54115790|publisher=O'Reilly|date=2002|location=Sebastopol, CA|isbn=978-1-4493-7128-9|oclc=54115790|first=Arnold|last=Robbins|title=Learning the Korn Shell|year=2002|pages=127}}</ref> 借鉴了变量替换的语法风格,使用 $( ... ) 解决了这个问题。今天大多数的 Unix shell 和 [[PowerShell|Powershell]] 都支持这种语法。<syntaxhighlight lang="bash"> |
||
#!/bin/sh |
#!/bin/sh |
||
vi $(fgrep -l malloc *.c) |
vi $(fgrep -l malloc *.c) |
||
</syntaxhighlight>将输出按空格做分隔来解析的做法也遭到了批评。这种做法在早期的 [[UNIX|Unix]] 系统上表现良好,因为它的文件名中不包含空格,但在现代的 [[Microsoft Windows|Windows]] 和 [[Linux]] 系统中,由于文件名可能会包含空格,导致这样的解析方式无法正确工作。例如,在先前的两个示例中,如果通配符匹配到的文件名包含空格,该文件名将被拆分成两个单独的参数传给 shell ,这显然和预期不符。[[Hamilton C shell]] 通过双反引号符号 `` ... `` 解决了这个问题:它只在换行符处解析。 |
</syntaxhighlight>将输出按空格做分隔来解析的做法也遭到了批评。这种做法在早期的 [[UNIX|Unix]] 系统上表现良好,因为它的文件名中不包含空格,但在现代的 [[Microsoft Windows|Windows]] 和 [[Linux]] 系统中,由于文件名可能会包含空格<ref>{{Cite book|chapter=8|url=https://www.worldcat.org/oclc/567139717|publisher=Apress|date=2009|location=New York|isbn=978-1-4302-1998-9|oclc=567139717|first=Chris F. A.|last=Johnson|title=Pro Bash Programming: Scripting the Linux Shell|pages=84}}</ref>,导致这样的解析方式无法正确工作。例如,在先前的两个示例中,如果通配符匹配到的文件名包含空格,该文件名将被拆分成两个单独的参数传给 shell ,这显然和预期不符。[[Hamilton C shell]] 通过双反引号符号 `` ... `` 解决了这个问题:它只在换行符处解析。<ref>{{Cite web|author=Hamilton Laboratories|date=2014-12-19|title=Hamilton C shell User guide: I/O redirection: Command substitution|url=https://web.archive.org/web/20141219230358/http://www.hamiltonlabs.com/userguide/07-IORedirection.htm#CommandSubstitution|access-date=|website=web.archive.org}}</ref> |
||
这是一个使用 PowerShell 中的 () 运算符进行命令替换的示例:<syntaxhighlight lang="powershell"> |
这是一个使用 PowerShell 中的 () 运算符进行命令替换的示例:<syntaxhighlight lang="powershell"> |
2023年5月8日 (一) 14:28的版本
命令替换是一个实现命令交互的方法。它将一个命令的输出作为参数传给另一个命令。命令替换最初出现在 1979 年 Unix 7 的 Bourne shell[1] 中。这之后在所有的 Unix shell 中都有它的存在。这一特性后来也被其他编程语言采用,包括 Perl、PHP、Ruby、Powershell 以及微软的 CMD.exe 中的 FOR 和 ( ) 命令。
语法和解析方式
Shell 通常用创建一个子进程的方式实现命令替换。该子进程运行第一个命令,并将它的标准输出通过管道返回给 shell ,shell 会读取得到的输出并以空格作为分隔来解析。在管道关闭或者子进程终止前,shell 会一直等待,因为它无法确定子进程是否完成了全部的输出。因此,shell 会等待第一个子进程运行结束,然后才创建第二个子进程并运行下一个命令。
这个 C shell 示例演示了如何利用 fgrep 搜索包含 malloc 的所有 C 文件,并使用 vi 对搜索到的文件进行编辑。这里的 ` ... ` 是原始风格的语法,即使用反引号作为分隔符。这一风格被所有常见的Unix shell支持。
#!/bin/csh
vi `fgrep -l malloc *.c`
存在对于语法和解析方式的不同观点和反对意见。 尽管命令替换的语法易于输入(这对交互式命令处理器来说很重要),但由于这种语法下的左右分隔符相同[2],因此在遇到嵌套使用时很难使用。Kornshell(ksh)[3] 借鉴了变量替换的语法风格,使用 $( ... ) 解决了这个问题。今天大多数的 Unix shell 和 Powershell 都支持这种语法。
#!/bin/sh
vi $(fgrep -l malloc *.c)
将输出按空格做分隔来解析的做法也遭到了批评。这种做法在早期的 Unix 系统上表现良好,因为它的文件名中不包含空格,但在现代的 Windows 和 Linux 系统中,由于文件名可能会包含空格[4],导致这样的解析方式无法正确工作。例如,在先前的两个示例中,如果通配符匹配到的文件名包含空格,该文件名将被拆分成两个单独的参数传给 shell ,这显然和预期不符。Hamilton C shell 通过双反引号符号 `` ... `` 解决了这个问题:它只在换行符处解析。[5] 这是一个使用 PowerShell 中的 () 运算符进行命令替换的示例:
$MyVariable = (ls)
echo $MyVariable
表达式替换
在相关的编程语言 Common Lisp 和 Scheme 中,可以使用反引号(或称为“准引号”)运算符标记的表达式来调用功能。类似地,在 ABC 编程语言中,可以在文本显示(字符串字面量)中使用反引号括起来的表达式。例如,ABC 语言中的命令 WRITE '2 + 2 = 2+2' 的输出结果为 2 + 2 = 4。
参见
参考资料
- ^ Dahdah, Howard. The A-Z of Programming Languages: Bourne shell, or sh, An in-depth interview with Steve Bourne, creator of the Bourne shell, or sh. Computerworld. 2009-03-05.
- ^ Jerry Peek, Tim O'Reilly & Mike Loukides. UNIX Power Tools. 1-56592-260-3. 1998-08-04 [2023-05-07].
- ^ Robbins, Arnold. Learning the Korn shell. Learning the Korn Shell Second edition. Sebastopol, CA: O'Reilly. 2002: 127. ISBN 978-1-4493-7128-9. OCLC 54115790.
- ^ Johnson, Chris F. A. 8. Pro Bash Programming: Scripting the Linux Shell. New York: Apress. 2009: 84. ISBN 978-1-4302-1998-9. OCLC 567139717.
- ^ Hamilton Laboratories. Hamilton C shell User guide: I/O redirection: Command substitution. web.archive.org. 2014-12-19.