所以我目前只是试图遍历我当前的目录,在那里我调用以下bash脚本,每次找到一个打印出来的'我们找到了一个.c文件'.我有一个if语句来检查args,因为我将扩展脚本,如果没有找到args它将继续运行,并且一个arg将告诉脚本要查看的目录.
问题是,此代码不起作用:
if [ -z "$#" ]
then
for i in *.c; do
echo "We found a .c file"
done
fi
Run Code Online (Sandbox Code Playgroud)
但是如果我加入echo "Test",它有效吗?
if [ -z "$#" ]
echo "Test"
then
for i in *.c; do
echo "We found a .c file"
done
fi
Run Code Online (Sandbox Code Playgroud)
我是bash的新手,也不知道为什么会发生这种情况.谁能帮我吗?
$#,报告参数的计数,永远不是一个空字符串 - 如果你没有指定参数,$#评估为0,仍然是一个非空字符串(-z测试空字符串).
因此,[ -z "$#" ]是永远(逻辑)假.
你正在寻找什么 - 使用惯用的Bash - 是:
if [[ $# -eq 0 ]]; then ... # -eq compares *numerically*
Run Code Online (Sandbox Code Playgroud)
正如anishsane在评论中指出的那样,POSIX兼容[ $# -eq 0 ]也适用于此; 一般来说,除非你的明确意图是编写符合POSIX标准的shell代码 - 否则你最好坚持使用更具可预测性,功能更丰富(并且速度更快)的Bash特定结构.
或者,使用算术评估:
if (( $# == 0 )); then ...
Run Code Online (Sandbox Code Playgroud)
至于为什么你的第二个片段导致if分支输入:
您的放错位置的 echo "Test" -由于被放置之前的then关键字,导致echo命令被解释作为条件的一部分.
换句话说:被评估的条件是有效的
[ -z "$#" ]; echo "Test",只有(两个)命令的列表,其最后一个命令的退出代码确定了条件的结果.
由于echo总是成功(退出代码0)[1]
,因此整个条件评估为(逻辑)为真,并且if输入了分支.
[1] gniourf_gniourf在注释中指出,如果使用带有无效源/目标的输入/输出重定向,则可以使简单echo命令失败(使用退出代码1); 例如,echo 'fail' > /dev/full.
(请注意,如果重定向源/目标基本上无效 - 不存在的输入文件或无法创建/打开的输出文件(相反,例如,可以使用写入权限打开但最终可以打开的输出目标) T为写到,如/dev/full在Linux上) -巴什甚至从来没有调用手头的命令,因为它"放弃",当它遇到无效重定向:
{ echo here >&2; echo hi; } >/dev/full # Linux: 'here' still prints (to stderr)
{ echo here >&2; echo hi; } >'' # invalid target: commands are never invoked)
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |