How to solve "permission denied" when using sudo with redirection in Bash?
When using sudo to allow edits to files, I regularly get 'permission denied'.
For example, my mouse is jittery and sluggish, so I want to disable polling:
sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf
I'm prompted for a password, and then get:
bash: /etc/modprobe.d/local.conf: Permission denied
So I tried to do a temporary change to disable polling by using:
sudo echo N> /sys/module/drm_kms_helper/parameters/poll
Yet again the system responded with:
bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied
Output redirection (via the
>operator) is done by the shell, not by echo. You have to login as root
Then you can use redirection
echo N> /sys/module/drm_kms_helper/parameters/poll
Otherwise you can run bash string with sudo
sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"
You can't run echo with sudo? the what about the result I got: `[email protected]:~$ sudo echo "Hi" [sudo] password for saji: Hi`
you can write on file, echo "something" > somewhre. It's using pipe.. That is the problem.
Ok, if that's the case, then please update your answer to reflect that running echo is a problem in that case only.
You can't simply run the shell builtin `echo` as sudo, unless you do something like `sudo bash -c 'echo …'`; however, POSIX systems usually supply an external `echo` command such as `/bin/echo` on OS X, which sudo can execute without rigamarole. Thus, the `echo` command you usually run and the `echo` command you run with sudo are probably two different, but similar commands.
If that is the case, why did the answers to this question suggest echo? http://askubuntu.com/questions/840431/high-cpu-usage-for-kidle-inject-x-in-ubuntu-16-10
The output redirection is done by the shell from which the command has been invoked. So, breaking everything into bits, here what is happening*:
sudo echo "options drm_kms_helper poll=N", which executes
echo "options drm_kms_helper poll=N"command line
sudo asks for a password, opens superuser shell and invokes
echo "options drm_kms_helper poll=N", which runs
echocommand passing it
"options drm_kms_helper poll=N"
echo, running with
rootprivileges, prints the string to its standard output.
echocommand terminates, superuser shell exits,
the shell from which the command has been invoked collects the output and tries to redirect it to
/etc/modprobe.d/local.conf, which is writeable only by root. It gets "permission denied" error.
For the ways to fix this see @shantanu answer.
(*) - while the above sequence helps to understand why the command fails, in reality things happen somewhat out-of-order: the original shell notices the redirection and tries to open the file for writing before invoking the
sudo ...command. When opening the file fails the shell doesn't even invoke the command which was supposed to write to the file (thanks to @PanosRontogiannis for pointing this out).
Here's a quick test:
$ touch ./onlyroot.txt $ sudo chown root:root ./onlyroot.txt $ sudo bash -c "whoami | tee who.txt" > onlyroot.txt bash: onlyroot.txt: Permission denied
In the test above the
whoami | tee who.txtwas going to create a file named
who.txtcontaining the word "root". However, when the output redirection fails in the calling shell, "who.txt" file is also missing because the command was not invoked.
More likely the shell 'forks' itself and tries to open /etc/modprobe.d/local.conf before trying to 'exec' sudo which means that the first 4 steps your describe never actually happen because the file cannot be opened.
You can use a
teecommand like this:
sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10
Or if its a command's output:
echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll
If you had a situation where you wanted to append rather than overwrite the target file--that is, to make
>--you would use
+1 logging in as root is a bad idea for manual work, and a *really* bad idea for scripted tasks.
An approach I haven't seen mentioned here is to simply execute the entire commandline in its own shell. The
sudomanpage itself gives an example of this approach:
To make a usage listing of the directories in the /home partition. Note that this runs the commands in a sub-shell to make the cd and file redirection work.
$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
sudo dd of=
To append as you want:
echo inbytes | sudo dd of=outfile oflag=append conv=notrunc
or to recreate the file from scratch:
echo inbytes | sudo dd of=outfile
- nicer than
- nicer than
shsince no explicit subshell (but an implicit one for the redirection)
ddhas many powerful options, e.g.
status=progressto see transfer progress
Works because sudo forwards stdin to the command.
This is good. We think of `dd` as how we overwrite our once-great filesystems, and don't realize it's for mundane tasks too--and that other commands as root also cause great harm if used on on the wrong files/devices. Like `sudo tee`, `sudo dd` will of course also work with here strings, e.g., `sudo dd of=outfile <<<'hello world'`. [Thanks for editing. NB with `sh -c 'cmd'`, `sh` is a subprocess that's a shell, but not really a subshell except in the sense *all* external commands begin as one.]
- nicer than