Bash, execute o comando depois de chamar um novo shell


12

Estou tentando criar um script como este:

#!/bin/bash
sudo -s
something...

Quando o executo, recebo um novo shell, mas somethingé executado apenas quando saio do shell criado por sudo -s, e não dentro dele.

Qualquer ajuda?

Respostas:


7

O problema é que, sudo -ssem qualquer argumento, será aberto um shell interativo para o root.

Se você deseja apenas executar um único comando usando sudo -s, você pode:

sudo -s command

Por exemplo :

$ sudo -s whoami
root

Ou você pode usar aqui as strings:

$ sudo -s <<<'whoami'
root

Se você possui vários comandos, pode usar aqui doc:

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--

1
Não é bom usar sudo -sapenas no caso de o rootusuário ter a idéia (bastante ruim) de alterar seu shell. Deve ser realmente o sudo shque afirma explicitamente qual shell deve ser usado.
Michael Le Barbier Grünewald

7

Outra maneira seria passar um comando bash completo para sudo:

#!/bin/bash
sudo bash -c 'command1; command2; command3;'

No entanto, a melhor maneira seria a de lançar o roteiro com sudoseu lugar. Não é uma boa idéia ter sudodentro do script. Muito melhor executar o script inteiro com privilégios de root ( sudo script.sh). Se necessário, você pode usar sudopara eliminar privilégios para comandos específicos. Por exemplo:

#!/usr/bin/env bash
whoami
echo $HOME
sudo -u terdon whoami  ## drop privileges for specific command.

A execução do script acima retorna:

$ sudo ~/scripts/a.sh
root
/root
terdon

3

O shell Bourne tem uma -cbandeira que você pode usar para passar um script arbitrário para o shell, para que você possa escrever algo como

sudo sh -c 'something'

No entanto, isso é útil apenas para os comandos mais simples, porque é muito complicado citar o script corretamente e o inconveniente é ainda maior se você enviar o comando para um servidor remoto através do ssh porque o script de argumento será analisado duas vezes, uma vez ao lado enviando o script e uma vez do lado executando o script.

Se somethingé um script complexo ou precisa ser passado por uma linha ssh , é prática comum escrever uma função prepare_something_scriptcujo trabalho é escrever o script 'algo' no stdout . Na sua forma mais simples, esta função pode usar um documento aqui para gerar sua saída:

prepare_something_script()
{
  cat <<EOF
something
EOF
}

O script produzido por prepare_something_scriptpode então ser executado localmente com os privilégios concedidos pelo sudo da seguinte maneira:

prepare_something_script | sudo sh

No cenário em que o script deve ser executado remotamente com privilégios concedidos pelo sudo , é habitual codificar o script na base 64 para evitar o redirecionamento da entrada padrão do ssh , assim:

something64=$(prepare_something_script | base64)
ssh usesr@remote-host "echo ${something64} | base64 --decode | sudo sh"

Se você usar esse código em uma função, não esqueça de marcar a variável something64 como local . Algumas implementações da base64 oferecem um -dsinalizador para decodificar, que é menos bem suportado que a --decodevariante detalhada . Algumas implementações requerem adicionar um -w 0ao comando de codificação para evitar quebras de linha falsas.


0

Você precisa adicionar o comando antes do sudo -s, em vez de na próxima linha.

sudo -s something...
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.