如何将多行输入从标准输入读取到变量中以及如何在 shell(sh,bash) 中打印一个输出?
题
我想做的是:
- 读取多行输入
stdin
进入变量A
- 进行各种操作
A
- 管道
A
不丢失分隔符(\n
,\r
,\t
等)到另一个命令
当前的问题是,我无法读取它 read
命令,因为它在换行符处停止读取。
我可以读取标准输入 cat
, , 像这样:
my_var=`cat /dev/stdin`
, ,但后来我不知道如何打印它。这样换行符、制表符和其他分隔符仍然存在。
我的示例脚本如下所示:
#!/usr/local/bin/bash
A=`cat /dev/stdin`
if [ ${#A} -eq 0 ]; then
exit 0
else
cat ${A} | /usr/local/sbin/nextcommand
fi
解决方案
这对我有用:
myvar=`cat`
echo "$myvar"
$myvar
周围的引号非常重要。
其他提示
在Bash中,还有另一种方式; man bash
提及:
命令替换
$(cat file)
可以替换为等效但更快的$(< file)
。
$ myVar=$(</dev/stdin)
hello
this is test
$ echo "$myVar"
hello
this is test
tee 完成工作
#!/bin/bash
myVar=$(tee)
是的,它对我也有用。感谢。
myvar=`cat`
与
相同myvar=`cat /dev/stdin`
是的。从bash
手册页:
用双引号括起字符 保留所有的字面值 引号内的字符, 除了$,`,\和,当历史扩展时 启用,!字符$和` 在双引号内保留其特殊含义。
[更新]
如果管道中没有任何内容,此分配将无限期挂起......
var="$(< /dev/stdin)"
我们可以通过超时来防止这种情况 read
对于第一个字符。如果超时,返回码将大于 128,我们就会知道 STDIN 管道(又名 /dev/stdin
) 是空的。
否则,我们可以通过以下方式获取 STDIN 的其余部分:
- 环境
IFS
为 NULL 仅用于read
命令 - 关闭转义
-r
- 消除读取的分隔符
-d ''
. - 最后,将其附加到我们最初得到的角色上
因此...
__=""
_stdin=""
read -N1 -t1 __ && {
(( $? <= 128 )) && {
IFS= read -rd '' _stdin
_stdin="$__$_stdin"
}
}
该技术避免使用 var="$(command ...)"
命令替换,根据设计,总是会删除任何尾随的换行符。
如果首选命令替换,为了保留尾随换行符,我们可以在输出中附加一个或多个分隔符 $()
然后把它们脱到外面。
例如 ( 笔记 $(parens)
在第一个命令中和 ${braces}
在第二)...
_stdin="$(awk '{print}; END {print "|||"}' /dev/stdin)"
_stdin="${_stdin%|||}"
不隶属于 StackOverflow