Bash

循環 python 腳本的輸出時,bash 中的“echo”出現問題

  • July 27, 2019

給定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這使得這更容易。


它看起來(從程式碼中的變數名稱和其他文本判斷)您可能想要實現某種互動式菜單。

這也可以用selectin來完成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循環中的選項。循環將繼續,直到使用者選擇了有效選項。最後,列印選擇的選項(及​​其編號)。

PS3prompt 是 in 使用select的提示bash。預設值#?後跟一個空格。

引用自:https://unix.stackexchange.com/questions/532414