SSH返回码状态和错误处理

SSH返回码状态和错误处理

我想使用 ssh 检查远程服务器上的文件计数是否为 0。

下面的代码仅检查文件(以 .dmp 结尾的文件是否存在)

if ssh v0021x91 ls /apps/oracle/home/DB_1201/*.dmp
    then
      echo "Files still exist after cleanup"
      exit -9991
    else
      echo "Files cleaned up"
   fi

对于下面的“then”部分是用 $? 执行的=0 当实际错误“ls:无法访问/apps/oracle/home/DB_1201/*.dmp:没有这样的文件或目录”时

if [ `ssh v0021x91 ls /apps/oracle/home/DB_1201/*.dmp | wc -l` -eq 0 ]
   then
      echo  "[INFO  ] Dumps Files Cleaned Up on Remote Host"
    else
      echo  "[ERROR ] issue in Remote Host"
      exit -9992
fi  

我需要输出“ls /apps/oracle/home/DB_1201/*.dmp |wc -l”0或N号。如果目录不存在(没有这样的文件或目录)。

需要返回文件计数 0 或 28 和/或捕获目录未找到错误。

请告知执行 SCP 以及之后验证其状态的正确方法?

即使在获取本地服务器最后一个命令状态时出现一些错误,下面也始终返回零。

   scp -rp /apps/oracle/home/DB_1201/*.dmp      oracle@v0021x91:/apps/oracle/home/DB_1201/
   if [ $? != 0 ]
    then
     echo -e "[ERROR ] Can't copy files from Source to Remote"
     exit -9995
   fi
  
   if    scp -rp /apps/oracle/home/DB_1201/*dmp oracle@v0021x91:/apps/oracle/home/DB_1201/
   then
     echo -e "[INFO ] SCP Success"
      else
     echo -e "[ERROR ] Can't copy files from Source to Remote"
     exit -9995
   fi

问候,维拉

答案1

  1. if [ `ssh v0021x91 ls /apps/oracle/home/DB_1201/*.dmp | wc -l` -eq 0 ]

    评估顺序是对通配符进行评估命令ssh被执行。如果/apps/oracle/home/DB_1202/*.dmp匹配上的一个或多个文件当地的主机,它将被替换为这些文件的名称。否则,星号将保留并作为文字传递到远程端。

    然后,远程 shell 将在执行ls命令之前评估该模式,要么将其扩展为一个或多个匹配文件,要么将其保留为字面星号。

    如果没有匹配的文件,ls将抱怨找不到该文件的错误/apps/oracle/home/DB_1201/*.dmp(以文字星号作为文件名的第一个字符)。作为副作用,它不会输出任何文件,wc -l并且您将得到零作为预期的正确结果。

    最后,测试将匹配零个文件以及写入的错误标准错误,或一些非零数量的文件。

    作为现代编码的一个要点,请考虑替换[ `command` ][ "$(command)" ].或者,如果你正在为 写作bash[[ "$(command)" ]]

  2. exit -9991

    退出代码应为 0(成功,正常)或范围为 1-127。使用大数或负数是错误且具有误导性的

  3. if [ $? != 0 ]

    您正在对数值使用字符串比较。实际上,这可能没问题,但您应该使用[ $? -ne 0 ]or[ $? -gt 0 ]来代替。

  4. if scp -rp /apps/oracle/home/DB_1201/*dmp oracle @ v0021x91:/apps/oracle/home/DB_1201/*dmp

    • 目标组件中的空格是怎么回事?
    • 不要在目标中指定通配符,除非您确实真的知道你在做什么

    几乎可以肯定的是oracle@v0021x91:/apps/oracle/home/dB_1202/

  5. if ssh v0021x91 ls /apps/oracle/home/DB_1201/*.dmp

    与 #1 类似,如果没有匹配的文件,您将收到错误消息*.dmp,您将收到错误消息,如果远程计算机上有一个或多个与该路径匹配的文件,则会出现意外问题当地的机器。

为了避免本地系统上的通配符扩展,请引用您传递给的命令ssh。所以对于 #5 你应该写if ssh v0021x91 'ls /apps/oracle/home/DB_1201/*.dmp'等等。

答案2

像 -9991 这样的退出代码在任何类型的脚本中都是毫无意义的。它们将以 256 为模进行截断,并返回 0-255 范围内的正值。 128 及以上的值具有常规含义(由信号终止),大约 124 到 127 之间的值用于 shell 进程错误。您也无法可靠地使用计数器的状态代码。

ssh 和 scp 返回它们自身的状态——远程系统是否可访问、您的凭据是否正确、远程服务是否正在运行?它们没有返回远程命令状态的机制。您需要将任何信息(例如远程脚本的结果)作为远程命令返回的数据传回,因此可以识别为不是实际数据:就像STATUS::9991您喜欢的那样。

如果您想捕获远程命令的 stderr,您可能需要2>&1在 ssh 命令中重定向它。

答案3

第一个代码片段的唯一问题是需要在远程“ls”命令周围放置单引号以延迟 glob 模式的执行。你的基本方法是正确的;根据 SSH 联机帮助页,ssh 命令的退出状态是远程命令的退出代码。

此外,退出状态限制在 0 - 255 范围内

尝试这个:

if ssh v0021x91 'ls /apps/oracle/home/DB_1201/*.dmp'
    then
      echo "Files still exist after cleanup"
      exit 1
    else
      echo "Files cleaned up"
   fi

相关内容