在 shell 脚本中如何使用 read in echo

sud*_*aju 0 shell-script

echo "my name is=`read` and am from `read`"
Run Code Online (Sandbox Code Playgroud)

预期输出:

my name is=sudhir and am from india
Run Code Online (Sandbox Code Playgroud)

sudhirindia使用输入。

如何实现这一点,我喜欢在 480 个问题中应用它。不知道每个问题所需的用户输入数量。请帮忙。

Sté*_*las 6

read默认情况下,从其输入中读取单词到 variables 中

`cmd`, 的古老形式$(...)捕获命令的输出。默认情况下,read不产生任何输出。当您键入要阅读的内容时,您看到的文本read是终端设备的回声,它不是由read¹输出的。

一些read实现可以输出它们读取的内容。例如,zshread内置函数可以使用-eor -E(后者除了将输入回显外,还将输入存储在变量中)。

所以在zsh

echo "my name is=$(read -e) and am from $(read -e)"
Run Code Online (Sandbox Code Playgroud)

可移植地,您可以读取一行输入(与的特殊读取行为read相反)并使用head -n1. 但是请注意,如果标准输入不是终端设备或可查找文件,大多数head实现将读取多于一行。

许多系统仍然有一个line命令(曾经是标准的,后来被弃用)。

echo "my name is=$(line) and am from $(line)"
Run Code Online (Sandbox Code Playgroud)

应该一次读取一个字节,所以不要读取超过一行的输入。

如果没有,你总是可以效仿的是line具有read

line() {
  IFS= read -r line
  ret=$?
  printf '%s\n' "$line" || return "$ret"
}
Run Code Online (Sandbox Code Playgroud)

或者甚至让它成为

prompt() {
  printf >&2 %s "$1"
  IFS= read -r answer
  printf '%s\n' "$answer"
}

printf '%s\n' "my name is=$(
  prompt "What is your name? ") and am from $(
  prompt "Where are you from? ")"
Run Code Online (Sandbox Code Playgroud)

(这里使用printf代替echoasecho通常不能用于任意数据)。

(与zsh's相同IFS= read -re '?What is your name? ')。

为了完整起见,使用cshtcsh,您可以执行以下操作:

printf '%s\n' "my name is=$< and am from $<"
Run Code Online (Sandbox Code Playgroud)

$< 是 csh 将输入读入变量的方式。

如果您想为每两行输入重复一次,最好使用文本处理实用程序,例如awk

awk '{name=$0; getline place; print "my name is="name" and am from "place}'
Run Code Online (Sandbox Code Playgroud)

¹ 除非read被配置为自己实现行编辑器,例如使用read -einbash或通过设置emacs, gmacsorvi选项 in ksh93(并且 stdin 是终端设备),但随后read会在 stderr 而不是 stdout 上输出回声