I was trying to use an alias which should run two commands, where the first is fine to be run with normal user privileges and the second one needs sudo privileges.

alias hosts-get="scp user@host.com:/etc/hosts /tmp/ && sudo cat /tmp/hosts >> /etc/hosts"

The usecase is to pull the hosts file of a remote server and then append it to the hosts file on my own computer (the remote server contains all the IP to domain information of client systems).

However, when running the alias I get zsh: permission denied: /etc/hosts, so it looks like the sudo is being ignored or rather zsh can't interpret it or something.

After some searching around I changed the alias to this:

alias hosts-get="scp user@host.com:/etc/hosts /tmp/ && cat /tmp/hosts | sudo tee -a /etc/hosts"

This looks to work correctly. Can someone please explain the background of this?

  • 1
    cat is being run by sudo, the redirect is done by the shell which is unprivileged.
    – Oskar Skog
    Feb 11 '20 at 8:26

While the sudo command in your first alias provides root privileges for cat /tmp/hosts the redirection >> /etc/hosts will be tried with your user privileges.
As those usually are not high enough you get the 'permission denied' error.

To make this work, you can run the command in a subshell like this:

alias hosts-get="scp user@host.com:/etc/hosts /tmp/ && sudo sh -c \"cat /tmp/hosts >> /etc/hosts\""  

or just do it the way you did it with your second approach.
Here you redirect the output of the 'unprivileged' cat command into the privileged 'tee' command which then has the right to append the information to /etc/hosts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.