示例输出
说我有一个功能,a
:
function a() {
read -r VALUE
if [[ -n "$VALUE" ]]; then # empty variable check
echo "$VALUE"
else
echo "Default value"
fi
}
因此,要展示该功能的管道:
nick@nick-lt:~$ echo "Something" | a
Something
但是,此功能的管道数据应该是可选的。所以,这也应该是有效的。并提供以下输出:
nick@nick-lt:~$ a
Default value
但是,该函数挂起,因为read
命令等待来自stdin
的数据。
我尝试了什么
老实说不是很多,因为我对此并不了解,在Google上搜索的回报很少。
从概念上讲,我认为可能有一种方法来推动" stdin
流的空(或空白,无论有效)值,以便即使空stdin
至少附加/预先添加此值,触发read
,然后只需先删除/最后一个字符。我没有办法做到这一点。
问题
如果可能的话,我怎样才能使上述两个场景都适用于函数a
,以便管道是可选的?
编辑:道歉,快速撰写的问题。现在应该正常工作。
答案 0 :(得分:3)
一种方法是检查标准输入(fd 0)是否是终端。如果是这样,请不要阅读,因为这会导致用户输入内容。
function a() {
value=""
if [ \! -t 0 ] ; then # read only if fd 0 is a pipe (not a tty)
read -r value
fi
if [ "$value" ] ; then # if nonempty, print it!
echo "$value"
else
echo "Default value"
fi
}
我在cygwin上检查过:a
打印“默认值”,echo 42 | a
打印“42”。
答案 1 :(得分:0)
两个问题:
句法,在关闭之前需要一个空格]]
算法,您需要-n
(非零长度)变量测试,而不是-z
(零长度)
所以:
if [[ -n "$VALUE" ]]; then
或者简单地说:
if [[ "$VALUE" ]]; then
由于[[
是内置的shell,因此您不必严格需要双引号:
if [[ $VALUE ]]; then
同时避免将所有大写字母用作变量名称,因为这些大写字母通常用于表示环境变量,并且您定义的大写字母可能以某种方式覆盖已存在的变量名称。所以使用小写变量名:
if [[ $value ]]; then
除非你是export
- 你的变量,并且严格要求它是大写的,否则也要确保它不会覆盖任何已存在的变量。
此外,我会向read
添加超时,例如-t 5
持续5秒,如果未输入任何输入,则打印默认值。同时将函数名称更改为更有意义的名称。
执行:
function myfunc () {
read -rt5 value
if [[ "$value" ]]; then
echo "$value"
else
echo "Default value"
fi
}
示例:强>
$ function myfunc () { read -rt5 value; if [[ "$value" ]]; then echo "$value"; else echo "Default value"; fi ;}
$ myfunc
Default value
$ echo "something" | myfunc
something
$ myfunc
foobar
foobar