Pythonスクリプトが与えられたら
if __name__ == '__main__':
print("first")
print("second")
print("third")
バッシュスクリプト
#!/usr/bin/env bash
declare -a choice=$( python3 test.py )
echo "You chose "
for c in "${choice[@]}"; do
echo "> ${c}"
done
印刷する必要がある
You chose
> first
> second
> third
しかし、代わりに印刷されます。
You chose
> first
second
third
なぜこれが起こり、どのように解決できますか?
答え1
Pythonスクリプトは3行のテキストを印刷します。配列として読み取るには、次のようにbash
しますreadarray
。
readarray -t chose < <( python3 test.py )
printf '> %s\n' "${chose[@]}"
このreadarray -t
コマンドは、標準入力の行を与えられた配列に読み込みます。プロセス置換を使用してPythonスクリプトから標準入力をリダイレクトします。デフォルトでは、ユーティリティはreadarray
改行文字で終わるテキスト文字列などの個々の行を読み取り、この-t
オプションを使用すると、ユーティリティが読み取ったデータから終了改行文字を削除します。
このprintf
呼び出しは、各配列要素を先行>
および空白とともに印刷します。 (このような配列拡張を提供することによって)複数の引数を指定すると、書式指定printf
文字列を再利用して個々の引数を出力します。これは屋根が必要ないことを意味します。
スクリプトの問題は、Pythonスクリプトの出力を単一の文字列として読み取ることです。コマンド置換は$( python3 test.py )
文字列に展開され、その後手動で解析し、改行を正しい配列要素に分割する必要があります。
あなたはできますダ・ボンバーが提案したとおりシェルにこの分割を実行させますchoice=( $( python test.py ) )
(必須ではありませんdeclare -a
)。ただし、これにより文字列が次に分割されます。どのスペース(デフォルトではスペース、タブ、および改行(の内容$IFS
))。これは、個々の配列要素にスペースを含めたい場合には望ましくないかもしれません。
IFS
1つのオプションは、シェルが改行からデータを分割するように改行に設定することです。ただread
、または次のようにしてreadarray
Pythonbash
コードの出力を読み込みます。
コードの変数名やその他のテキストを見ると、一種のインタラクティブメニューを実装したいようです。
select
これは次の方法で行うこともできますbash
。
readarray -t options < <( python3 test.py )
echo 'Please select your option' >&2
PS3='Your selection: '
select ch in "${options[@]}"; do
[ -n "$ch" ] && break
echo 'Invalid, try again' >&2
done
printf 'You chose option %d ("%s")\n' "$REPLY" "$ch"
これにより、Pythonスクリプトの出力がselect
ループのオプションとして使用されます。ユーザーが有効なオプションを選択するまで、ループは続行されます。最後に選択したオプション(および対応する番号)が印刷されます。
このプロンプトPS3
はで使用されるプロンプトです。デフォルト値の後にはスペースが続きます。select
bash
#?
答え2
declare -a choice=$( python3 test.py )
1長さの配列を作成するようです。
choice[0]='first
second
third'
努力するdeclare -a choice=( $( python3 test.py ) )