0

How to do that with a regular sudoers user:

wget -q https://example.com/binary.tar.gz -O - | tar -xzO binary > /usr/local/bin/binary # Doesn't work because I can't write in /usr/local/bin as regular user

I can't use sudo with the redirect >. So what is the appropriate way to do it?

Subsidiary question: I know I can use tee for the following case:

echo "foo" > /etc/myapp.conf # Doesn't work
echo "foo" | sudo tee -a /etc/myapp.conf # Solution

But I know this is not the goal of tee. So the question is the same for this case: what's the best solution?

EDIT:

  • I don't want to use a subshell with something like sudo sh -c 'my-command'. One reason is to limit as much as possible the number of commands launched as root.
  • This is a question to find a solution in the "linux standard", not some kind of hacking.
  • I think the goal of tee is to write output to some files AND in the stdout. I don't want to use something which can do that, but something which exists to do that.
Antoine
  • 310
  • 1
  • 5
  • 14
  • "I know this is not the goal of tee" -- why do you say that? This is a perfectly valid use of tee. – glenn jackman Sep 16 '21 at 13:16
  • Yes, it's a valid use of tee, but this is not the main goal of tee which is designed to output to some files AND in the stdout (like a `T` I guess). – Antoine Sep 16 '21 at 13:59

1 Answers1

3

The reason you cannot redirect to a file you don't have write access to, is because the shell does the opening of the file. When using sudo only the process that are ran with special privileges, consider the following example:

$ sudo my-cmd --flag1 --flag2 > file

The shell invokes the command sudo with the arguments: my-cmd, --flag1 and --flag2, and tries to open a file called file, and connect the sudo process' standard output to the input of the file.

The command sudo will elevate the users permissions and execute the command my-cmd with the arguments --flag1 and --flag2.

Understanding this it also becomes clear why you cannot just prefix with sudo to write to a file that you don't have permissions to.

Instead you can, as you have already discovered, use tee as it can take a path as an argument and open it for writing.

Alternative you can invoke another shell with special privileges:

$ sudo sh -c 'my-cmd --flag1 --flag2 > file'

This will invoke the shell sh with escalated privileges. This however becomes quite tedious as you'll need to stick your whole command into one argument for sh. This will cause quotes and glob to be hard to write properly.

Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
  • Thanks @andlrc. Yes, I know why it does not work, I just want to find a "clean solution". I edited my post to explain I don't want to use a subshell. I hope there is a solution similar to tee. – Antoine Sep 16 '21 at 13:55