2016-12-28 5 views
0

Grundsätzlich versuche ich eine Subshell, die eine Schleife enthält, zu beenden. Hier ist der Code: `So beenden Sie eine Subshell

stop=0 
( # subshell start 
    while true   # Loop start 
    do 
     sleep 1   # Wait a second 
     echo 1 >> /tmp/output   # Add a line to a test file 

     if [ $stop = 1 ]; then exit; fi   # This should exit the subshell if $stop is 1 
    done # Loop done 

) |   # Do I need this pipe? 

    while true 
    do 
     zenity --title="Test" --ok-label="Stop" --cancel-label="Refresh" --text-info --filename=/tmp/output --font=couriernew  # This opens Zenity and shows the file. It returns 0 when I click stop. 

     if [ "$?" = 0 ]  # If Zenity returns 0, then 
     then 
     let stop=1  # This should close the subshell, and 
     break  # This should close this loop 
     fi 
    done  # This loop end 
    echo Done 

Das funktioniert nicht. Es sagt nie Fertig. Wenn ich Stop drücke, schließt es nur den Dialog, schreibt aber weiter in die Datei.

Edit: Ich muss in der Lage sein, eine Variable von der Subshell zur übergeordneten Shell übergeben. Ich muss jedoch weiterhin in die Datei schreiben und den Zenity-Dialog beibehalten. Wie würde ich das tun?

+0

Ich glaube nicht, dass ich verstehe. Gibt es eine spezielle Möglichkeit, Subshells zu verlassen? – Feldspar15523

Antwort

2

Wenn Sie eine Subshell spawnen, wird ein Subprozess der aktuellen Shell erstellt. Das heißt, wenn Sie eine Variable in einer Shell bearbeiten, wird sie nicht in der anderen Shell angezeigt, da sie verschiedene Prozesse sind. Ich schlage vor, Sie senden die Subshell in den Hintergrund und verwenden $!, um ihre PID zu erhalten, dann verwenden Sie diese PID, um die Subshell zu töten, wenn Sie fertig sind. Das würde so aussehen:

(        # subshell start 
    while true     # Loop start 
    do 
     sleep 1     # Wait a second 
     echo 1 >> /tmp/output # Add a line to a test file 
    done      # Loop done 

) &        # Send the subshell to the background 

SUBSHELL_PID=$!     # Get the PID of the backgrounded subshell 

while true 
do 
    zenity --title="Test" --ok-label="Stop" --cancel-label="Refresh" --text-info --filename=/tmp/output --font=couriernew  # This opens Zenity and shows the file. It returns 0 when I click stop. 

    if [ "$?" = 0 ]    # If Zenity returns 0, then 
    then 
    kill $SUBSHELL_PID   # This will kill the subshell 
    break      # This should close this loop 
    fi 
done       # This loop end 

echo Done 
+0

Die explizite Subshell mit den Klammern ist nutzlos (und wahrscheinlich nicht erwünscht). –

+0

Es funktioniert mit oder ohne die Klammern; Es geht nur darum, die Subshell zum Hintergrund oder zur Schleife zu schicken. Ich persönlich bevorzuge die Subshell, weil sie deutlich macht, was in den Hintergrund geschickt wird, im Gegensatz zu "while ......... done &", was für mich aussieht als wäre es "backed" (obwohl es funktioniert immer noch). Gibt es einen zwingenden Grund, die Parens wegzulassen? –

+0

Wenn ich eine Variable in der Subshell ändere, wird sie dann hauptsächlich geändert? Wenn nicht, wie sende ich dann Wert zwischen den beiden? – Feldspar15523