Como executar um comando que envolve redirecionar ou canalizar com o sudo?

60

Estou tentando seguir o que presumo serem as melhores práticas de uso do sudo em vez da conta raiz.

Estou executando uma operação simples de arquivo concat, como:

sudo echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock

Isso falha à direita do ">>" que está sendo executado como usuário normal. A adição de sudos extras também falha (comportamento esperado desde a canalização para o comando sudo e não para o arquivo).

O exemplo é exatamente isso, mas foi verificado e testado na conta raiz.

DarkSheep
fonte

Respostas:

75

Você pode invocar um novo shell como root:

sudo sh -c 'echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'

Você também pode apenas elevar um processo para gravar no arquivo:

sudo tee -a /etc/conf.d/hwclock > /dev/null << EOF
clock_hctosys="YES"
EOF
Chris Down
fonte
8
Em geral, a segunda opção é mais segura, porque apenas os teecomandos são executados como raiz, não o comando principal, que pode ser complexo e propenso a comportamentos inadequados. (não é o caso de echo)
pabouk
19

Outra opção, igualmente segura, é usar sudoo -iswitch para fazer login como root:

$ sudo -i
# echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'

Isso ainda segue as regras de boas práticas, pois a conta raiz não está realmente ativada como tal, mas permite que você faça as coisas como raiz com segurança. De man sudo:

The -i (simulate initial login) option runs the shell
    specified by the password database entry of the target user
    as a login shell.  This means that login-specific resource
    files such as .profile or .login will be read by the shell.
    If a command is specified, it is passed to the shell for
    execution via the shell's -c option.  If no command is
    specified, an interactive shell is executed. 
terdon
fonte
Outra alternativa ésudo bash
starbeamrainbowlabs
11

Se você expressar seu comando sem aspas simples, poderá colocá-lo entre aspas simples e executá-lo por meio de um shell intermediário.

Para executar isso como root:

echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock

Escreva o comando de uma maneira diferente que não use ':

echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock

Em seguida, invoque sudo sh -c …:

sudo sh -c 'echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'

Como alternativa, para gravar a saída em um arquivo no qual somente o root pode gravar, chame sudo tee. Passe a -aopção para teeanexar ao arquivo de destino, caso contrário, o arquivo será truncado.

echo 'clock_hctosys="YES"' | sudo tee -a /etc/conf.d/hwclock >/dev/null

Para mais modificações de arquivo complexos, você pode chamar sudo sed, sudo ed, sudo perl, ...

Como alternativa, use um editor decente e faça com que ele chame sudo. No Emacs, abra /sudo:/etc/conf.d/hwclock. No Vim, chame :w !sudo tee %para gravar no arquivo aberto como root ou use o plug-in sudo.vim . Ou vá do final do sudo e ligue sudoedit /etc/conf.d/hwclock.

Ou você pode ceder ao lado sombrio e executar um shell como raiz.

$ sudo -i
# echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock
Gilles 'SO- parar de ser mau'
fonte
5

O comando falha devido às permissões no arquivo redirecionado para. O redirecionamento acontece antes mesmo de o sudocomando ser chamado.

Você precisará se certificar de que é a raiz que realmente abre o arquivo para gravação.

A maneira mais simples de fazer isso:

echo 'clock_hctosys="YES"' | sudo tee -a /etc/conf.d/hwclock >/dev/null

O echopode ser executado como você usuário comum, uma vez que apenas produz uma cadeia de texto. O teeutilitário terá que ser executado como root e tee -aanexará dados. Nós redirecionamos a saída para , /dev/nullporque tee, por padrão, duplicará seus dados de entrada na saída padrão, além de gravar nos arquivos indicados.

Com bashou qualquer shell que entenda "here-strings":

sudo tee -a /etc/conf.d/hwclock >/dev/null <<<'clock_hctosys="YES"'

Isso é idêntico em efeito ao acima. Somente a maneira como produzimos a string é alterada.


Outra maneira levemente indireta de fazer isso:

sudo sh -c 'echo clock_hctosys=\"YES\" >>/etc/conf.d/hwclock'

Aqui, o redirecionamento acontece dentro de um sh -cshell filho executando como root.

Kusalananda
fonte
4

sudo dd of=

Para adicionar como quiser:

echo inbytes | sudo dd of=outfile oflag=append conv=notrunc

ou para recriar o arquivo do zero:

echo inbytes | sudo dd of=outfile

Vantagens:

  • melhor do que teedesde nenhum /dev/nullredirecionamento
  • melhor do que shdesde nenhum subshell
  • ddpossui muitas opções poderosas, por exemplo, status=progresspara ver o progresso da transferência

Funciona porque o sudo encaminha o stdin para o comando.

Ciro Santilli adicionou uma nova foto
fonte