sudo
只适用于简单的命令吗?从下面的例子我猜是这样的。我的说法正确与否?
$ if true; then echo hello; fi
hello
$ sudo if true; then echo hello; fi
bash: syntax error near unexpected token `then'
$ sudo ( if true; then echo hello; fi )
bash: syntax error near unexpected token `if'
$ sudo "if true; then echo hello; fi"
[sudo] password for t:
sudo: if true; then echo hello; fi: command not found
$ sudo " ( if true; then echo hello; fi ) "
sudo: ( if true; then echo hello; fi ) : command not found
但当我看到这个例子时我不确定:
$ sudo time echo hello
hello
0.00user 0.00system 0:00.00elapsed 100%CPU (0avgtext+0avgdata 1924maxresident)k
0inputs+0outputs (0major+71minor)pagefaults 0swaps
是time echo hello
一个简单的命令吗?我不这么认为,因为time
是关键字,而不是命令名称。
谢谢。
答案1
sudo
甚至不支持完整的“简单命令”语法。根据 bash 手册页,在 Shell Grammar 部分:
A简单的命令是一系列可选变量赋值,后跟空白的- 分隔单词和重定向,并以控制操作员。
也就是说,一个简单的命令可能是这样的:
LC_ALL=C grep -i "keyword" <infile >outfile &
sudo
支持变量赋值(如LC_ALL=C
)和命令名称及其参数(如grep -i "keyword"
),但是才不是支持重定向(如<infile >outfile
)或控制运算符(&
)。事实上,如果您尝试将不支持的元素与 一起使用sudo
,如下所示:
sudo LC_ALL=C grep -i "keyword" <infile >outfile &
...然后 shell 将&
在运行之前解释重定向和后台 ( ) sudo
,并将它们应用到sudo
自身(而不是应用到grep
命令,除非间接)。
其他sudo
不支持:任何类型的复杂命令,包括管道、列表(由;
或分隔的多个命令&
)、命令组(带有( )
或{ }
)、条件和算术表达式([[ ]]
和(( ))
)、逻辑运算符(!
、&&
和||
)、关键字(if
、for
、while
、case
等),或 shell 别名和函数。
time
是一个有趣的例子,因为它是一个 shell 关键字并且常规命令(通常是 /usr/bin/time)。当您使用 时sudo time somecommand
,它不会识别time
为 shell 关键字,因此它使用常规命令可执行版本。
如果你想使用shell(关键字)版本,你可以在下面运行一个shellsudo
并让它识别关键字;像这样的东西:
sudo bash -c 'time echo hello'
由于它运行完整的 shell,因此您还可以在此形式中使用您想要的任何其他复杂的 shell 语法。但要小心引用等;之后的内容sudo bash -c
将通过 shell 解析运行(以及引用和转义解释)两次,所以很容易得到意想不到的结果。