Shell

使用()和$()執行一系列命令的區別

  • July 31, 2020

我目前正在嘗試製作一個腳本,該腳本創建將作為輸入傳遞給 netcat 的字節。

這是腳本的想法:

(perl -e "print \"$BYTES\x00\";

cat file;

perl -e "print \"More bytes\"x16 . \"\r\n\"";) | netcat ip port

我嘗試同時使用子外殼和命令替換(例如,使用 $())來執行命令。但是我不明白為什麼使用命令替換時腳本的輸出是錯誤的。我懷疑命令替換在執行多個命令時錯誤地管道其輸出。有人可以向我解釋為什麼會這樣嗎?

編輯

這是使用命令替換的變體:

$(perl -e "print \"$BYTES\x00\";

cat file;

perl -e "print \"More bytes\"x16 . \"\r\n\"";) | netcat ip port

好的,讓我們分解一下。子shell 在鏈中執行其內容(即,將它們分組)。這實際上具有直覺意義,因為子shell 是通過簡單地將命令鏈用(). 但是,除了在執行時將子shell 的內容組合在一起之外,您仍然可以像使用單個命令一樣使用子shell。也就是說,子shell 仍然有一個stdinstdout因此stderr您可以通過管道將內容傳入子shell 和從子shell 傳出。

另一方面,命令替換與簡單地將命令連結在一起並不是一回事。相反,命令替換的作用有點像變數訪問,但帶有函式呼叫。與命令不同,變數沒有標准文件描述符,因此您不能通過管道將任何內容傳入或傳出變數(一般來說),命令替換也是如此。

為了更清楚地說明這一點,以下是一組可能不清楚(但準確)的範例和一組我認為可能更容易理解的範例。

假設該date -u命令給出以下內容:

Thu Jul  2 13:42:27 UTC 2015

但是,我們想要操縱這個命令的輸出。所以,讓我們把它變成這樣的東西sed

user@host~> date -u | sed -e 's/ /    /g'
Thu    Jul        2    13:42:27    UTC    2015

哇,那很有趣!以下內容完全等同於上述內容(除非您可以在有關您的 shell 的手冊頁中閱讀一些環境差異):

user@host~> (date -u) | sed -e 's/ /    /g'
Thu    Jul        2    13:42:27    UTC    2015

這應該不足為奇,因為我們所做的只是 group date -u。但是,如果我們執行以下操作,我們會得到一些起初看起來有點奇怪的東西:

user@host~> $(date -u) | sed -e 's/ /    /g'
command not found: Thu

這是因為$(date -u)相當於準確地輸入date -u輸出的內容。所以以上等價於以下內容:

user@host~> Thu Jul  2 13:42:27 UTC 2015 | sed -e 's/ /    /g'

當然,這會出錯,因為Thu它不是命令(至少不是我所知道的);它當然不會通過管道傳輸任何東西stdout(因此sed永遠不會得到任何輸入)。

但是,由於我們知道命令替換的行為類似於變數,因此我們可以輕鬆解決這個問題,因為我們知道如何將變數的值通過管道傳遞給另一個命令:

user@host~> echo $(date -u) | sed -e 's/ /    /g'
Thu    Jul        2    13:42:27    UTC    2015

但是,與 bash 中的任何變數一樣,您可能應該用"".

現在,對於可能更簡單的範例;考慮以下:

user@host~> pwd
/home/hypothetical
user@host~> echo pwd
pwd
user@host~> echo "$(pwd)"
/home/hypothetical
user@host~> echo "$HOME"
/home/hypothetical
user@host~> echo (pwd)
error: your shell will tell you something weird that roughly means “Whoa! you tried to have me echo something that isn't text!”
user@host~> (pwd)
/home/hypothetical

我不知道如何描述它比這更簡單。命令替換就像變數訪問一樣工作,其中子shell 仍然像命令一樣執行。

引用自:https://unix.stackexchange.com/questions/213530