Como forçar o script bash a aguardar a resposta do usuário?

3

Já existem perguntas semelhantes, mas estou postando isso porque nenhuma das respostas funcionou. Estou escrevendo um script para automatizar a instalação de pacotes do pacman e do AUR no meu sistema Arch. A idéia é ler um arquivo (myfile) com os nomes dos pacotes primeiro linha por linha e depois palavra por palavra e executar a instalação para cada palavra. Isso funciona bem para o pacman, mas não para o AUR Helper (aurman). A parte para aurman se parece com isso:

while read line; do
if [[ "$line" =~ \$[[:space:]]aurman[[:space:]]-S[[:space:]][[:alnum:]]* ]]
then
    aurline=$(echo "$line" | awk '{ $1=""; $2=""; $3=""; print}' | sed 's/^ *//')
    for aurpkg in $aurline
    do
       sudo -u "${my_user}" bash << EOF
aurman -S --noconfirm --needed --noedit "$aurpkg"
wait
EOF
    done
fi
done < "$myfile"

Com as opções - noconfirm --needed --noedit o aurman não me pede Sim / Não, mas para alguns pacotes ele me pede um número. Portanto, o problema é, neste caso, o script não espera, o pacote não é instalado e o aurman produz um erro "EOFError: EOF ao ler uma linha". Eu tentei pausar o script assim:

aurman ...
wait

ou assim:

aurman ... &
wait

mas nenhum desses trabalhos.

Então, como posso pausar meu script quando o aurman me pede um número? Qual é a abordagem geral em casos como este? Como eu poderia dar uma resposta para um pacote específico desde o início quando eu executava o script (por exemplo, 1 para o pacote x)?

    
por coverflower 14.04.2018 / 19:21

2 respostas

4

O problema básico é que stdin (que aurman está tentando ler) não está vindo do usuário, ele está sendo redirecionado primeiro de $myfile e depois de um documento aqui contendo os comandos do shell para sudo para executar. Uma opção é passar esses arquivos por um descritor de arquivo diferente, como # 3 (que normalmente não é usado). Eu acho que você também pode simplificá-lo, eliminando a execução do shell em sudo - já que você está executando aurman em primeiro plano, não há necessidade de wait para isso. não precisa do shell (e, portanto, não precisa do aqui-doc).

while read line <&3; do
    if [[ "$line" =~ \$[[:space:]]aurman[[:space:]]-S[[:space:]][[:alnum:]]* ]]
    then
        aurline=$(echo "$line" | awk '{ $1=""; $2=""; $3=""; print}' | sed 's/^ *//')
        for aurpkg in $aurline
        do
            sudo -u "${my_user}" aurman -S --noconfirm --needed --noedit "$aurpkg"
        done
    fi
done 3< "$myfile"

Se isso não funcionar e você realmente precisar executar o shell em sudo , também poderá redirecioná-lo via FD # 3 e ter bash como script, assim:

            sudo -u "${my_user}" bash /dev/fd/3 3<< EOF
aurman -S --noconfirm --needed --noedit "$aurpkg"
wait
EOF
    
por 15.04.2018 / 02:50
0

Para o bash, existe o comando dormir , que coloca o script para dormir até que uma quantidade de tempo em segundos tenha passado. No entanto, se o que você quer é pegar uma senha, eu recomendo que você, um dos dois métodos abaixo (verifique o script que eu coloquei na parte inferior, para ilustrar como o sono funciona, e também as duas alternativas mencionadas abaixo). / p>

  • Você pode enviar a senha como um parâmetro ao iniciar o script.
  • Você pode usar o comando ler , isso registrará as entradas até que o cliente pressione enter.

[root@client ~]# cat readPass.sh
#!/bin/bash

# Author: @djcerdas
password="$1"

# Sample sleep command
echo "Hi, I am the PID $$, I am going to sleep 3 seconds"
date&&sleep 3&&date
echo "---------------------------------------"
# Sample method 1: passing password a parameter
echo  "Method 1: The password is $password"
password=""
echo "---------------------------------------"
# Sample method 2: using read
echo "Method 2: Please provide your password:"
read password
echo The password is $password

[root@client ~]# ./readPass.sh myPasswordX
Hi, I am the PID 2257, I am going to sleep 3 seconds
Tue Apr  3 01:17:55 CST 2018
Tue Apr  3 01:17:58 CST 2018
---------------------------------------
Method 1: The password is myPasswordX
---------------------------------------
Method 2: Please provide your password:
myNewPassword
The password is myNewPassword
[root@client ~]#

    
por 15.04.2018 / 00:45