由于没有jpg在我的当前工作目录下的文件,为什么两个脚本jpg1.sh,并jpg2.sh给出不同的结果?如何理解差异?请注意,脚本之间的唯一区别是是否在$()命令替换周围使用双引号。
$ cat jpg1.sh
#!/bin/bash
if [ "$(ls *.jpg | wc -l)" = 0 ]; then
echo "yes"
else
echo "no"
fi
$ ./jpg1.sh
ls: *.jpg: No such file or directory
no
$ cat jpg2.sh
#!/bin/bash
if [ $(ls *.jpg | wc -l) = 0 ]; then
echo "yes"
else
echo "no"
fi
$ ./jpg2.sh
ls: *.jpg: No such file or directory
yes
Run Code Online (Sandbox Code Playgroud)
跟进
我证明打勾的答案是关键——wc -l在其返回值中有一些额外的空格。添加set -x到两个脚本后,差异就会显现出来。
$ ./jpg1.sh
++ wc -l
++ ls '*.jpg'
ls: *.jpg: No such file or directory
+ '[' ' 0' = 0 ']'
+ echo no
no
$ ./jpg2.sh
++ wc -l
++ ls '*.jpg'
ls: *.jpg: No such file or directory
+ '[' 0 = 0 ']'
+ echo yes
yes
Run Code Online (Sandbox Code Playgroud)
顺便说一下,我的系统是 macOS Catalina。
在某些系统上,这是错误的,因为wc -l用空格填充其答案,而您要比较的字符串 -- 0-- 根本不包含任何空格。使用引号时,会比较准确的输出;当您不使用它们时,输出会根据空格拆分为单独的单词,并且在将这些单词放入[命令行之前,这些单词中的每一个都被扩展为一个 glob 。要确定您是否在这样的系统上,请添加set -x到您的脚本以启用跟踪级别日志记录,以便您可以查看[要求比较的确切值。
在目前的情况下,整个问题是平凡避免:没有理由使用两种 ls或wc用于此目的。
#!/usr/bin/env bash
shopt -s nullglob
jpegs=( *.jpg )
if (( ${#jpegs[@]} == 0 )); then
echo "No JPEG files were found"
else
echo "Exactly ${#jpegs[@]} JPEG files were found"
fi
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
44 次 |
| 最近记录: |