1. Overview

As we know, we can redirect the standard output (stdout) of a command to a file using the “*>*” operator in the Linux command line.

However, sometimes, we want to redirect to a file where we don’t have permission to write — for example, “sudo command > file_requires_root_permission“.

In this case, we may get a “Permission denied” error even if we’ve used the sudo command.

In this quick tutorial, we’ll analyze the cause of this problem and address the right ways to solve it.

2. Introduction to the Problem

An example is probably the best way to explain the problem.

Let’s say we have an empty, plain text file:

kent$ ls -l /opt/output.txt
-rw-r--r-- 1 root root 0 May  8 10:43 /opt/output.txt

The ls output above shows that only user root can write to the /opt/output.txt file.

Now, we attempt to redirect the output of an echo command to the mentioned file as the regular user kent:

kent$ echo "Linux is awesome!" > /opt/output.txt
bash: /opt/output.txt: Permission denied

We’ve gotten the “Permission denied” error. It isn’t hard to understand. This is because we execute the echo command and redirect the output as the kent user, but the user kent has no write permission on the file /opt/output.txt.

We know if we execute a command with sudo, the command will be executed as the root user. Let’s say the user kent has been granted the sudo privilege.

Next, let’s see if we can redirect the echo output to our target file using sudo:

kent$ sudo echo "Linux is awesome!" > /opt/output.txt
[sudo] password for kent:
bash: /opt/output.txt: Permission denied

Oops, after we give the password, we keep having the same error message.

We may ask why we still don’t have permission to write to the file though we’ve used the sudo command?

Next, let’s find the answer to the question.

3. Why Do We Have the “Permission Denied” Error?

To answer the question, let’s take a closer look at the whole echo command. The command has two parts:

  • The command part: sudo echo “Linux is awesome!”
  • The redirection part: > /opt/output.txt

The sudo command allows us to execute the echo command as the root user. However, when we write “sudo command > file“, the sudo command won’t affect the redirection part.

In other words, the redirection is still performed as the regular user kent. Therefore, we encounter the “Permission denied” error.

Now that we understand the cause of the problem, let’s discuss the solutions.

We’ll address several different approaches to solve the problem:

  • Launching a “root” shell to execute the command
  • Wrapping the command in a shell script
  • Changing the redirection part into a command

Next, let’s look at these three approaches one by one.

4. Launching a “root” Shell to Execute the Command

If we can start a shell logged in as the root user and execute our command in this shell, the redirection will also be done by root.

We can pass the -s option to the sudo command to have a “root” shell:

kent$ sudo -s
[sudo] password for kent: 
[root]# echo "Linux is awesome!" > /opt/output.txt
[root]# exit 
kent$ cat /opt/output.txt
Linux is awesome!

As the output above shows, after executing sudo -s, we’re in an interactive shell with the root user. Then, we can execute the whole command and redirection as root.

The output has also been successfully written to the target file.

5. Wrapping the Command in a Shell Script

If we can turn the command and redirection into a single command, we can execute it with sudo so that the redirection gets done by root.

Following this idea, we can create a simple shell script file containing our echo command:

kent$ cat myScript.sh
#!/bin/bash
echo "Linux is awesome! - (shell script)" > /opt/output.txt

Next, let’s empty the /opt/output.txt file and test our myScript.sh:

kent$ sudo ./myScript.sh 
[sudo] password for kent:
kent$ cat /opt/output.txt
Linux is awesome! - (shell script)

Our shell script works as we expected.

However, it can be inconvenient if we always have to create shell script files for commands with redirections.

If we want to execute such a command only once quickly, we can use sudo bash -c “Command > file” to execute the command with redirection in a sub-shell so that the root user performs both the command and the redirection:

kent$ sudo bash -c 'echo "Linux is awesome! - (sub-shell)" > /opt/output.txt'
[sudo] password for kent: 
kent$ cat /opt/output.txt
Linux is awesome! - (sub-shell)

6. Changing the Redirection Into a Command

We’ve learned from a previous section that the sudo command won’t affect the redirection part. However, if we can change the redirection into a command, we can execute it with sudo once again.

The tee command is exactly what we are looking for. tee* allows us to redirect the input to a file and *stdout. Further, we can launch “sudo tee …” to cause the tee command to be executed as the root user.

Next, let’s test this approach with our example:

kent$ sudo echo "Linux is awesome! - (using tee)" | sudo tee /opt/output.txt >/dev/null
[sudo] password for kent: 
kent$ cat /opt/output.txt
Linux is awesome! - (using tee)

As the example above shows, we’ve written the expected value in the /opt/output.txt file.

Since we don’t want to print the text in stdout, we redirect tee‘s stdout to /dev/null.

7. Conclusion

When we execute commands like “sudo command > file_requires_root“, we may encounter the “Permission denied” error.

In this article, we’ve discussed this error, why it occurs, and several ways to solve the redirection problem.