下面的脚本抛出错误:
#!/bin/bash
if [[ $(wc -l "/disk1/environment.sh") -ge 0 ]];then
echo "File has data"
fi
line 2: [[: 5 /disk1/environment.sh: division by 0 (error token is "/environment.sh")
但下面的代码工作正常:
#!/bin/bash
if [[ $(wc -l "/disk1/environment.sh") > 0 ]];then
echo "File has data"
fi
有人可以告诉我为什么“-ge”和“>”在这里表现不同吗?
bash版本:GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
答案1
这是因为 的输出wc -l /filename
,这将输出例如:
5 /filename
但您正在进行整数比较(运算符-ge
:),因此无关部分/filename
无效,导致错误消息。
只需通过 STDIN 将文件名传递给它wc
,这样wc
就可以返回计数:
[[ $(wc -l </disk1/environment.sh) -ge 0 ]]
在第二种情况下,[[ $(wc -l /disk1/environment.sh) > 0 ]]
您只需检查命令替换的输出,$(wc -l /disk1/environment.sh)
,是否按字典顺序排序在0
;除非wc
返回一些错误并且在 STDOUT 上不产生任何结果,否则情况总是如此。
请注意,[[
不支持算术运算符,如>
, >=
, <
, <=
,您需要((
这些关键字:
(( $(wc -l </disk1/environment.sh) > 0 ))
答案2
第二次尝试不会产生错误,但它无法正常工作,假设您的尝试是测试文件是否至少包含一行。
的输出wc -l "/disk1/environment.sh"
由文件中的行数、空格和文件名组成。如果要使用行数,则需要将其提取出来。除了分割输出之外,还有一种更简单的方法:不是在命令行上传递文件名,而是重定向wc
文件的输出。然后wc
只打印没有文件名的数字。
if [[ $(wc -l <"/disk1/environment.sh") -ge 0 ]];then
echo "File has data"
fi
或者,既然你无论如何都在使用 bash 语法,
if (($(wc -l <"/disk1/environment.sh") >= 0)); then
echo "File has data"
fi
当然,这始终是正确的,因为行数始终大于或等于 0。但是您可以使用其他数字获得有用的结果。
在第一次尝试中,您使用-ge
运算符。这是整数运算符。您会收到一条错误消息,因为左侧不是整数,而是类似42 /disk1/environment.sh
.
在第二次尝试中,您<
在条件语句中使用运算符。该运算符是字符串比较(按词法顺序)。碰巧 的输出wc -l /disk1/environment.sh
总是按词法排序在 之后0
,因为它以数字开头,因此[[ $(wc -l <"/disk1/environment.sh") > 0 ]]
始终为真。例外情况是/disk1/environment.sh
不存在;在这种情况下,wc -l
标准输出上不会产生任何内容(而是将错误消息写入标准错误),并且比较为 false。
将文件中的行数与 0 进行比较并不是很有用。在现代系统上,wc -l
计算换行符的数量。在文本文件中,仅当文件为空时换行数才为 0。 (一般来说,wc -l
如果文件不包含任何换行符,则返回 0;文本文件在每行末尾都包含换行符,非文本文件中换行符的数量很少是有用的信息。)条件中有一个运算符表达式来测试文件是否为空,您不需要调用wc
.
if [[ ! -e /disk1/environment.sh ]]; then
if [[ -L /disk1/environment.sh ]]; then
echo "/disk1/environment.sh is a broken symbolic link"
else
echo "/disk1/environment.sh does not exist"
fi
elif [[ ! -r /disk1/environment.sh ]]; then
echo "/disk1/environment.sh exists but is not readable"
elif [[ ! -s /disk1/environment.sh ]]; then
echo "/disk1/environment.sh is empty or is a special file (name pipe, etc.)"
else
echo "/disk1/environment.sh is not empty"
fi