Bash, execute o comando depois de invocar um novo shell

9

Estou tentando criar um script como este:

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

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

Alguma ajuda?

    
por Matteo 23.07.2015 / 11:02

4 respostas

7

O problema é que sudo -s sem nenhum argumento abrirá um shell interativo para o root.

Se você quiser apenas executar um único comando usando sudo -s , você pode fazer o seguinte:

sudo -s command

Por exemplo:

$ sudo -s whoami
root

Ou você pode usar aqui strings:

$ sudo -s <<<'whoami'
root

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

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--
    
por 23.07.2015 / 11:20
5

Outra maneira seria passar um comando bash completo para sudo :

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

No entanto, a melhor maneira seria lançar o script com sudo . Não é uma boa idéia ter sudo dentro do script. É muito melhor executar o script inteiro com privilégios de root ( sudo script.sh ). Se necessário, você pode usar sudo para descartar 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
    
por 23.07.2015 / 12:04
3

O shell Bourne tem um sinal -c 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 a inconveniência é ainda maior se você enviar o comando para um servidor remoto por ssh porque o argumento o script será analisado duas vezes, uma vez no lado enviando o script e uma vez no lado executando o script.

Se something for um script complexo ou precisar ser passado por uma linha ssh , é uma prática comum escrever uma função prepare_something_script cujo trabalho é escrever o script 'algo' em stdout . Em sua forma mais simples, essa função pode usar um documento here para gerar sua saída:

prepare_something_script()
{
  cat <<EOF
something
EOF
}

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

prepare_something_script | sudo sh

No cenário em que o script deve ser executado remotamente com privilégios concedidos pelo sudo , é costume codificar o script na base 64 para evitar redirecionar a entrada padrão de 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 se esqueça de marcar a variável algo64 como local . Algumas implementações de base64 oferecem um sinalizador -d para decodificar, o que é menos bem suportado do que a variante --decode detalhada. Algumas implementações exigem a adição de um -w 0 ao comando de codificação para evitar quebras de linha falsas.

    
por 23.07.2015 / 14:01
0

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

sudo -s something...
    
por 23.07.2015 / 11:12