我在别人编写的脚本中遇到了一个条件语句的命令语法问题。脚本如下(已截断)。
#! /bin/bash
# app_upgrade.sh
# Verify file integrity
filehash=$( md5sum install_package.tgz )
md5hash=$( cat install_package.tgz.md5 )
if [ -z $( diff <(echo $md5hash) <(echo $filehash) ) ]; then
printf "File Integrity Check Passed"
else
printf "File Integrity Check Failed"
exit
fi
当我运行此脚本时,由于意外的左括号,它在试图解释条件语句时失败。报告给CLI的确切错误如下。
app_upgrade.sh: command substitution: line 118: syntax error near unexpected token `('
app_upgrade.sh: command substitution: line 118: ` diff <(echo $md5hash) <(echo $filehash) )'
我验证了diff是由运行脚本的同一用户在我的系统上执行的命令。我还从CLI运行了diff <(echo $md5hash) <(echo $filehash)
,这一操作没有任何问题。我也试着逃离括号,但也失败了。我不明白为什么这会引起一个问题。
作为一种变通方法,我尝试了其他一些条件,因为如果我一开始就写脚本,我就不会使用diff进行比较。我尝试用以下替换上面脚本中指定的条件。
if [ "$filehash" = "$md5hash" ]
然而,这并没有奏效。尽管散列是相同的,但条件导致比较意外失败。
if [[ "$filehash" == "$md5hash" ]]
这终于奏效了。
总之,我的问题是:
为什么脚本在试图解释原始条件语句中的
$( diff <(echo $md5hash) <(echo $filehash)
时失败并出现语法错误?在我更新的条件语句中,假设两个散列相同,为什么
if [ "$filehash" = "$md5hash" ]
失败,而if [[ "$filehash" == "$md5hash" ]]
成功?从我的研究来看,这两种方法似乎都是比较bash中字符串的有效方法。
提前感谢!
当您针对shellcheck
linter运行脚本时,您可以看到错误
In ./test.sh line 9: if [ -z $( diff <(echo $md5hash) <(echo $filehash) ) ]; then ^-- SC2046 (warning): Quote this to prevent word splitting. ^------^ SC2086 (info): Double quote to prevent globbing and word splitting. ^-------^ SC2086 (info): Double quote to prevent globbing and word splitting.
您必须引用if
表达式来避免分词:
#! /bin/bash
# app_upgrade.sh
# Verify file integrity
filehash=$( md5sum install_package.tgz )
md5hash=$( cat install_package.tgz.md5 )
# mind the `"` quotation marks around
if [ -z "$( diff <(echo $md5hash) <(echo $filehash) )" ]; then
printf "File Integrity Check Passed"
else
printf "File Integrity Check Failed"
exit
fi
我的问题与shell有关。我的问题的根本原因是/home/目录中的noexec
安全约束,因此我无法从那里运行./app_upgrade.sh
。然而,sh app_upgrade.sh
运行良好,并执行了脚本,但我并没有像预期的那样运行它。使用bash app_upgrade.sh
可以使脚本正常运行。因此,这里的根本原因是我执行脚本的目录中存在权限问题,导致我使用sh
命令错误地执行bash脚本。
总结:
[user@host ~]$ ./app_upgrade.sh
导致bash: ./app_upgrade.sh: Permission denied
[user@host ~]$ sh app_upgrade.sh
执行了该脚本,但没有像bash那样执行,因此这导致了正确解释其中一行代码的问题。
[user@host ~]$ bash app_upgrade.sh
正确执行了脚本,没有出现错误。
如果我最初在一个没有noexec
约束的目录中运行这个,那么这个问题就永远不会出现。
感谢所有的意见、建议和帮助!