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
次のようにします。$b
bash
{
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[*]}"
。