我正在尝试测试文件是否$SSHPATH/$ID.*
存在。我用来sshpass
提供密码,这样我就不必输入密码。
如果文件不存在,我想执行代码
if [ "sshpass -p $SSHPASS ssh root@$SSHHOST test ! -f $SSHPATH/$ID.*" ]; then
即使文件存在于远程服务器上,这似乎也会返回 true。为什么?
我不认为它是重复的如果命令成功或失败,如何有条件地执行某些操作因为这也不起作用,如果文件不存在,它就不会执行
if sshpass -p "$SSHPASS" ssh "root@$SSHHOST" test ! -f "$SSHPATH/$ID.*"; then
答案1
正如 pLumo 所解释的,你的测试总会成功。
您想要做的是测试您的模式 是否可以$SSHPATH/$ID.*
扩展为某种内容。这与测试-f
是否是常规文件不同,因为模式可能会扩展到多个名称,并且测试-f
只能应用于单个路径名。
在本地,您可以使用以下命令来执行此操作
set -- "$SSHPATH/$ID".*
if [ -e "$1" ]; then ...; fi
这会将位置参数( 、 等)设置$1
为$2
与给定模式匹配的名称set
。然后,这些if
语句测试第一个匹配是否是现有名称(如果该模式不匹配任何内容,则在大多数 shell 中将保持未展开状态)。
要运行此操作ssh
:
ssh user@host "set -- '$SSHPATH/$ID'.*; [ -e \"\$1\" ]"
不稳定的引用确保了$SSHPATH
and$ID
被扩展当地的shell,而"$1"
远程扩展。
ssh
如果模式与现有名称匹配,则退出状态为零(“成功”);如果不匹配(或者以某种方式失败),则退出状态为非零(“失败”) 。
if
您可以在如下声明中使用它:
if ssh user@host "set -- '$SSHPATH/$ID'.*; [ -e \"\$1\" ]"; then
# do something for success
else
# do something for failure
fi
测试非-存在,否定测试:
if ssh user@host "set -- '$SSHPATH/$ID'.*; [ ! -e \"\$1\" ]"; then
# do something for failure
else
# do something for success
fi
我忽略了您对 的使用sshpass
,但您可能只是ssh
像在问题中所做的那样在其前面加上前缀。
答案2
你的第一个命令是一样的
if [ "some string" ]; then ... fi
这永远是真的。
第二个命令几乎是正确的,但是您需要添加!
内部引号或对其进行转义,否则它将被您的 shell 解释。
双引号整个命令并单引号路径以避免路径中特殊字符的问题。确保*
单引号外面有:
if sshpass -p "$SSHPASS" ssh root@$SSHHOST "test ! -f '$SSHPATH/$ID.'*"; then ... fi
如果您的模式匹配多个文件,测试将会失败。