0

Doessudo only apply to a simple command? I guess so from the following example. Am I correct or not?

$  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

But I am not sure when I see this example:

$ sudo time echo hello
hello
0.00user 0.00system 0:00.00elapsed 100%CPU (0avgtext+0avgdata 1924maxresident)k
0inputs+0outputs (0major+71minor)pagefaults 0swaps

Is time echo hello a simple command? I don't think so, since time is a keyword, not a command name.

Thanks.

Tim
  • 101,790
  • 1
    Sudo is a regular program which is invoked by the shell as any other program, so your attempt at sudo (...) is just a syntax mistake. You could try sudo "(...)" then the command enclosed in double quotes would be passed to the shell in the context of the sudo'ed user – Serge May 16 '18 at 01:32
  • 3
    In sudo time echo hello you are executing the external time command (e.g. /usr/bin/time) rather than your shell's time – steeldriver May 16 '18 at 01:37
  • @steeldriver thanks. In time time, are both time keyword? https://unix.stackexchange.com/questions/444071/is-each-time-in-these-examples-a-keyword-or-usr-bin-time – Tim May 16 '18 at 03:42

1 Answers1

4

sudo doesn't even support the full "simple command" syntax. According to the bash man page, in the Shell Grammar section:

A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator.

That is, a simple command might be something like this:

LC_ALL=C grep -i "keyword" <infile >outfile &

sudo supports variable assignments (like LC_ALL=C) and a command name and its arguments (like grep -i "keyword"), but does not support redirections (like <infile >outfile) or control operators (&). In fact, if you tried to use the unsupported elements with sudo, like this:

sudo LC_ALL=C grep -i "keyword" <infile >outfile &

... then the shell will interpret the redirects and backgrounding (&) before running sudo, and apply them to sudo itself (not to the grep command, except indirectly).

Other things sudo doesn't support: any sort of complex command, including pipelines, lists (multiple commands separated by ; or &), command groups (with either ( ) or { }), conditional and arithmetic expressions ([[ ]] and (( ))), logical operators (!, &&, and ||), keywords (if, for, while, case, etc), or shell aliases and functions.

time is an interesting case, because it's a shell keyword and also a regular command (generally /usr/bin/time). When you use sudo time somecommand, it doesn't recognize time as a shell keyword so it uses the regular command executable version instead.

If you want to use the shell (keyword) version, you can run a shell under sudo and let it recognize the keyword; something like this:

sudo bash -c 'time echo hello'

Since that runs a full shell, you can also use any other complex shell syntax you want in this form. But be careful about quoting and such; whatever's after sudo bash -c will be run through the shell parsing (and quote and escape interpretation) twice, so it's easy to get unexpected results.

  • Of course sudo doesn't support compound commands and redirection ! Those are shell features. Sudo itself is a command. Now, if it supported specifying output files via some flag like strace -o for example, that'd be different story – Sergiy Kolodyazhnyy May 16 '18 at 04:26
  • @SergiyKolodyazhnyy It's obvious if you have a clear understanding of what's done by the shell and what's done by execl() et al. (Well, except for variable assignments; it's not obvious that sudo would support those.) But a lot of people aren't clear on that, so I thought It'd be best to just go down the list of syntax elements and cover which work & which don't. – Gordon Davisson May 16 '18 at 05:35
  • Indeed, understanding the underlying syscalls and mechanics helps. I've nothing against the answer, in fact I like it hence +1ed. As for execl(), consider adding a note about that. Overall, very helpful answer. – Sergiy Kolodyazhnyy May 16 '18 at 05:49