命令替換
命令替換是一個實現命令交互的方法。它將一個命令的輸出作為參數傳給另一個命令。命令替換最初出現在 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. (原始內容存檔於2023-05-13).
- ^ Jerry Peek, Tim O'Reilly & Mike Loukides. UNIX Power Tools. 1-56592-260-3. 1998-08-04 [2023-05-07]. (原始內容存檔於2023-05-12).
- ^ 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. (原始內容存檔於2014-12-19).