Command the Command Line

Part II - Getting Your Bearings

All about `sudo`

If you've been using a Unix-like environment before working through this guide, you may recognize the word sudo. It shows up in commands and scripts all over the Internet, often without an explanation. Even if you've never seen it before, it's an important part of working on the command line.

What does it do? How does it work? When should you use it?

That's what this chapter is all about.

Background: Users and permissions

vm$ echo $HOME
/home/sally
vm$ ls /home
larry
nancy
sally
xavier
vm$ 

Recall from Chapter 4 - A Brief History of Unix that Unix was designed as a time-sharing system. Many people were expected to be logged in and working at the same time. The system recognizes "users" as a way to promote privacy while still allowing people to share files and devices.

We've already seen some evidence of this: our $HOME directory isn't simply /home; it's a sub-directory of /home named sally. This suggests that there might be more directories for other people.

vm$ ls /home/larry
ls: cannot open directory /home/larry: Permission denied
vm$ 

We don't generally have access to the $HOME directories that belong to other users. Chapter 16 - Users and Groups explains how the system manages file ownership, but for now, just know that a file's owner is a fundamental trait, much like its name.

whoami

Show the name of the current user

vm$ whoami
sally
vm$ 

The whoami application is one of the better-named utilities in our toolkit; it simply displays the name of the user who invoked it. We're about to learn to switch between accounts, so this will be a helpful tool to show the effect of the new commands.

Background: the root user

Root vegetables

"Root vegetables" by Sheep"R"Us is licensed under CC BY-NC-ND 2.0

A Unix-like system can have any number of user accounts like this. However, there is one special user that is present on all Unix-like systems: the "root" user (also known as the "superuser").

This is the administrative user account. It has no access control restrictions, meaning it has the permissions to do everything with every file and every directory. The root user's HOME directory is in a special location on the file system: /root.

vm$ rm -rf /bin
rm: cannot remove ‘/bin/zdiff’: Permission denied
rm: cannot remove ‘/bin/findmnt’: Permission denied
rm: cannot remove ‘/bin/bzegrep’: Permission denied
rm: cannot remove ‘/bin/gzexe’: Permission denied
rm: cannot remove ‘/bin/sh.distrib’: Permission denied
rm: cannot remove ‘/bin/chgrp’: Permission denied
rm: cannot remove ‘/bin/login’: Permission denied

This separation is helpful when you are learning because it means you are unable to perform many actions that would break things. Even the person who is "in charge" of the system (that's you in these exercises and on your personal computer) usually has a normal user account. In addition to reducing the risk of mistakes, working under a separate account limits the damage that a malicious program can do when it runs on your behalf.

sudo

vm$ whoami
sally
vm$ sudo whoami
[sudo] password for sally: ​       
root
vm$ 

The sudo utility allows us to execute single commands as the root user.

There is some disagreement about where its name comes from. Some say it is short for "super user do." Because you may use the -u option to execute a command as any user, some argue that it is short for "switch user and do."

vm$ whoami
untrusteduser
vm$ sudo whoami
[sudo] password for untrusteduser: ​       
untrusteduser is not in the sudoers file.  This incident will be reported.
vm$ 

Not all users are able to use sudo. If you are working on a machine that you do not own, you may need to request the necessary permissions from your system administrator.

vm$ sudo echo "After I've authenticated once..."
[sudo] password for sally: ​       
After I've authenticated once...
vm$ date
Wed Dec 31 1969 19:00:00 EST 1969
vm$ sudo echo "I stay in 'sudo mode' for a little while."
I stay in 'sudo mode' for a little while.
vm$ date
Wed Dec 31 1969 19:21:00 EST 1969
vm$ sudo echo "...but I'll need to re-authenticate every so often."
[sudo] password for sally: ​       
...but I'll need to re-authenticate every so often.
vm$ 

Most systems are configured to "recognize" users that have recently authenticated with sudo. In this state, you will still need to use sudo to take actions as the root user, but you will not have to re-enter your password. This status will expire after a short period (15 minutes by default).

Using sudo safely

vm$ apt-get install cowsay
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
vm$ sudo apt-get install cowsay
[sudo] password for sally: ​       
Reading package lists... Done
Building dependency tree
Reading state information... Done
cowsay is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 23 not upgraded.
vm$ 

You will need to use sudo when performing system administration tasks like installing software. (In this example, we're using the APT package manager commonly used in the Debian and Ubuntu GNU/Linux distributions.) It's generally safe to use sudo with system utilities and when you understand what the command is going to do.

Avoiding "unsafe" uses of sudo

vm$ sudo ./script-i-found-on-the-web.sh
[sudo] password for sally:  ​       
Installing a key logger... Done
Deleting all your applications... Done
vm$ 

However, many tutorials online contain instructions that use sudo unsafely. Remember that the root user can do anything, so using sudo with an untrusted program from the Internet may cause all sorts of problems.

vm$ sudo apt-get install the-dependency-i-need
[sudo] password for sally: ​       
vm$ ./script-i-found-on-the-web.sh
Performing actions as the current (de-privileged) user
vm$ 

It's much better to perform the administrative actions manually and rely on the untrusted program to do the rest. Even this is dangerous, though--the script could still access your personal files. There is no substitute for trusting the code you run, whether through reading the source or through having confidence in its origins!

In Review

Exercise

  1. Recall from Chapter 6 - Command Invocation that when we run the following command:

    echo ~
    

    the shell steps in and replaces the ~ with a path to the current user's "home" directory. Consider the following command:

    sudo echo ~
    

    What do you expect will happen when we run that?

  2. What does the following command mean?

    sudo sudo whoami
    

    Are there any reasons to use sudo twice like that?

Solution

  1. The output of sudo echo ~ should be /home/vagrant. That's the same as if we didn't use sudo at all. Remember that the shell makes its substutions before the command runs. sudo hasn't changed the active user at that moment. So even though echo does run as the root user, it's being invoked with the value /home/vagrant. It's just like we had written sudo echo /home/vagrant.

  2. Remember that sudo is an application that interpets the options you pass it as a new command. It may look a little strange to give sudo a sudo command, but the application still works the same way as the other examples in this chapter.

    In sudo sudo whoami, sudo receives sudo whoami and runs that command as the root user. Then, sudo whoami, running as root, invokes the whoami command as root.

    The overall effect is the same as sudo whoami: whoami runs as the root user, and so we see root printed to the screen. There's not much reason to use sudo twice like that, so you can save yourself the extra typing!