在提示字符串中使用变量时如何在 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

相关内容