Naturally enough, when you run a command or script the system executes it as a process that was launched by you. But you can run commands and scripts as another user.
Processes Have Owners
When a program or script is executed, Linux creates a process. That process has an owner. The owner is either another process or the name of a user account if a person launched it.
The ownership of a process defines some of the capabilities and the environment of the process. Depending on how the process was launched, it inherits certain attributes of its parent process or the user. Or, more strictly, the process that the user used to launch the program which is usually a shell.
Running a command or script as another user can be useful because the ownership of any files that are created by the process will belong to the appropriate user.
Every time we use sudo
we’re running a command as another user. The default user account used by sudo
is the root or ‘super’ user. Because of that, sudo
is often mistakenly thought to stand for super user do. But that’s just slack jargon. It actually stands for substitute user do.
With sudo
, you can run commands as any other user, not just as root. Ironically, you need root privileges to do so. But launching a program or script owned by another user isn’t the same as running that process as that other user. You’ll still be running it as root.
Here’s how to actually run a process as another user, and how to run commands from within a script as though they had been executed by another user.
Run a Script as Another user
We’re using a computer that has multiple users configured. One is Mary, who has the username maryq, and the other is Dave with the user name dave.
Mary has a script called “other-user.sh” in her home directory. This is the text of the script.
#!/bin/bash echo "Script name:" $0 echo "Working directory:" $(pwd) echo "Script running as user:" $(whoami)
It prints out the script name, which is held in the $0
environment variable. It then uses pwd
to print the working directory. Finally, it uses the whoami
command to print the name of the user who launched the script. Or who it thinks launched the script.
Copy the text from the script into an editor and save it as “other-user.sh” in the home directory of a different user account.
We’ll need to make the script executable. We’ll use the chmod
command and use the +x
(execute) option and the -u
(user) option to set the execution flag for the owner only. That means only Mary can run the script. We’ll check the file permissions with ls
.
chmod u+x other-user.sh
ls
From left-to-right, the permissions read:
- The owner can read, write, and execute the file.
- Group members can read and write the file.
- Others can only read the file.
So the only users capable of running the script are Mary and root. This is what happens when Mary runs the script:
./other-user.sh
We are told the current working directory of the script is Mary’s home directory, and the owner of the script is the user account maryq.
As expected, Dave can’t run the script.
/home/maryq/other-user.sh
If Dave has root user privileges, he can try to run the script as root, using sudo
.
sudo /home/maryq/other-user.sh
This is a partial success. The script runs, but the owner of the script is root, not maryq.
The trick we need to employ is the sudo -u
(user) option. This lets you specify the user you want to run the command as. If you don’t use the -u
option, sudo
defaults to using root. If we want to run the command as Mary, we need to pass the name of their user account to the sudo
command.
sudo -u maryq /home/maryq/other-user.sh
This time the script reports that the process owner is maryq.
Let’s add a line to the “other-user.sh” script. We’ll echo
some text and redirect the output into a file called “mary.txt.”
#!/bin/bash echo "Script name:" $0 echo "Working directory:" $(pwd) echo "Script running as user:" $(whoami) echo "This is going into a file in /home/maryq/" > /home/maryq/mary.txt
We’re creating the new file in Mary’s home directory. This is perfectly fine because we’re running the script as Mary.
./other-user.sh
If we check in Mary’s home directory we’ll see the file has been created, and the ownership of the file belongs to the maryq user account.
ls -hl mary.txt
This is the same behavior we’d see if Mary had actually launched the script herself.
RELATED: How to Use the chmod Command on Linux
The runuser Command
You could use the sudo -u
commands we’ve used so far inside a script, but there’s another command, runuser
, that’s designed to run processes as a different user from inside scripts. It has better handling of the return code from the launched process, and it has fewer overheads than sudo
.
The runuser
command needs to be run by root, but that is accomplished by running the entire script as root. You don’t need to use sudo
inside the script. The runuser
command can be used on the command line, too, so isn’t restricted to script use, although it is the preferred method for scripts.
Dave can’t list the “mary.txt” file because it is in Mary’s home directory and he doesn’t have access.
cat /home/maryq/mary.txt
We can peek inside the file using runuser
, however. The -
(login) option launches a new shell with an environment very close to the shell environment Mary would have if they had actually logged in. The -c
(command) option is followed by the command we want to run.
sudo runuser - maryq -c 'cat mary.txt'
Note that the command doesn’t need the full path to the file. We can reference the file in the same way that Mary would, relative to her home directory.
As user Dave, we’ll create a script called “run-maryq.sh” with this text in it:
#!/bin/bash runuser -l maryq -c 'cat mary.txt'
We’ll make it executable:
chmod +x run-maryq.sh
Let’s see what happens when we try to run it.
./run-maryq.sh
The runuser
command complains because it is being executed by a regular user. Let’s run it again with sudo
.
sudo ./run-maryq.sh
That works as we’d like it to, and just as if Mary had launched the script herself.
Which One to Use?
On the command line, there’s not a lot to choose between them. But as you’ve got to use sudo
with runuser
anyway, you might as well use sudo
on its own.
But in a script, runuser
is the preferred command.