Pythonスクリプトの出力を繰り返すときのbashの「echo」の問題

Pythonスクリプトの出力を繰り返すときのbashの「echo」の問題

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))。これは、個々の配列要素にスペースを含めたい場合には望ましくないかもしれません。

IFS1つのオプションは、シェルが改行からデータを分割するように改行に設定することです。ただread、または次のようにしてreadarrayPythonbashコードの出力を読み込みます。


コードの変数名やその他のテキストを見ると、一種のインタラクティブメニューを実装したいようです。

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はで使用されるプロンプトです。デフォルト値の後にはスペースが続きます。selectbash#?

おすすめ記事