如何测试命令是否输出空字符串?
当前回答
Bash参考手册
6.4 Bash条件表达式
-z string
True if the length of string is zero.
-n string
string
True if the length of string is non-zero.
你可以使用速记版:
if [[ $(ls -A) ]]; then
echo "there are files"
else
echo "no files found"
fi
其他回答
正如Jon Lin所评论的,ls -al将始终输出(for。和. .)。您希望ls -Al避免这两个目录。
例如,你可以把命令的输出放到一个shell变量中:
v=$(ls -Al)
较旧的、非嵌套的符号是
v=`ls -Al`
但我更喜欢嵌套符号$(…)
您可以测试该变量是否为非空
if [ -n "$v" ]; then
echo there are files
else
echo no files
fi
你可以把两者结合起来,就像[-n "$(ls -Al)"];然后
有时,ls可能是某个shell别名。您可能更喜欢使用$(/bin/ls -Al)。参见ls(1)和hier(7)和environ(7)和你的~/。bashrc(如果你的shell是GNU bash;我的交互式shell是zsh,定义在/etc/passwd -见passwd(5)和chsh(1))。
之前,问题询问如何检查目录中是否有文件。下面的代码实现了这一点,但请参阅rsp的答案以获得更好的解决方案。
空的输出
命令不返回值——它们输出值。您可以使用命令替换来捕获此输出;例如$(ls -A)。你可以像这样在Bash中测试一个非空字符串:
if [[ $(ls -A) ]]; then
echo "there are files"
else
echo "no files found"
fi
注意,我使用的是-A而不是-A,因为它省略了当前(.)和父目录(..)的符号项。
注意:正如注释中指出的,命令替换不捕获尾随换行符。因此,如果命令只输出换行,则替换将不会捕获任何内容,并且测试将返回false。虽然不太可能,但在上面的例子中这是可能的,因为一个换行符就是一个有效的文件名!更多信息在这个答案中。
退出代码
如果要检查命令是否成功执行,可以检查$?,其中包含最后一个命令的退出代码(0表示成功,非0表示失败)。例如:
files=$(ls -A)
if [[ $? != 0 ]]; then
echo "Command failed."
elif [[ $files ]]; then
echo "Files found."
else
echo "No files found."
fi
更多信息请点击这里。
到目前为止给出的所有答案都处理终止并输出非空字符串的命令。
大多数是在以下意义上被打破的:
它们不能正确地处理只输出换行符的命令; 从Bash≥4.4开始,如果命令输出null字节(因为他们使用命令替换),大多数将发送垃圾邮件标准错误; 大多数人将发出完整的输出流,所以会等到命令结束才回答。有些命令永远不会终止(例如,尝试,yes)。
所以为了解决所有这些问题,并有效地回答下面的问题,
如何测试命令是否输出空字符串?
你可以使用:
if read -n1 -d '' < <(command_here); then
echo "Command outputs something"
else
echo "Command doesn't output anything"
fi
您还可以使用read的-t选项添加一些超时,以测试命令是否在给定时间内输出非空字符串。例如,对于2.5秒的超时:
if read -t2.5 -n1 -d '' < <(command_here); then
echo "Command outputs something"
else
echo "Command doesn't output anything"
fi
的话。如果您认为需要确定命令是否输出非空字符串,那么您很可能遇到了XY问题。
我猜你想要ls -al命令的输出,所以在bash中,你会有这样的东西:
LS=`ls -la`
if [ -n "$LS" ]; then
echo "there are files"
else
echo "no files found"
fi
正如tripleee在问题评论中提到的,使用moreutils ifne(如果输入不为空)。
在这种情况下,我们想要ifne -n,它否定测试:
ls -A /tmp/empty | ifne -n command-to-run-if-empty-input
当初始命令的输出为非空时,此方法相对于许多其他答案的优点。ifne将立即开始将其写入STDOUT,而不是缓冲整个输出,然后再写入,如果初始输出生成缓慢或非常长,并且会溢出shell变量的最大长度,这是很重要的。
moreutils中有一些utils可以说应该放在coreutils中——如果你花大量时间生活在shell中,它们值得一试。
对OP特别感兴趣的可能是diempty /exists工具,在撰写本文时仍在考虑中,并且已经有一段时间了(它可能会使用bump)。