LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   Root (sudo) can't write to file it created (http://www.linuxquestions.org/questions/linux-general-1/root-sudo-cant-write-to-file-it-created-867527/)

debsys07 03-09-2011 01:41 PM

Root (sudo) can't write to file it created
 
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:

-rw-r--r-- 1 root root 0 2011-03-09 11:18 zero_file

But then this command fails

sudo echo abcdef >>zero_file
-bash: zero_file: Permission denied

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?

Thanks,
Ron

Snark1994 03-09-2011 01:54 PM

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
Code:

sudo echo "" >> zero_file
Hope this helps,

debsys07 03-09-2011 01:57 PM

Ah! Never mind -- more googling revealed this hint:

sudo sh -c "echo abcd >>zero_file"

debsys07 03-09-2011 02:11 PM

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.

-Ron

EDDY1 03-09-2011 02:28 PM

You have to be part of sudoers group to sudo

orgcandman 03-09-2011 02:31 PM

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):

Code:

#!/bin/bash
FILENAME=$1
shift
echo "$1" > $FILENAME

and execute like:
sudo /path/to/script_writer /path/to/file "all this blah"

Just a heads up.

eSelix 03-09-2011 02:38 PM

It is priority of execution issue.

Code:

sudo echo abcdef >>zero_file
( (sudo (echo abcdef)) >> zero_file ) - added brackets for clarification

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.

hda7 03-09-2011 02:49 PM

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).

Telengard 03-09-2011 02:55 PM

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.

http://www.gnu.org/software/bash/man...#Bash-Builtins

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.

Quote:

Originally Posted by debsys07 (Post 4284575)

sudo echo abcdef >>zero_file
-bash: zero_file: Permission denied

  • sudo invokes /bin/echo.
  • 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?

Snark1994 03-10-2011 09:32 AM

Quote:

Originally Posted by orgcandman (Post 4284630)
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.

Thanks for the correction :)


All times are GMT -5. The time now is 07:39 AM.