Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Debugging some of my scripts after upgrading from Debian Lenny to Ubuntu 10.04. In so doing, I tripped over this "problem," the solution to which may give me a clue to others.
On a bash shell command line I created a file thusly:
sudo touch zero_file
and it lists as expected with default permissions 0644:
I can place the command (minus the "sudo") in a script & run it under the auspices of sudo & it works. Am I missing something re the stdin redirection when using sudo?
You need to change the permissions for the file to be **6 - you're not root, and only the owner of the file (root) can write to it. Sudo carries over the user and user's group (ie. you don't actually become root). From a bit of experimentation, if you wanted to do the same as "touch" but creating it with your own user, you could use
Snark, Thanks for the input. However, your command suggestion fails as well. I do need to understand the subtleties of sudo & shells better. And if sudo doesn't make me root, effectively, why did the file created with "sudo touch zero_file" end up with root as owner (and group)?
As I understand it so far, the shell I'm in (and not logged in as root) does the redirection. So, the first part of the command ("sudo echo abcd") executes with root privilege, but then the result devolves back to my non-root shell which can't append it to the file.
I can see myself making this mistake in the future also as I think this will remain something of a mind-screwer for me.
sudo spawns a new context as a particular user. Snarks post is incorrect. If I sudo -u root (or omit the -u parameter) and execute a command, I am root executing that command. sudo bash = root shell. sudo vi /etc/passwd = root editing /etc/passwd. sudo id should be sufficient to convince you.
I/O redirection applies to the current shell context (in which, your current user is the user doing the writing). As such, if you type "echo 'asdf' > file" the shell will attempt to open file for writing and put asdf into it. Clearly, if file is owned by root and only writable by the owner, and you are not root, you don't have permission.
To do what you want requires a bit of thought the sudo sh -c "xxx" is one way, since it tells sudo to spawn a shell which executes only those things which are in the quotations. Additonally, you could write a shell script like (untested):
Here the shell executes "sudo" which execute "echo abcdef" (nothing more) and then redirects output to zero_file (without sudo in effect).
Code:
sudo sh -c "echo abcd >>zero_file"
( sudo (sh -c "(echo abcd >>zero_file)") ) - added brackets for clarification
And here shell executes the sudo which executes another shell which execute "echo abcd >>zero_file"
Other words redirect operator ">>" is executed in shell after all commands, has least priority. The quotes can change priority, but unfortunately they also switched off special meaning of ">>" symbol. So trick with another shell was needed.
To clear up some confusion about the "priority" of the > and >> operators, here is a description of what happens:
After you type
Code:
sudo echo "abcdef" >zero_file
your shell parses the line, and then forks a child process. The child process sets its standard output to "zero_file" (in append mode if you use >>), and then it executes the command. Because the file is opened for writing by the shell before sudo is executed, the command fails (since you as non-root don't have permission to write to the file).
I'm not completely sure about this, but I have some ideas why this might be happening. Hopefully someone who knows better will reply to correct any misconceptions I may accidentally convey here.
On my system (Kubuntu) I have a program /bin/echo.
Code:
~$ which echo
/bin/echo
But Bash also has it's own built-in function echo.
Bash built-ins normally take precedence over external programs. When I type echo on the command line, I am normally talking to Bash's built-in echo function. This can be demonstrated by a simple test.
Code:
~$ echo --help
--help
~$ /bin/echo --help
Usage: /bin/echo [OPTION]... [STRING]...
Echo the STRING(s) to standard output.
-n do not output the trailing newline
-e enable interpretation of backslash escapes
-E disable interpretation of backslash escapes (default)
--help display this help and exit
--version output version information and exit
. . .(goes on for many more lines). . .
echo by itself invokes the Bash built-in function. The Bash built-in function does not honor the --help option, and instead treats it as a string to be printed to stdout.
/bin/echo invokes the external program which honors the --help option. The help text is printed to stdout.
Here's the part where I tie this into OPs question. Which echo command do I get when I invoke sudo echo?
Code:
~$ sudo echo --help
Usage: /bin/echo [OPTION]... [STRING]...
Echo the STRING(s) to standard output.
-n do not output the trailing newline
-e enable interpretation of backslash escapes
-E disable interpretation of backslash escapes (default)
--help display this help and exit
--version output version information and exit
. . .(goes on for many more lines). . .
It looks like sudo is invoking the external echo command. If your system is configured similarly to mine, then perhaps you are also getting /bin/echo. I'll assume that is the case.
The output of /bin/echo is then redirected to zero_file which is owned by root.
Permissions -rw-r--r-- means that only processes owned by root may write to the file.
Now let's add your redirection into the mix. Redirection is done by the Bash (I think?), not by external programs. That leads me to some important questions.
Which process is performing the redirection?
Who owns the process performing the redirection?
Does that owner have permission to write to the file?
Here's where I make a few assumptions while attempting to answer those three questions.
Bash performs the redirection.
Bash is owned by the user sitting at the terminal, debsys07.
User debsys07 does not have permission to write to the file.
Now let's look at that solution Google found for you.
Code:
$ sudo touch bar
[sudo] password for me:
$ ls -l bar
-rw-r--r-- 1 root root 0 2011-03-09 15:45 bar
$ sudo sh -c "echo abcd >>bar"
$
bash owned by debsys07 invokes sudo.
sudo invokes sh for a single command as root.
sh (owned by root) performs the redirection.
sh (owned by root) has permission to write to the file, and does so.
sh (owned by root) exits.
Control returns to bash (owned by debsys07).
And that's what I think is going on here. Is there anything I've missed or gotten wrong?
Last edited by Telengard; 03-09-2011 at 03:03 PM.
Reason: fix code tag
If I sudo -u root (or omit the -u parameter) and execute a command, I am root executing that command. sudo bash = root shell. sudo vi /etc/passwd = root editing /etc/passwd. sudo id should be sufficient to convince you.
I/O redirection applies to the current shell context (in which, your current user is the user doing the writing). As such, if you type "echo 'asdf' > file" the shell will attempt to open file for writing and put asdf into it. Clearly, if file is owned by root and only writable by the owner, and you are not root, you don't have permission.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.