3

There are some commands like cd or ll that if I run them as sudo, their execution just "breaks".

What is a rule of thumb to know which commands will "break" this way when a sudo command precedes them?

This data can help me and other newcomers to code stabler scripts.

3
  • 4
    Shell builtins and aliases? Mar 27, 2017 at 14:03
  • 1
    Anything root may not have access to (e.g. encrypted volumes, remote NFS shares...)
    – thrig
    Mar 27, 2017 at 15:22
  • 1
    I don't think this question should be closed as being too broad. I think my answer provides a reasonably comprehensive “rule of thumb” for determining whether a command will run as the user might expect it to run with sudo. Mar 27, 2017 at 17:03

3 Answers 3

6

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
2
  • This is a very good answer, but the first statement is false. You need to run kill with sudo to stop processes started by another user.
    – Bruno9779
    Mar 27, 2017 at 16:29
  • 1
    @Bruno9779 In that case, you're running an external kill command (provided by the util-linux package on most GNU/Linux systems). In fact, I've already mentioned kill it in my Example 3. Rather than downvote incomplete/misleading answers, I thought I'd add a better one. Mar 27, 2017 at 17:00
0

cd or ll is not a program, but in fact it is a built-in command in shell. You can view all the available built-in commands by using the following command.

compgen -b

sudo will not work with all these commands.

3
  • 1
    No. ll is an alias
    – Bruno9779
    Mar 27, 2017 at 14:42
  • Also it is not true at all that all builtins will not work with sudo. EG: pwd true kill
    – Bruno9779
    Mar 27, 2017 at 14:46
  • 1
    @Bruno9779 the versions you run with sudo are the standalone executables. The built-in versions do not run with sudo.
    – roaima
    Mar 27, 2017 at 21:05
0

ll does not work with sudo because it is an alias. Aliases do not work with sudo, as you don't get an interactive shell with sudo (unless asked specifically)

cd is a different case, since it doesn't make sense to change to a directory you don't have permission with sudo.

As suggested many builtins will not work with sudo, but others do, most notably kill. You need to run sudo kill <pid> to kill a process started by an user different than yours.

3
  • Even when the ll alias is defined in root's .bashrc, sudo ll reports command not found, because sudo <command> (or sudo -i <command>, or sudo -s <command>) doesn't start an interactive shell.
    – JigglyNaga
    Mar 27, 2017 at 15:00
  • You are right, aliases don't work either way. I have edited my answer
    – Bruno9779
    Mar 27, 2017 at 15:07
  • 1
    The versions you run with sudo are the standalone executables. The built-in versions do not run with sudo. At all. For one example of a difference between a built-in and its corresponding standalone, try cd /tmp; mkdir a; ln -s a b; cd b; pwd; /bin/pwd
    – roaima
    Mar 27, 2017 at 21:06

You must log in to answer this question.