変数を設定するためにサブシェルで置換

変数を設定するためにサブシェルで置換

リモートでスクリプトを実行し、標準出力を使用して変数を入力しようとしています。一時ファイルを避けるためにこれを行います。

これが私が試しているパターンです。

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のですが、残念ながら上記を実行した結果は次のとおりです。varhello

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モードで実行するとシェルがプロセス置換を実行しようとしたときに発生するエラーです。シェルはbashPOSIX モードでのプロセス置換をサポートしません。

bash次の場合、POSIXモードで実行されます。

  1. set -o posix使用されたか、
  2. シェルは次のように呼び出されますsh

test.sh私の直感では、実行中のスクリプトがあるか、ハッシュバンラインがsh test.shあり、偶然。もう一つの可能​​性はスクリプトです#!/bin/shshbashいいえ#!-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.shPOSIXを使用して移植可能な方法でスクリプトでこれを実行するには、次のようにします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入力ストリームを別のユーティリティにリダイレクトします。

関連情報