我试图理解这一行中使用括号:
if !(ssh -q $user@$server "[ -d /some/directory ]")then
通常条件介于[]之间,这里究竟使用了什么?
答案 0 :(得分:2)
有一个小小的,有争议的" (请参阅评论here)行中的拼写错误。第一个支架前面的空间。在shell脚本中,不需要空间。但是,根据shell中的某些选项,可能需要在命令行上直接键入此行时添加空格。用空格重写是:
if ! (ssh -q $user@$server "[ -d /some/directory ]"); then ... ; fi
这一行有几个部分
[ -d /some/directory ]
:这是对所谓的test
命令的调用,也可以写成[ ... ]
。 test -d /some/directory
和[ -d /some/directory ]
是相同的命令。它将检查目录/some/directory
是否存在或是否可访问。 (有关详细信息,请参阅man test
)ssh -q $user@$server cmd
:这将在cmd
上执行$user
$server
命令。但是它会通过不抛出任何错误输出而安静地(-q
)执行此操作。基本上,在cmd
替换为上述测试的情况下,我们会检查$user
上$server
的目录是否存在或是否可访问。
man ssh ::
-q
:安静模式。导致抑制大多数警告和诊断消息
完整命令现在括在括号中。括号是一个分组,允许以统一的方式执行多个命令。即( cmd1; cmd2 )
将作为一个单元执行。尽管如此,这些括号将在单独的实例中执行此操作。它会派一个子shell来执行。在这种情况下,只有一个命令在子shell中执行。这是不必要的开销。 如您所见,即使语法看起来更清晰,它也会产生影响。
man bash ::
(list)
list
在子shell环境中执行。影响shell环境的变量赋值和内置命令在命令完成后不会保持有效。返回状态是list
的退出状态。
! cmd
:这会否定cmd
的退出状态。如果命令成功执行(退出状态= 0),则假定为假。反之亦然。
if
语句写为if list; then thenlist; fi
。如果if
的退出状态为零,则执行list
语句。在这种情况下,list
为! (ssh -q $user@$server "[ -d /some/directory ]")
,而list
的更常见示例为[ -e foo ]
,test
命令。
现在编写if条件的方法类似:
if ! ssh -q $user@$server "[ -d /some/directory ]"; then ...; fi
或者您可以移动!
中的test
,导致:
if ssh -q $user@$server "[ ! -d /some/directory ]"; then ...; fi
最后,如果你想让分组保留没有子shell的外观,你可以使用{ ... }
,即
if ! { ssh -q $user@$server "[ -d /some/directory ]"; }; then ...; fi
man bash ::
{ list; }
list
只是在当前的shell环境中执行。列表必须以换行符或分号结尾。 这称为组命令。返回状态是退出 状态为list
。
答案 1 :(得分:0)
您需要!
和(...)
之间的空格。使用bash
shell写一个正确的方法:
if ! (ssh -q $user@$server "[ -d \"/some/directory\" ]"); then
echo "do something";
else
echo "do something else";
fi
使用/some/directory
检查远程server
上的目录ssh
是否存在。
man test
了解选项,例如-d
。
-d FILE FILE exists and is a directory
!
表示对()
的输出的逻辑(布尔)NOT或否定。
-q
选项适用于安静模式。
有关bash中单个括号ssh
的信息,请参阅https://www.gnu.org/software/bash/manual/html_node/Command-Grouping.html
注意,单个括号用于对子shell中的命令行进行分组。正如OP建议的那样,()
并非在此严格需要/推荐,并且可以在没有它的情况下编写相同的()
条件,
if