
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 - sudo
executa o comando especificado como root e esse su
também é o único propósito. Use sudo -i
em vez de sudo su -
se desejar executar um shell de login como root - o que provavelmente é desnecessário aqui - ou sudo sh
apenas 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_override
opção esteja ativada na configuração do sudo, o que não é o caso por padrão; por padrão, sudo
fecha 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 sudo
possa 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 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 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.