Como executar comandos interativos como outro usuário

Como executar comandos interativos como outro usuário

Estou tentando escrever um script bash que

  • contexto muda para outro usuário (root, neste caso)
  • executa um conjunto de comandos paraeu.crie um usuário (solicitando interativamente ao invocador o nome de usuário) e entãoii.define a senha desse usuário
  • obtém um valor de retorno
  • então continua fazendo coisas, com esse valor de retorno

Até agora tentei uma entrada << EOF (Figura 1), uma função (Figura 2) e puxar/executar um script separado (fig.3). No entanto, não obtive os resultados que preciso.

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

Figura 1

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

Figura 2

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

fig.3

Responder1

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

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

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

Observe que isso sudo sué redundante - sudoexecuta o comando especificado como root e esse sutambém é o único propósito. Use sudo -iem vez de sudo su -se desejar executar um shell de login como root - o que provavelmente é desnecessário aqui - ou sudo shapenas executar um shell como root.

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

Isso torna estranho usar uma aspa simples no snippet de 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 aquiem um descritor diferente. No entanto, isso requer que a closefrom_overrideopção esteja ativada na configuração do sudo, o que não é o caso por padrão; por padrão, sudofecha todos os descritores de arquivo diferentes de stdin, stdout e stderr.

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

Se você deseja 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 argumento.

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

Alternativamente, se você quiser que o script sudoed possa ser lido no terminal, você pode passar o corpo do script na entrada padrão. Uma limitação desta abordagem é que ela não permite que a entrada do script geral seja redirecionada.

sudo sh <<'EOF'
exec </dev/tty
# do stuff...
EOF

Responder2

Desde que o usuário que está invocando sudopossa alocar um 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 sudoinvocaçõ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 normalmente com $?.

Responder3

su -c '. /dev/fd/4' 4<<\SCRIPT
    ...automated stuff here...
    ....then for interactive...
    exec </dev/tty
SCRIPT

Deveria fazer isso. Personalize isso para atender às suas necessidades - mas isso mudará de contexto e o status de retorno do shell estará em $?quando você terminar.

informação relacionada