Bash 测试 wc 与 '-ge' - 除以 0 错误

Bash 测试 wc 与 '-ge' - 除以 0 错误

下面的脚本抛出错误:

#!/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

相关内容