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
shell
permissions
io-redirection
sudo
io
Michael Mrozek
fonte
fonte
chown
mudar de proprietário; foi apenas um exemploRespostas:
Sim, usando
tee
. Entãoecho test > /tmp/foo
se tornaVocê também pode acrescentar (
>>
)fonte
echo test | sudo tee /tmp/foo > /dev/null
Para substituir o conteúdo do arquivo pela saída de
echo
(como o>
operador de redirecionamento de shell).Para gravar no arquivo (no início, embora você possa usar
seek
para produzir diferentes deslocamentos) sem truncar (como o1<>
operador de shell Bourne):Para acrescentar ao arquivo (como
>>
), com o GNUdd
:Veja também GNU
dd
'sconv=excl
para evitar derrotar um arquivo existente (comoset -o noclobber
em shells POSIX) econv=nocreat
pelo contrário (atualizar apenas um arquivo existente).fonte
echo test | sudo tee /tmp/foo >/dev/null
para descartar a saída.dd
não é confiável para isso, a menos que você esteja usando opções obscuras apenas do GNUiflag=fullblock oflag=fullblock
, o que remove a elegância desta resposta. Eu vou ficar comtee
.dd
pode ser bastante perigoso (se não quer dizer: devastador) se apenas um pequeno erro foi cometido. Portanto, para novos usuários, prefiro recomendar otee
método para estar em um local seguro.dd of=file
sozinho (semcount
/skip
...), é confiável.iflag=fullblock
não é necessário porque aquidd
escreve na saída o que leu na entrada. Não importa se não foram blocos completos.tee
é provavelmente a melhor escolha, mas, dependendo da sua situação, algo como isto pode ser suficiente:fonte
eval
vez de um simplessh -c
; -i, que mudará seu diretório de trabalho; executando o comando inteiro como root, o que pode mudar seu comportamento ou introduzir um risco desnecessário. Por que isso foi aprovado?Enquanto eu concordo, essa
| sudo tee
é a maneira canônica, às vezes o sed (aqui assumindo o GNUsed
) pode funcionar:-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:
fonte
sed -i
, na verdade, não modifica o arquivo no local - ele cria um arquivo temporário e o renomeia ao sair. Então você não vai ser capaz de fazer algo assimtail -f ...
no arquivo original e ver a saída usandosed -i ...
enquanto o gasoduto está sendo executado-i creates a new file of same name
ou há algo mais compacto? Eu acho que gostoin place
, porque explica oi
. A página de manual do gnu-sed também o coloca no lugar e a bandeira longa é--in-place
.Tenho pensado no fundo de minha mente por um problema semelhante e descobri as seguintes soluções:
sudo uncat
Ondeuncat
está um programa que lê a entrada padrão e a grava no arquivo nomeado na linha de comando, mas ainda não o escreviuncat
.sudocat
a variante dosudoedit
que eu não escrevi ainda que faz um limpadorsudo cat
ousudo uncat
.ou esse pequeno truque de usar
sudoedit
com um EDITOR que é um script de shellque pode ser invocado como um
|sudo ./uncat file
ou mais,| EDITOR=./uncat sudoedit
mas que tem efeitos colaterais interessantes.fonte
cat
leva uma lista de arquivos para con gato inata, portanto CCT deve dar uma lista de arquivos para un con gato inata para. Teria que usar magia para decidir quanto colocar em cada arquivo. Nome alternativo incluemdog
,to-file
,redirect
.uncat
quando tivertee
.tee
tem a desvantagem trivial de gravar seu stdin em seu stdout - o que é trivialmente mitigado redirecionando o stdout para/dev/null
. Outras alternativas incluemdd of=/tmp/foo
(mencionadas em outra resposta), que grava informações de status no stderr, ecp /dev/stdin /tmp/foo
.Use esponja do pacote moreutils. Tem a vantagem de não gravar no stdout.
Use a opção -a para anexar a um arquivo em vez de substituí-lo.
fonte
/dev/null
se fosse um problemaO erro vem da ordem em que o shell faz as coisas.
O redirecionamento é tratado antes da execução do shell
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 umpermission denied
erro do shell.A solução é garantir que o arquivo de saída seja criado sob a identidade que lhe é fornecida
sudo
, por exemplo, comtee
:fonte