为什么我的带反引号的 if 语句不能正常工作?

Why doesn't my if statement with backticks work properly?

我正在尝试制作一个 Bash 脚本,用户可以在其中复制文件,并查看是否成功完成。但是每次复制完成时,无论正确与否,都会显示第二个输出 "copy was not done"。知道如何解决这个问题吗?

if [ `cp -i $files $destination` ];then
        echo "Copy successful."
else
        echo "Copy was not done"
fi

使用反引号,您测试的是 cp 命令的输出,而不是它的状态。您也不需要此处的测试命令(方括号)。

只需使用:

if cp ... ; then
    ...

除了测试 output verses status 正如其他答案中正确指出的那样,您还可以使用 复合命令 来完成您正在尝试的操作,而不需要完整的 if ... then ... else ... fi 语法。例如:

cp -i "$files" "$destination" && echo "Copy successful." || echo "Copy was not done"

这基本上与 if 语法完全相同。基本上:

command && 'next cmd if 1st succeeded'

command || 'next cmd if 1st failed'

您只是将 command && 'next cmd if 1st succeeded' 用作 command || 'next cmd if 1st failed' 中的 command。加在一起简直就是:

command && 'next cmd if 1st succeeded' || 'next cmd if 1st failed'

注意: 确保始终引用变量以防止 word-splitting 路径名扩展,等等...

你想要的是

if cp -i "$file" "$destination"; then #...

Don't forget the quotes.


你的版本:

if [ `cp -i $files $destination` ];then #..

将始终执行 else 分支。

shell中的if语句接受一个命令。 如果该命令成功(returns 0,它被分配到 $?),则条件成功。

如果你这样做if [ ... ]; then,那就和 if test ... ; then 因为 [ ]test command/builtin.

的语法糖

在您的例子中,您将 cp 操作的 stdout* 的结果作为参数传递给 test

cp 操作的 stdout 将是空的(cp 通常只输出错误,那些会转到 stderr).带有空参数列表的 test 调用是错误的。该错误导致非零退出状态,因此您总是得到 else 分支。


*$() 进程替换或反引号进程替换 slurp 命令的 stdout 运行

尝试:

                cp -i $files $destination
                #check return value $? if cp command was successful
                if [ "$?" == "0" ];then
                        echo "Copy successful."

                else
                        echo "Copy was not done"
                fi