子shell中的程序替換以設置變數
我正在嘗試遠端執行腳本並使用其標準輸出來填充變數。我這樣做是為了避免臨時文件。
這是我正在嘗試的模式:
var=$(bash <(curl -fsSkL http://remote/file.sh)) echo "var=${var}"
我正在測試這種模式而不
curl
使用cat
:var=$(bash <(cat ./local/file.sh)) echo "var=${var}"
就語法而言,這應該是相同的。
./local/file.sh
containsecho hello
,所以我希望var
包含 valuehello
,但可惜的是,執行上述結果如下:test.sh: command substitution: line 4: syntax error near unexpected token `(' test.sh: command substitution: line 4: `bash <(cat ./local/file.sh)' var=
如何在不使用臨時文件的情況下實現我的目標?
bash
這些是您在 shell 在 POSIX 模式下執行時嘗試執行程序替換時遇到的錯誤。bash
shell 不支持 POSIX 模式下的程序替換。
bash
將在 POSIX 模式下執行
set -o posix
已使用,或- shell 被呼叫為
sh
.我的預感是你有一個腳本,
test.sh
你正在執行sh test.sh
或者有一個#!/bin/sh
hashbang 行,而你sh
恰好是bash
. 另一種可能性是腳本根本沒有*-line*#!
,它是由bash
-as-sh
以其他方式呼叫的。相反,請確保您的
test.sh
腳本被bash
.例子:
$ cat script.sh echo hello
$ cat test.sh var=$(bash <( cat script.sh )) printf 'var="%s"\n' "$var"
$ bash -o posix test.sh test.sh: command substitution: line 2: syntax error near unexpected token `(' test.sh: command substitution: line 2: `bash <( cat script.sh ))' var=""
$ bash test.sh var="hello"
如果您想
test.sh
使用 POSIX 在腳本中以可移植的方式執行此操作sh
:var=$( cat script.sh | bash ) printf 'var="%s"\n' "$var"
這將產生程序在其標準輸入上
bash
讀取輸出的效果,這與您的程序替換變體(僅保留標準輸入)不太一樣。如果內部shell 執行的腳本從其標準輸入中讀取任何形式的數據,這很重要。cat``bash
如果您需要
bash
單獨保留 shell 的標準輸入(因為您需要從中讀取),您可能會假設它mktemp
可用並使用var=$( tmpfile=$(mktemp); cat script.sh >"$tmpfile" && bash "$tmpfile"; rm -f "$tmpfile" ) printf 'var="%s"\n' "$var"
Where
cat script.sh
被理解為稍後被您的curl
命令替換。如果您對處理文件描述符感到滿意,您還可以在呼叫
bash
shell 之前使文件描述符 3 成為標準輸入描述符的副本,然後讓獲取的腳本從中讀取:var=$( exec 3<&0; cat script.sh | bash ) printf 'var="%s"\n' "$var"
然後該
script.sh
腳本將用於read -u 3
從原始標準輸入流中讀取,或utility <&3
將該輸入流重定向到另一個實用程序。