¿Cómo obligar a bash script a esperar la respuesta del usuario?


3

Ya hay preguntas similares, pero estoy publicando esto porque ninguna de las respuestas funcionó. Estoy escribiendo un script de bash para automatizar la instalación de los paquetes pacman y AUR en mi sistema Arch. La idea es leer un archivo (myfile) con los nombres de los paquetes primera línea por línea y luego palabra por palabra y realizar la instalación de cada palabra. Esto funciona bien para pacman pero no para AUR Helper (aurman). La parte para aurman se ve así:

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"

Con las opciones --noconfirm - necesario --noedit aurman no me solicita Sí / No, pero para algunos paquetes me pide un número. Entonces, el problema es que en este caso el script no espera, el paquete no se instala y aurman produce un error "EOFError: EOF al leer una línea". He intentado pausar el script así:

aurman ...
wait

o así:

aurman ... &
wait

Pero ninguna de estas obras.

Entonces, ¿cómo puedo pausar mi script cuando aurman me pide un número? ¿Cuál es el enfoque general en casos como este? ¿Cómo puedo dar una respuesta para un paquete específico desde el principio cuando ejecuto el script (por ejemplo, 1 para el paquete x)?


No lo sé aurman pero tal vez expect Es la herramienta que necesitas. Ver man 1 expect y esta respuesta .
Kamil Maciorowski

Respuestas:


4

El problema básico es que stdin (que aurman está intentando leer desde) no proviene del usuario, se está redirigiendo primero desde $myfile, y luego desde un documento aquí que contiene los comandos de shell para sudo correr. Una opción es pasar esos archivos a través de un descriptor de archivo diferente, como el # 3 (que normalmente no se usa). yo pensar También puede simplificarlo eliminando el shell ejecutado bajo sudo - ya que estas corriendo aurman en primer plano, no hay necesidad de wait para ello, no necesita el shell (y, por lo tanto, no necesita el documento aquí).

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"

Si eso no funciona y realmente necesitas ejecutar el shell bajo sudo, también puede redirigirlo a través de FD # 3, y tener bash Lee eso como un guión, así:

            sudo -u "${my_user}" bash /dev/fd/3 3<< EOF
aurman -S --noconfirm --needed --noedit "$aurpkg"
wait
EOF

0

Para bash, hay la dormir comando, que pone el script en suspensión hasta que haya transcurrido un tiempo en segundos. Sin embargo, si lo que desea es capturar una contraseña, le recomendaría que prefiera uno de los dos métodos siguientes (verifique la secuencia de comandos que coloco en la parte inferior, para ilustrar cómo funciona el sueño, y también las 2 alternativas mencionadas a continuación).

  • Puede enviar la contraseña como un parámetro al iniciar el script.
  • Puedes usar leer comando, esto registrará las entradas hasta que el cliente presione 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 ~]#

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.