Only external commands can be run by sudo
.
Sudo
The sudo
program forks (start) a new process to launch an external command with the effective privileges of the superuser (or another user if the -u
option is used). That means that no commands that are internal to the shell can be specified; this includes shell keywords, builtins, aliases, and functions.
The best way to find out if a command is available as an external command (and not internal to the shell) is to run type -a command_name
which displays all locations containing the specified executable.
Example 1: Shell builtin
In this case, the cd
command is only available as a shell builtin:
$ type -a cd
cd is a shell builtin
It fails when you try to run it with sudo
:
$ sudo cd /
sudo: cd: command not found
Example 2: Alias
In this case, the ls
command is external – but an alias with the same name has also been created in the user’s shell.
$ type -a ls
ls is aliased to `ls -F --color'
ls is /bin/ls
If I was to run sudo ls
, it would not be the alias that runs as the superuser; if I wanted the -F
option, it would have to be explicitly included as an option, i.e., sudo ls -F
.
Example 3: Shell builtin and external command
In this case, the pwd
command is provided as both a shell builtin and an external command:
$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd
In this case, the external /bin/pwd
command would run with sudo
:
$ sudo pwd
/home/anthony
Other examples of commands that are often provided as both shell builtins and external commands are kill
, test
([
) and echo
.
Run internal shell commands with sudo
If you really want to run a shell builtin with superuser privileges, you’d have to launch a shell as the external command. E.g., the following command runs bash
as the superuser with the cd
builtin command provided as a command line option:
$ sudo bash -c "cd /; ls"
bin etc lib media mnt ntp.peers proc sbin share sys
tmp var boot dev home lost+found misc net opt … …
Note: Aliases can not be passed as commands to Bash using its -c
option.
Shell redirection
Another issue to watch out for is that shell redirection takes place in the context of the current shell. If I try to run sudo /bin/echo abc > /test.file
, it won’t work. I get -bash: /test.file: Permission denied
. While the echo command runs with superuser privileges, it prints its output to my current (non-privileged) shell and, as a regular user, I don’t have permission to write to the /
directory.
One work-around for this is to use sudo
to launch a new shell (similar to the above example):
sudo bash -c "echo abc > /test.file"
In this case, the ouptut redirection takes place in the context of the privileged shell (which does have permission to write to /
).
Another solution is to run the tee
command as the superuser:
echo abc | sudo tee /test.file
root
may not have access to (e.g. encrypted volumes, remote NFS shares...)sudo
.