在提示字串中使用變數時如何在 read -p 命令中使用換行符

在提示字串中使用變數時如何在 read -p 命令中使用換行符

我想在提示中使用cowsay函數時在提示後有一個換行符:

read -p "$(cowsay "do you know this word?") \n" answer

這個問題有多種答案:

1)https://stackoverflow.com/questions/4296108/how-do-i-add-a-line-break-for-read-command/4296147

2)https://stackoverflow.com/questions/12741529/how-to-break-a-line-add-a-newline-in-read-p-in-bash

但是答案使用了''符號,這不能解析cowsay指令

答案1

為什麼要使用-p需要 shell 的選項bash

做就是了:

cowsay "do you know this word?"
read answer

在 中bash,該選項僅在與(另一個使s 的行為類似於s 的擴展)-p結合使用時有用,在某些情況下可能需要重繪提示(例如 on )。但是,當提示有多行時,您可能不需要也不希望它重繪該提示。-ebashbashreadzshvaredbashCtrl+L

如果你願意,你總是可以這樣做:

read -ep "$(cowsay "do you know this word?")"$'\n' answer

(此處使用 ksh93 的$'...'引用形式來理解類似 C 的轉義序列)

或者

read -ep "$(cowsay "do you know this word?")
" answer

更一般地說,問題是命令替換從命令輸出的末尾刪除換行符(不僅僅是一個,所有這些都可以被視為錯誤/錯誤功能1)。

要解決這個問題,通常的技巧是:

output=$(cowsay "do you know this word?"; echo .)
output=${output%.}
read -p "$output" answer

即添加.\n到輸出中。命令替換會刪除 ,\n並且我們會刪除.,留下${output%.}整個命令的輸出(前提是它在除 之外的 shell 中不包含 NUL 字符zsh,並且它是 中當前語言環境中的有效文本yash)。

根據記錄,在其他類似 Korn 的 shell 中,read自行發出提示的語法如下:

read 'answer?prompt: '

當從終端讀取並且已啟用編輯器選項(例如使用set -o emacsset -o vi)時,Korn shell 也會重新繪製該提示。zsh也支援該語法以實現相容性,但行編輯器僅用於vared,而不用於read那裡。


1 例如,它會導致basename=$(basename -- "$file")錯誤,因為它可以從檔案名稱末尾刪除換行符,而不僅僅是由basename

相關內容