如何在 Bash 中使用 read 命令?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7676045/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:05:51  来源:igfitidea点击:

How to use the read command in Bash?

bashbuilt-in

提问by Determinant

When I try to use the readcommand in Bash like this:

当我尝试read在 Bash 中使用该命令时:

echo hello | read str
echo $str

Nothing echoed, while I think strshould contain the string hello. Can anybody please help me understand this behavior?

没有回显,而我认为str应该包含字符串hello. 有人可以帮我理解这种行为吗?

回答by jpalecek

The readin your script command is fine. However, you execute it in the pipeline, which means it is in a subshell, therefore, the variables it reads to are not visible in the parent shell. You can either

read脚本中的命令是好的。但是,您在管道中执行它,这意味着它在子 shell 中,因此,它读取的变量在父 shell 中不可见。你可以

  • move the rest of the script in the subshell, too:

    echo hello | { read str
      echo $str
    }
    
  • or use command substitution to get the value of the variable out of the subshell

    str=$(echo hello)
    echo $str
    

    or a slightly more complicated example (Grabbing the 2nd element of ls)

    str=$(ls | { read a; read a; echo $a; })
    echo $str
    
  • 也在子shell中移动脚本的其余部分:

    echo hello | { read str
      echo $str
    }
    
  • 或者使用命令替换从子shell中获取变量的值

    str=$(echo hello)
    echo $str
    

    或者稍微复杂一点的例子(获取 ls 的第二个元素)

    str=$(ls | { read a; read a; echo $a; })
    echo $str
    

回答by glenn Hymanman

Other bash alternatives that do not involve a subshell:

其他不涉及子 shell 的 bash 替代方案:

read str <<END             # here-doc
hello
END

read str <<< "hello"       # here-string

read str < <(echo hello)   # process substitution

回答by Shizzmo

Typical usage might look like:

典型用法可能如下所示:

i=0
echo -e "hello1\nhello2\nhello3" | while read str ; do
    echo "$((++i)): $str"
done

and output

和输出

1: hello1
2: hello2
3: hello3

回答by l0b0

The value disappears since the read command is run in a separate subshell: Bash FAQ 24

由于 read 命令在单独的子 shell 中运行,该值消失了:Bash FAQ 24

回答by RAKK

To put my two cents here: on KSH, reading as is to a variable willwork, because according to the IBM AIX documentation, KSH's readdoesaffects the current shell environment:

把我的两分钱放在这里:在 KSH 上,read按原样对变量进行操作是可行的,因为根据IBM AIX 文档,KSHread确实会影响当前的 shell 环境:

The setting of shell variables by the read command affects the current shell execution environment.

read命令对shell变量的设置会影响当前的shell执行环境。

This just resulted in me spending a good few minutes figuring out why a one-liner ending with readthat I've used a zillion times before on AIX didn't work on Linux... it's because KSH does saves to the current environment and BASH doesn't!

这只是导致我花了几分钟弄清楚为什么read我之前在 AIX 上使用了无数次的单行结尾在 Linux 上不起作用......这是因为 KSH 确实保存到当前环境和 BASH没有!

回答by HymanDR

I really only use read with "while" and a do loop:

我真的只将 read 与 "while" 和 do 循环一起使用:

echo "This is NOT a test." | while read -r a b c theRest; do  
echo "$a" "$b" "$theRest"; done  

This is a test.
For what it's worth, I have seen the recommendation to always use -r with the read command in bash.

这是一个测试。
就其价值而言,我已经看到了在 bash 中始终将 -r 与 read 命令一起使用的建议。

回答by jxqz

Another alternative altogether is to use the printf function.

另一种选择是使用 printf 函数。

printf -v str 'hello'

Moreover, this construct, combined with the use of single quotes where appropriate, helps to avoid the multi-escape problems of subshells and other forms of interpolative quoting.

此外,这种结构与在适当情况下使用单引号相结合,有助于避免子外壳和其他形式的插值引用的多重转义问题。

回答by mmrtnt

Do you need the pipe?

你需要管子吗?

echo -ne "$MENU"
read NUMBER