我有一个命令,当以当前用户身份运行时可以运行,但如果我sudo
在命令前面加上前缀,就会出现错误。
如果文件是目录,我会尝试删除它(但如果它是目录的符号链接,则不会删除它)。这很有效:
brad@ip-10-0-0-1:~$ [[ -d /path/to/my/place && ! -L /path/to/my/place ]] && rm -rf /path/to/my/place
但是,如果我尝试sudo
以超级用户身份执行此操作,我会收到错误,因为sudo
似乎认为[[
是一个命令:
brad@ip-10-0-0-1:~$ sudo [[ -d /path/to/my/place && ! -L /path/to/my/place ]] && rm -rf /path/to/my/place
sudo: [[: command not found
我必须添加双括号才能使该! -L /path/to/my/place
位工作;sudo
以前我运行时,使用单括号就可以正常工作
brad@ip-10-0-0-1:~$ sudo [ -d /path/to/my/place ] && rm -rf /path/to/my/place
但是现在我试图检查以确保它不是符号链接,我无法让它工作sudo
。我该怎么做:
sudo
获取与或一起使用的双括号语法- 获取单括号语法允许我否定该
-L
部分?
答案1
$ type -a [
[ is a shell builtin
[ is /usr/bin/[
$ type -a [[
[[ is a shell keyword
$
如您所见[
(除了是 shell 内置命令之外)是一个sudo
可以使用的常规命令。[[
不是。您需要bash
提供[[
:
sudo bash -c '[[ -d /path/to/my/place && ! -L /path/to/my/place ]]' && …
因为[[
是 shell 关键字,解析器会识别它并更改&&
between[[
和的行为]]
。您不能使用&&
inside,[ … ]
因为它[
充当命令,并且]
实际上是传递给它的最后一个参数。使用&&
inside 意味着有两个命令,这是错误的。
但是[
支持-a
,所以这可能工作:
sudo [ -d /path/to/my/place -a ! -L /path/to/my/place ] && …
但你应该避免这样做。来自本文:
二进制
-a
和-o
[…] 是 POSIX 标准的 XSI 扩展。在 POSIX-2008 中,它们都被标记为过时。它们不应在新代码中使用。[ A = B -a C = D ]
(or ) 的一个实际问题是 POSIX 不指定带有超过 4 个参数的or命令-o
的结果。它可能在大多数 shell 中都有效,但您不能指望它。如果您必须为 POSIX shell 编写,那么您应该使用由运算符分隔的两个or命令。test
[
test
[
&&
因此,如果您想使用,这应该更安全[
:
sudo [ -d /path/to/my/place ] && sudo [ ! -L /path/to/my/place ] && …