バックティックまたは励起文字列または読み取りは、RHEL 8で期待どおりに機能しません。

バックティックまたは励起文字列または読み取りは、RHEL 8で期待どおりに機能しません。

Pythonスクリプトの出力をインタラクティブシェルスクリプトの入力にリダイレクトしようとしています。

test.py

print('Hello')
print('world')

上記のようにtest.pyを教えてください。「こんにちは世界」これは2つの変数を使用して提供されます。ここにある文字列次のようにリダイレクト

対話型スクリプト: read a b <<< `python3 test.py`

Rhel 8サーバーでは期待どおりに動作しませんが、Rhel 7では正常に動作します。

リエル8:

tmp> read a  b  <<< `python3 test.py`
tmp> echo $a $b
Hello
tmp> cat /etc/redhat-release
Red Hat Enterprise Linux release 8.3 (Ootpa)

変数bは空です。RHEL 8から

リエル7:

tmp> read a  b  <<< `python3 test.py`
tmp> echo $a $b
Hello world
tmp> cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.8 (Maipo)

そしてここから文字列を読む(&H)下図のように、どちらの場合もうまく機能します。

tmp> read a b <<< Hello world"
tmp> echo $a $b
Hello world

答え1

read a bで2つの単語を読む一つ行($IFS文字で区切られた単語、エスケープされた単語、行区切り記号\

スクリプトpythonは2行を出力します。

以前のバージョンにはbashバグがあるか、cmd <<< $varトークン化を拡張に適用し、cmd <<< $(cmd2)結果要素を空白に再リンクしました。これは実際にここの文字列の内容を構成します(例を参照)。$var$(cmd2)bashのカットが失敗するのにzshが失敗するのはなぜですか?)。

この問題はバージョン 4.4 で解決され、なぜ何も得られなかった理由が説明されています。あなたもっと期待しています。

コマンド出力の最初の2行を変数として読み取るには、$a次のようにします。$bbash

{
  IFS= read -r a
  IFS= read -r b
} < <(cmd)

または(対話型シェルでない場合):

shopt -s lastpipe
cmd | {
  IFS= read -r a
  IFS= read -r b
}

またはlastpipe

cmd | {
  IFS= read -r a
  IFS= read -r b
  something with "$a" and "$b"
}
# $a and $b will be lost after the `{...}` command group returns

コマンド出力行をスペースで連結するには、次のようにしますcmd | paste -sd ' ' -。これにより、次のことができます。

IFS=' ' read -r a b < <(cmd | paste -sd ' ' -)

あなたが望むなら。

以下を使用して、行を配列要素として読み取ることもできます。

readarray -t array < <(cmd)

そして、配列の要素を最初の文字$IFS(デフォルトは空白)に関連付けます"${array[*]}"

関連情報