リモートでスクリプトを実行し、標準出力を使用して変数を入力しようとしています。一時ファイルを避けるためにこれを行います。
これが私が試しているパターンです。
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
含んでいるのでその値を含めたいecho hello
のですが、残念ながら上記を実行した結果は次のとおりです。var
hello
test.sh: command substitution: line 4: syntax error near unexpected token `('
test.sh: command substitution: line 4: `bash <(cat ./local/file.sh)'
var=
一時ファイルを使用せずにどのように目標を達成できますか?
答え1
bash
これは、POSIXモードで実行するとシェルがプロセス置換を実行しようとしたときに発生するエラーです。シェルはbash
POSIX モードでのプロセス置換をサポートしません。
bash
次の場合、POSIXモードで実行されます。
set -o posix
使用されたか、- シェルは次のように呼び出されます
sh
。
test.sh
私の直感では、実行中のスクリプトがあるか、ハッシュバンラインがsh test.sh
あり、偶然。もう一つの可能性はスクリプトです#!/bin/sh
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
これは標準入力を読み取るプロセスの出力に影響しますcat
。不完全プロセス交換のバリエーションと同じです(標準入力のみを保持)。内部シェルによって実行されるスクリプトが任意の形式で標準入力からデータを読み取る場合、bash
これは重要です。
シェルの標準入力を別々に保持する必要がある場合bash
(読み取る必要があるため)、使用可能であると仮定してmktemp
使用できます。
var=$( tmpfile=$(mktemp); cat script.sh >"$tmpfile" && bash "$tmpfile"; rm -f "$tmpfile" )
printf 'var="%s"\n' "$var"
後でコマンドcat script.sh
に置き換えられると理解されます。curl
ファイルディスクリプタを扱うことに慣れている場合は、シェルを呼び出す前にファイルディスクリプタ3のコピーを標準入力ディスクリプタにし、インポートしたスクリプトをbash
ここで読み取ることもできます。
var=$( exec 3<&0; cat script.sh | bash )
printf 'var="%s"\n' "$var"
その後、スクリプトを読み取るscript.sh
ために使用されます。read -u 3
オリジナル標準入力ストリームまたはutility <&3
入力ストリームを別のユーティリティにリダイレクトします。