スクリプトをリモートで実行し、その標準出力を使用して変数を設定しようとしています。一時ファイルを回避するためにこれを行っています。
これが私が試しているパターンです:
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=
一時ファイルを使用せずに目標を達成するにはどうすればよいですか?
これらは、シェルがPOSIXモードで実行されているときにbash
でプロセス置換を実行しようとすると発生するエラーです。 bash
シェルは、POSIXモードでのプロセス置換をサポートしていません。
bash
は、次の場合にPOSIXモードで実行されます
set -o posix
が使用されている、またはsh
として呼び出されています。私の直感は、あなたがスクリプトtest.sh
を持っているか、sh test.sh
で実行しているか、#!/bin/sh
のハッシュバング行があり、sh
がたまたまbash
であることです。別の可能性は、スクリプトがnotに#!
- 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"
POSIX sh
を使用してtest.sh
スクリプトで移植可能な方法でこれを行う場合:
var=$( cat script.sh | bash )
printf 'var="%s"\n' "$var"
これは、標準入力でbash
の出力を読み取るcat
プロセスに影響します。これはnot notプロセス置換バリアントと同じです(標準入力のみを残します)。これは、内部のbash
シェルが実行するスクリプトが、その標準入力からデータの読み取りを行う場合に問題になります。
bash
シェルの標準入力をそのままにする必要がある場合(そこから読み取る必要があるため)、mktemp
が使用可能であると想定して、
var=$( tmpfile=$(mktemp); cat script.sh >"$tmpfile" && bash "$tmpfile"; rm -f "$tmpfile" )
printf 'var="%s"\n' "$var"
cat script.sh
は、後でcurl
コマンドに置き換えられると理解されています。
ファイル記述子のジャグリングに慣れている場合は、bash
シェルを呼び出す前に、ファイル記述子3を標準入力記述子のコピーにして、フェッチされたスクリプトにそれを読み取らせることもできます。
var=$( exec 3<&0; cat script.sh | bash )
printf 'var="%s"\n' "$var"
次に、script.sh
スクリプトはread -u 3
を使用してoriginal標準入力ストリームから読み取るか、utility <&3
を使用してその入力ストリームを別のユーティリティにリダイレクトします。