Wie zwingt man ein Bash-Skript, auf eine Antwort des Benutzers zu warten?

Wie zwingt man ein Bash-Skript, auf eine Antwort des Benutzers zu warten?

Es gibt bereits ähnliche Fragen, aber ich poste diese, weil keine der Antworten funktioniert hat. Ich schreibe ein Bash-Skript, um die Installation von Pacman- und AUR-Paketen auf meinem Arch-System zu automatisieren. Die Idee ist, eine Datei (myfile) mit den Paketnamen zuerst Zeile für Zeile und dann Wort für Wort zu lesen und die Installation für jedes Wort durchzuführen. Das funktioniert gut für Pacman, aber nicht für den AUR Helper (aurman). Der Teil für aurman sieht so aus:

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"

Mit den Optionen--noconfirm --needed --noeditaurman fordert mich nicht zur Eingabe von Ja/Nein auf, aber bei einigen Paketen fordert es mich zur Eingabe einer Nummer auf. Das Problem ist also, dass das Skript in diesem Fall nicht wartet, das Paket nicht installiert wird und aurman einen Fehler „EOFError: EOF beim Lesen einer Zeile“ erzeugt. Ich habe versucht, das Skript folgendermaßen anzuhalten:

aurman ...
wait

oder so:

aurman ... &
wait

aber nichts davon funktioniert.

Wie kann ich also mein Skript anhalten, wenn aurman mich zur Eingabe einer Nummer auffordert? Was ist in solchen Fällen die allgemeine Vorgehensweise? Wie könnte ich gleich zu Beginn, wenn ich das Skript ausführe, eine Antwort für ein bestimmtes Paket angeben (z. B. 1 für Paket x)?

Antwort1

Das grundlegende Problem ist, dass stdin ( aurmanvon dem es zu lesen versucht) nicht vom Benutzer kommt, sondern zuerst von umgeleitet wird $myfileund dann von einem Here-Dokument, das die Shell-Befehle enthält, die sudoausgeführt werden sollen. Eine Möglichkeit besteht darin, diese Dateien über einen anderen Dateideskriptor zu übergeben, wie beispielsweise #3 (der normalerweise nicht verwendet wird). IchdenkenSie können es auch vereinfachen, indem Sie die Shell eliminieren, unter der es ausgeführt wird . Da es im Vordergrund sudoläuft , ist dies nicht erforderlich und Sie brauchen die Shell nicht (und daher auch das vorliegende Dokument nicht).aurmanwait

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"

Wenn das nicht funktioniert und Sie die Shell tatsächlich unter ausführen müssen sudo, können Sie sie auch über FD #3 umleiten und bashdas als Skript wie folgt lesen:

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

Antwort2

Für Bash gibt es dieschlafenBefehl, der das Skript in den Ruhezustand versetzt, bis eine bestimmte Zeitspanne in Sekunden verstrichen ist. Wenn Sie jedoch ein Passwort abfangen möchten, empfehle ich Ihnen eher eine der beiden folgenden Methoden (sehen Sie sich das Skript an, das ich unten eingefügt habe, um zu veranschaulichen, wie der Ruhezustand funktioniert, und auch die beiden unten genannten Alternativen).

  • Sie können das Passwort beim Starten des Skripts als Parameter übergeben.
  • Sie könnenlesenBefehl, dadurch werden die Eingaben aufgezeichnet, bis der Kunde die Eingabetaste drückt.

[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 ~]#

verwandte Informationen