Bash

命令行變數賦值和命令執行

  • January 8, 2021

在研究有關 Bash 子shell 的更深入資訊時,我遇到了一個有趣的執行,我想了解它為什麼起作用。執行涉及將字元串分配給變數,然後在man呼叫時使用該變數,連結到原始範例。我已經閱讀了為什麼LESS在該範例中使用特定變數(在許多發行版manless作為其預設尋呼機),我不明白的是,在沒有任何類型的分隔元字元的情況下,變數賦值和命令執行是如何工作的。

LESS=+/'OPTIONS' man man``man直接在該OPTIONS部分下打開命令的手冊頁。它也適用於直接打開的文件less(這讓我相信該LESS變數的使用方式與在“會話”less中進行正則表達式搜尋的方式相同)。lessLESS變數沒有被導出,它從未保存在目前的 shell 環境中(執行echo $LESS不返回任何內容)那麼如何less擷取該值?

為什麼這行得通,但不是這樣的foo='hello' echo $foo?這種情況僅;在變數賦值和命令執行之間包含命令分隔符 ( ) 時有效。我什至嘗試過在 Bashfoo=+'hello' echo $foo=+做了一些我不知道的事情,但輸出沒有變化。

歡迎任何解釋或閱讀材料!

這是一個標準功能。您可以在啟動命令時設置變數,然後將為命令設置變數。它也適用於您展示的範例,foo='hello' echo $foo. 問題是您正在測試錯誤的方式。當你執行這個:

foo='hello' echo $foo

shell 將在執行命令*之前擴展變數。*由於foo在您啟動它時並未實際設置,因此變為echo (無回顯)。你可以看到這個set -x

$ set -x
$ foo='hello' echo $foo
+ foo=hello
+ echo

現在,將其與您改用一個小腳本以使您的 shell 看不到變數時發生的情況進行比較:

$ cat ~/scripts/foo.sh
+ cat /home/terdon/scripts/foo.sh
#!/bin/bash

echo "The value of foo is:$foo"

用它來回顯變數,你會得到:

$ foo='hello' ~/scripts/foo.sh
+ foo=hello
+ /home/terdon/scripts/foo.sh
hello

如果您呼叫bash -c並用單引號將您給它的命令括起來,您可以做同樣的事情,這樣變數將受到保護,並且在呼叫之前不會被您目前的 shell 擴展bash -c

$ foo='hello' bash -c 'echo $foo'
hello

雖然這失敗了,因為雙引號意味著它在看到它$foo之前就被擴展了:bash -c

$ foo='hello' bash -c "echo $foo"

$

該行為記錄在man bash“環境”部分中:

  The environment for any simple command or  function  may  be  augmented
  temporarily  by  prefixing  it with parameter assignments, as described
  above in PARAMETERS.  These assignment statements affect only the envi‐
  ronment seen by that command.

手冊中也有詳細描述:3.7.1 簡單命令擴展

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