我想使用 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
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)" ]]
exit -9991
退出代码应为 0(成功,正常)或范围为 1-127。使用大数或负数是错误且具有误导性的
if [ $? != 0 ]
您正在对数值使用字符串比较。实际上,这可能没问题,但您应该使用
[ $? -ne 0 ]
or[ $? -gt 0 ]
来代替。if scp -rp /apps/oracle/home/DB_1201/*dmp oracle @ v0021x91:/apps/oracle/home/DB_1201/*dmp
- 目标组件中的空格是怎么回事?
- 不要在目标中指定通配符,除非您确实真的知道你在做什么
几乎可以肯定的是
oracle@v0021x91:/apps/oracle/home/dB_1202/
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