循環 python 腳本的輸出時,bash 中的“echo”出現問題
給定python腳本
if __name__ == '__main__': print("first") print("second") print("third")
bash 腳本
#!/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
為什麼會這樣,我該如何解決?
Python 腳本列印三行文本。要將這些讀入數組中
bash
,請使用readarray
:readarray -t chose < <( python3 test.py ) printf '> %s\n' "${chose[@]}"
該
readarray -t
命令將從標準輸入讀取行到給定數組中。使用程序替換從您的 Python 腳本重定向標準輸入。預設情況下,該readarray
實用程序將讀取單個行,即由換行符終止的文本字元串,並且該-t
選項使該實用程序從讀取的數據中刪除終止的換行符。該
printf
呼叫使用前導>
和空格列印每個數組元素。為 提供多個參數printf
,您可以通過給它這樣的數組擴展來做到這一點,它將重用其格式化字元串來輸出每個單獨的參數。這意味著不需要循環。您的腳本的問題是您正在將 Python 腳本的輸出讀入單個字元串。命令替換
$( python3 test.py )
將擴展為一個字元串,然後您必須手動解析並在換行符上拆分為正確的數組元素。您可以按照 Dabombber 的建議進行操作,並讓 shell 為您執行此拆分
choice=( $( python test.py ) )
(declare -a
不需要),但請注意,這會將字元串拆分為任何空格($IFS
預設情況下,空格、製表符和換行符(的內容)),其中如果您希望各個數組元素包含空格,則可能不是您想要的。然後一個選項可能是設置
IFS
為換行符以使 shell僅在換行符上拆分數據,或者使用 讀取 Python 程式碼的輸出read
,這些可能是很好的解決方案,但您有readarray
內置實用程序bash
這使得這更容易。它看起來(從程式碼中的變數名稱和其他文本判斷)您可能想要實現某種互動式菜單。
這也可以用
select
in來完成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
prompt 是 in 使用select
的提示bash
。預設值#?
後跟一個空格。