Frage Skript überspringt Benutzereingaben in verschachtelten Case-Anweisungen


Ich versuche, eine verschachtelte Case-Anweisung zu erstellen, in der Benutzereingaben erwartet werden (J / N). Das System wartet jedoch nie auf die Eingabe und geht immer zur dritten Option "Bitte antworte ja oder nein". Kann mir jemand sagen, was ich vermisse?

Hier ist die Case-Anweisung

#!/bin/bash
STATUS=status

find /etc/init.d/* -name '*' -print0 | while IFS= read -r -d '' FILE;
do
if [ "$FILE" != "." -o "$FILE" != ".." ]; then
OUTPUT=$($FILE $STATUS)
case "$OUTPUT" in
    *disabled* )
        echo "Do you wish to start $FILE ?"
        read  yn
        case $yn in
         [yY] | [yY][Ee][Ss] )
                $FILE start
                ;;
         [nN] | [n|N][O|o] )
                ;;
        * )
        echo "Please answer yes or no.";;
        esac
        ;;
       * )
        echo "App $FILE is running"
;;
esac
fi
done

Unter Ubuntu 14.04 LTS läuft

Beispielausgabe

App /etc/init.d/reboot is running
App /etc/init.d/resolvconf is running
App /etc/init.d/rsync is running
App /etc/init.d/rsyslog is running
App /etc/init.d/samba is running
App /etc/init.d/samba-ad-dc is running
Do you wish to start /etc/init.d/saned ?
Please answer yes or no.

1
2018-06-26 07:03


Ursprung


Ich versuche mit bestimmten ubuntu Init-Skripten. Aktualisieren des vollständigen Skripts - Ubuntuser
Es ist immer noch eine allgemeine Programmierfrage. Die Tatsache, dass Sie es für Ubuntu-Init-Skripte verwenden, macht es nicht zu einer Ubuntu-bezogenen Frage. Bitte posten Sie es an Paketüberfluss, da es sich um ein Thema außerhalb dieser Seite handelt. - kraxor


Antworten:


Du bist pingelig find Ausgabe an die While-Schleife. Der innere Lesebefehl liest eine Zeile aus finddie Ausgabe, nicht von stdin.

Sie können so umstrukturieren: senden Sie die find Ausgabe an die While-Schleife für einen anderen Dateideskriptor. Dies lässt Stdin frei für das innere Lesen.

while IFS= read -u3 -r -d '' FILE; do
    if [ "$FILE" != "." -o "$FILE" != ".." ]; then
        OUTPUT=$($FILE $STATUS)
        case "$OUTPUT" in
            *disabled* )
                read -p "Do you wish to start $FILE ?" yn
                case $yn in
                    [yY] | [yY][Ee][Ss] ) $FILE start ;;
                    [nN] | [nN][Oo] ) ;;
                    * ) echo "Please answer yes or no.";;
                esac
                ;;
            * ) echo "App $FILE is running" ;;
        esac
    fi
done  3< <(find /etc/init.d/* -name '*' -print0)

Dies verwendet ein Prozesssubstitution, statt einer Rohrleitung, von zu lesen find


3
2018-06-26 13:00





Der Kontext liefert diesmal die Antwort. Sie leiten die Ausgabe von find in die gesamte while-Schleife ein, und das schließt auch Ihre innere Lesart ein ... was bedeutet, dass Ihr "read yn" auch von der gleichen Ausgabe liest, die "find" liefert, im Gegensatz zu Ihrer Tastatur.

Ich mag auch nicht Ihre allgemeine Handhabung von Dateien. Eine einfache:

for file in /etc/init.d/*; do
   echo Processing $file
done

funktioniert heute in der Regel gut, auch für größere Mengen von Dateien.

Wenn Sie wirklich suchen müssen, könnten Sie Ihren Handler vielleicht in ein anderes Skript einfügen und ihn für jede Datei aufrufen mit:

find /etc/init.d -type f -perm +111 -exec myhandlerscript.sh {} \;

Dies wird alle Dateien mit ausführbaren Berechtigungen finden und rufen Sie myhandlerscript.sh für jeden mit dem Namen als Argument auf. Innerhalb des Skripts wird der Dateiname innerhalb der $ 1-Sondervariablen angezeigt.

Wenn es wirklich in der gleichen Datei sein müssen, wickeln Sie den Code in einer Funktion, exportieren Sie es mit „export -f myfunction“ und mit „exec bash -c‚myfunction ‚$ 0‘‘{} \;“ als ein Parameter zu finden.


2
2018-06-26 12:44





Ihre Verwendung des Befehls "Lesen" scheint nicht ganz richtig zu sein.

read -p "Do you wish to input data ?" yn

Die Option -p erwartet direkt daneben eine Zeichenfolge, die als Eingabeaufforderung verwendet wird. Daher dachte er, dass "yn" etwas zu zeigen sei, anstatt die Variable, in der die Antwort gespeichert werden soll.


1
2018-06-26 07:42



Damit würde es keine Notwendigkeit für die echo -n "Do you wish to input data ?" sonst würde es das zweimal zeigen. Eine Alternative wäre nur zu haben read yn ohne das -p Option, die das Problem verursacht. - Wilf
@Wilf, ich habe beides versucht, irgendwie funktioniert beides nicht. Es springt immer den Eingang. Aktualisiert mit dem vollständigen Skript, das ich erstellen möchte. - Ubuntuser
Überspringt es auch das Echo oder nur das Lesen? Kommt es jemals sogar in den "deaktivierten" Fallzweig? - Whyte
@ Whyte: Ja, tut es. Die Ausgabe, die ich bekomme, ist: App /etc/init.d/reboot is running App /etc/init.d/resolvconf is running App /etc/init.d/rsync is running App /etc/init.d/rsyslog is running App /etc/init.d/samba is running App /etc/init.d/samba-ad-dc is running Do you wish to start /etc/init.d/saned ? Please answer yes or no. - Ubuntuser