Ao tentar modificar um arquivo sem ter permissões de gravação, você recebe um erro:
> touch /tmp/foo && Sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Sudoing não ajuda, porque executa o comando como root, mas o Shell lida com o redirecionamento de stdout e abre o arquivo da mesma maneira:
> Sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Existe uma maneira fácil de redirecionar o stdout para um arquivo no qual você não tem permissão para gravar, além de abrir um Shell como root e manipular o arquivo dessa maneira?
> Sudo su
# echo test > /tmp/foo
Sim, usando tee
. Assim echo test > /tmp/foo
torna-se
echo test | Sudo tee /tmp/foo
Você também pode acrescentar (>>
)
echo test | Sudo tee -a /tmp/foo
Para substituir o conteúdo do arquivo pela saída de echo
(como o >
Operador de redirecionamento de shell).
echo test | Sudo dd of=/tmp/foo
Para gravar no arquivo (no começo, embora você possa usar seek
para gerar diferentes compensações) sem truncar (como o 1<>
Operador Bourne Shell):
echo test | Sudo dd of=/tmp/foo conv=notrunc
Para anexar ao arquivo (como >>
), com GNU dd
:
echo test | Sudo dd of=/tmp/foo oflag=append conv=notrunc
Veja também GNU dd
's conv=excl
para evitar atropelar um arquivo existente (como com set -o noclobber
em shells POSIX) e conv=nocreat
pelo contrário (atualize apenas um arquivo existente).
tee
é provavelmente a melhor escolha, mas dependendo da sua situação, algo como isto pode ser suficiente:
Sudo sh -c 'echo test > /tmp/foo'
Enquanto eu concordo, que | Sudo tee
é o caminho canônico, às vezes sed (assumindo aqui GNU sed
) pode funcionar:
cat sudotest
line 1
Sudo sed -i '1iitest' sudotest && cat sudotest
itest
line 1
Sudo sed -i '$aatest' sudotest && cat sudotest
itest
line 1
atest
-i
modifica o arquivo no lugar. 1i
significa inserir antes da linha 1. $a
significa acrescentar após a última linha.
Ou copie para o xclipboard:
somecommand | xclip
Sudo gedit sudotest
move cursor to desired place, click middle mouse button to insert, save
Tenho pensado no fundo de minha mente por um problema semelhante e descobri as seguintes soluções:
Sudo uncat
onde uncat
é um programa que lê a entrada padrão e a grava no arquivo nomeado na linha de comando, mas ainda não escrevi uncat
.
sudocat
a variante de sudoedit
que ainda não escrevi que faz um limpador Sudo cat
ou Sudo uncat
.
ou este pequeno truque de usar sudoedit
com um EDITOR que é um script Shell
#!/bin/sh
# uncat
cat > "$1"
que pode ser chamado como |Sudo ./uncat file
ou | EDITOR=./uncat sudoedit
mas isso tem efeitos colaterais interessantes.
Use esponja do pacote moreutils. Tem a vantagem de não gravar no stdout.
echo test | Sudo sponge /tmp/foo
Use a opção -a para anexar a um arquivo em vez de substituí-lo.
O erro vem da ordem em que o Shell faz as coisas.
O redirecionamento é tratado antes mesmo que o Shell execute Sudo
e, portanto, é feito com as permissões do usuário em que você está trabalhando no momento. Como você não tem permissões de gravação para criar/truncar o destino do redirecionamento, você recebe um permission denied
erro do Shell.
A solução é garantir que o arquivo de saída seja criado sob a identidade que lhe foi dada por Sudo
, por exemplo com tee
:
$ generate_output | Sudo tee target_file