Bash:如果 [ tar = error ]

Bash:如果 [ tar = error ]

我想要一个 shell 脚本来根据tar成功还是失败写一条消息,但是这个脚本不能正常工作:

TAR=$(tar -cf Archiv.tar myfolder/ myotherfolder/)
if [ ! "$TAR" = "/dev/null" ]; then
   echo "success"
else
  echo "error - no such Directory or file"
fi

问题是什么?

答案1

我不知道在什么情况下tar会输出/dev/null错误信号,而这正是代码尝试检测错误的方式。这是检查错误的正确方法:

if tar -cf Archiv.tar myfolder/ myotherfolder/
then
    echo "success"
else
    echo "error - no such Directory or file"
fi

您可能不需要该else案例,因为tar该案例本身会抱怨。如果您使用的目的/dev/null是抑制tar抱怨,以便您可以替换自己的消息,那么第一行应该是:

if tar -cf Archiv.tar myfolder/ myotherfolder/ > /dev/null 2>&1

请注意,我们这里没有使用方括号。这实际上是内置 shell 命令的别名,名为test(1)它执行逻辑运算并分别返回 0 或非零来表示成功或失败。if反过来检查这个 0/非零返回,所以为了检查像tar失败时返回非零的程序的成功,你不需要涉及test或其别名[

如果您接受过某种编程语言的培训,该语言要求在表达式周围使用某种标点符号,if而标点符号的缺乏会困扰您,那么您可以像这样重写第一行:

tar -cf Archiv.tar myfolder/ myotherfolder/
if [ $? = 0 ]

这两行合在一起完成与上面版本相同的功能,因为 shell 内置变量$?保存了上次程序运行的状态码。

这也许更清楚,但有点浪费。

答案2

像往常一样,有多种方法可以完成您想要做的事情。
这是一种(可能很紧凑的)方法:

#!/bin/bash
TAR_COMMAND='tar -cf Archiv.tar myfolder/ myotherfolder/ 2>/dev/null'
MSG_OK='### Work well DONE ### '   # A more common way to use a variable
MSG_ERR='### OPS IT FAILS ###  '    

$TAR_COMMAND && echo $MSG_OK || echo $MSG_ERR

简短说明

  • 如果你有无需存储退出状态(或退出代码)你可以在操作符后立即使用&&, 和 或者|| [1]
    逻辑:cmd1 && cmd2,仅在无错误退出cmd2时执行(退出代码)。相反,仅在出现错误退出时执行(错误代码不同于)。 cmd10cmd1 || cmd3cmd3cmd10

  • 相反,如果你想要存储退出代码你必须在命令执行后立即执行此操作,因为在下一个命令执行时,此值将被更新。变量赋值就足够了

    mycommand               # you execute your command
    ExitCodeToUseLater=$?   # So I can use it later in the script
    # ... other stuffs ...
    [ $ExitCodeToUseLater = 0  ]  && echo "It was gone ok " 
    # ... again other stuffs ...
    [ $ExitCodeToUseLater = 0  ] || echo "# Never a time that it goes as I want"
    
  • 在 bash 脚本以及 makefile 中[2a2b], 你可以找到一个命令有很多选择写在变量中以使代码更具可读性(如上所示TAR_COMMAND)。在 shell 中写入变量$MyVar与在 shell 中写入的内容相同[3]。它在脚本中也有效。您可能需要注意 bash 扩展和替换规则,有关详细信息,请参阅man bash

  • /dev/null是个空设备 [4]“丢弃写入的所有数据但报告写入操作成功的设备文件”。它可用于为命令提供空输入(</dev/null)或以“绝对静默”的方式传递标准输出或标准错误[5]

相关内容