使用 < 時在子 shell 內設定變數

使用 < 時在子 shell 內設定變數

我使用以下方法將命令傳遞到由“newgrp”啟動的子 shell 中。

#!/bin/csh
echo "Before newgrp"
/usr/bin/newgrp users <<EONG
echo "hello from within newgrp"
id
EONG
echo "After newgrp"

只要我不嘗試在子 shell 中「設定」任何內容,它就可以正常工作。

IE

#!/bin/csh
echo "Before newgrp"
/usr/bin/newgrp users <<EONG
echo "hello from within newgrp"
set a=npy
echo $a
id
EONG
echo "After newgrp"

正如您在上面看到的,我在子 shell 中設定了 a=npy 並執行 echo $a 應該會傳回 npy。但是,我看到一個錯誤,因為 a 未聲明。

有人可以告訴我如何在使用時在子 shell 內設定環境變量<<

答案1

這個<<構造引入了一個 shell這裡的文檔它在讀取時被視為雙引號字串,因此變數在被 shell 讀取時立即擴展。如果您啟用告訴您未定義變數的 shell 功能,您會清楚地看到這一點。我將在此處的 BASH shell 中使用該功能:

$ set -o nounset
$ echo "$a"
bash: a: unbound variable
$ bash <<EOF
> a=foo
> echo "$a"
> EOF
bash: a: unbound variable

要阻止 shell 在讀取此處文件時擴展變量,您可以使用單引號標記或反斜杠每一個 用於每一個多變的:

$ bash <<'EOF'
> a=foo
> echo "$a"
> EOF
foo

$ bash <<EOF
> a=foo
> echo "\$a"
> EOF
foo

請注意,此處文件中變數周圍使用的引號類型與讀取此處文件時 shell 是否擴展該變數無關。

附註始終用雙引號引用變數擴展,這樣它們就不會觸發意外的 GLOB 檔案名稱匹配。

聚苯硫醚在 shell 中開啟未定義變數檢查,以擷取輸入錯誤。這會讓你了解你的問題。

點對點不要使用 C shell 編寫腳本。 他們有很多錯誤不一致之處

答案2

您正在使用由字串分隔的此處文件EONG

當用 引入here-documents時<<word,here-document是否會擴展取決於是否有字符單字被引用。當沒有引用任何字元時,此處文件會進行參數擴展、命令替換和算術擴展。當至少一個字元被引用時,這裡的文檔不會被擴展; Bourne 和 Korn(和 POSIX)shell 使用完全不帶引號的單字作為最終分隔符,而 C shell 使用單字照原樣。

您可以將範例重寫為:

#!/bin/csh
echo "Before newgrp"
/usr/bin/newgrp users <<"EONG"
echo "hello from within newgrp"
set a=npy
echo $a
id
"EONG"
echo "After newgrp"

否則,帶有不帶引號的單字,您需要轉義$a\$a防止它在作為 stdin 傳遞到之前被 shell 取代newgrp

#!/bin/csh
echo "Before newgrp"
/usr/bin/newgrp users <<EONG
echo "hello from within newgrp"
set a=npy
echo \$a
id
EONG
echo "After newgrp"

相關內容