Execute uma linha de comandos com um sudo

Execute uma linha de comandos com um sudo

Por exemplo, se eu quiser criar um arquivo e inserir texto em uma linha, posso redirecionar a saída para um arquivo usando o >operador:

echo "something" > /path/foobar

mas se eu não tiver acesso à pasta /path/e precisar de privilégios de sudo, como posso obter esse mesmo comando que um usuário normal com direitos de sudo?

tentei

sudo echo "something" > /path/foobar

mas isso não funciona, porque o sudo só conta para a parte certa, editmas não para a parte
direita>

Claro, eu poderia me tornar root antes sudo suou usar tee:

echo "something" | sudo tee /path/foobar

Mas gostaria de encontrar uma solução onde eu pudesse trabalhar com a última linha como substituição via

sudo !!

Não existe uma maneira de "reciclar" a última linha e apenas adicionar sudona frente?

Responder1

Você não pode simplesmente ficar sudona frente de um comando shell, você precisa invocar um shell para avaliar esse comando novamente (fazendo coisas como expandir variáveis, abrir arquivos para operadores de redirecionamento, etc.). Então isso é

sudo bash -c !!

exceto que isso não funciona muito bem, porque !!interpola o texto do comando anterior, com caracteres especiais e tudo. Você precisa recuperar o texto do comando como uma string e passá-lo como argumento para sh. Felizmente, o bashfcconstruídas empermite que você faça isso¹.

sudo bash -c "$(fc -ln -1)"

Ou ainda, para ter certeza de invocar a mesma versão do bash que está em execução no momento:

sudo "$BASH" -c "$(fc -ln -1)"

Observe que, como o comando é executado em um processo de shell separado, ele herda variáveis ​​de ambiente (apenas aquelas que sudopreservam), mas não variáveis ​​internas do shell. As opções de shell (por exemplo kshglob, ) e outras configurações também começarão a partir do padrão.

O mesmo comando² funciona em zsh e ksh, embora ATT ksh93 exija que o número firste lastseja passado para fc³ (que também funciona em bash, zsh e pdksh/mksh):

sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"

Usar $0para designar o executável do shell em execução funciona apenas se o shell foi invocado através do $PATH e o $PATH não foi alterado, ou através de um caminho absoluto.

Aqui está outro método em zsh que é um pouco mais claro, mas mais longo:

sudo zsh -c $history[$[HISTCMD-1]]

Uma última palavra de advertência: sudodestina-se a comandos potencialmente perigosos. Não torne muito fácil usá-lo!

¹ Há alguns espaços em branco extras no início e a substituição do comando remove novas linhas no final, mas a sintaxe do shell não se importa com isso.
² Não acho que zsh ou ksh tenham algo parecido com o bash $BASH; $0só funciona quando é um caminho absoluto ou quando não contém nenhuma barra e o caminho de pesquisa do comando não foi alterado.
³ é um apelido para ATT ksh, mas é igualmente bom. fchist

Responder2

Se você quiser refazer o mesmo comando comsudo!!depois de fazer um comando como este:

echo "something">/path/file

Você usa a sintaxe de substituição global para recuperar o comando:

!!:gs/>/|sudo tee -a /

Use um espaço após o-aparâmetro.

Isto é o equivalente asudo!!mas ajuda a ignorar as restrições do sudo para < e >. Porque o sudo não permite que você use [<, >].


Para ignorar as restrições do sudo em geral para redirecionamentos, você pode usá-lo assim:

echo "something" | sudo tee myfile

O comando tee permitirá que você leia a entrada padrão e grave na saída e nos arquivos padrão

Se você quiser repetir o comando e acrescentar um texto ao arquivo, o comando tee tem o-aopção para anexar. Então você pode lembrar o comando com

sudo !!

e o texto será anexado ao arquivo

exemplo:

echo "something" | sudo tee -a /path/file
sudo !!

Responder3

Parece ser tão simples quanto sudo sh -c "!!":

$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo

informação relacionada