Como executar comandos interativos, como outro usuário

4

Estou tentando escrever um script que

  • o contexto muda para outro usuário (raiz, nesse caso)
  • executa um conjunto de comandos para i. criar um usuário (interativamente solicitando invoker para nome de usuário) e, em seguida, ii. define a senha nesse usuário
  • obtém um valor de retorno
  • então continua fazendo coisas, com esse valor de retorno

Eu até agora tentei um < < Entrada EOF ( fig.1 ), uma função ( fig.2 ), e puxar / executar um script separado ( fig.3 ). No entanto, não obtive os resultados de que preciso. Alguma ajuda aqui? Espero ter explicado isso claramente.

sudo su - << 'EOF'
# do stuff...
EOF

fig.1

function myfunc()
{
    local  myresult='some value'
    echo "$myresult"
}

fig.2

sudo su - -c bash <(curl -fksSL https://<my-script-location>.sh)

fig.3

    
por Nutritioustim 15.06.2014 / 02:41

3 respostas

5
sudo su - << 'EOF'
# do stuff...
EOF

Isso funciona, mas com uma limitação: o script é passado para o shell em sua entrada padrão, portanto, você não pode usar a entrada padrão para outra coisa, como ler o nome do usuário para criar.

A maneira simples de manter a entrada padrão é passar o comando shell como um argumento.

Observe que sudo su é redundante - sudo executa o comando especificado como root e esse é o único propósito de su também. Use sudo -i em vez de sudo su - se você deseja executar um shell de login como root - o que provavelmente é desnecessário aqui - ou sudo sh para executar um shell como root.

sudo sh -c '
  # do stuff...
'

Isso dificulta o uso de uma aspa simples no snippet do shell. Você pode usar '\'' para colocar uma aspa simples dentro do literal entre aspas simples. Se você quiser manter a estrutura do documento aqui, existem várias maneiras. O mais simples é passar o documento aqui em um descritor diferente . No entanto, isso requer que a opção closefrom_override seja ativada na configuração do sudo, o que não é o caso por padrão; por padrão, sudo fecha todos os descritores de arquivos, exceto stdin, stdout e stderr.

sudo -C 3 sh -c '. /dev/fd/3' 3<<'EOF'
# do stuff...
EOF

Se você quiser que seu código seja portável para máquinas onde esta opção não está ativada, você pode ler o script de um heredoc e passá-lo para o shell como um argumento.

script=$(cat <<'EOF'
# do stuff...
EOF
)
sudo sh -c "$script"

Como alternativa, se você quiser que o script sudo possa ler a partir do terminal, pode passar o corpo do script na entrada padrão. Uma limitação dessa abordagem é que ela não permite que a entrada do script geral seja redirecionada.

sudo sh <<'EOF'
exec </dev/tty
# do stuff...
EOF
    
por 16.06.2014 / 04:04
1

Desde que o usuário que invoca sudo possa alocar tty :

Defaults someuser:requiretty

ans recebeu permissões para executar os comandos necessários como root:

Cmnd_Alias STUFF = /usr/bin/passwd, /usr/sbin/useradd
someuser ALL = STUFF

um script contendo sudo invocações será interativo. Você poderia passar o nome de usuário como um argumento posicional:

sudo useradd $1
sudo passwd $1

e verifique o status de retorno como de costume com $? .

    
por 15.06.2014 / 09:57
-2
su -c '. /dev/fd/4' 4<<\SCRIPT
    ...automated stuff here...
    ....then for interactive...
    exec </dev/tty
SCRIPT

Deve fazer isso. Adapte isso para atender às suas necessidades - mas ele alternará os contextos e o status de retorno do shell estará em $? quando você terminar com isso.

    
por 15.06.2014 / 20:37