it-swarm.com.de

Wie erhalte ich den Exit-Code des Spawn-Prozesses im Expect Shell-Skript?

Ich versuche, ein Skript auszuführen, das ein EXPECT-Skript ausführt, und einen erzeugten Prozess, der Exit-Code enthält. Ich kann den Exit-Code des erzeugten Prozesses für das Hauptskript jedoch nicht ermitteln. Ich bekomme immer Null als Erfolg.

das erwartete Skript lautet:

 [Linux Dev:anr ]$ cat testexit.sh
 #!/bin/bash
 export tmp_script_file="/home/anr/tmp_script_temp.sh"
 cp /home/anr/tmp_script $tmp_script_file
 chmod a+x $tmp_script_file
 cat $tmp_script_file
 expect << 'EOF'
 set timeout -1
 spawn  $env(tmp_script_file)
 expect {
 "INVALID "  { exit 4 }
 timeout     { exit 4 }
 }
 EOF
 echo "spawned process status" $?
 rm -f $tmp_script_file
 echo "done"

Spawned Script:

 [Linux Dev:anr ]$ cat tmp_script
 exit 3

Ausführung des Expect-Skripts:

 [Linux Dev:anr ]$ ./testexit.sh
 exit 3
 spawn /home/anr/tmp_script_temp.sh
 spawned process status 0
 done

Problem ist, dass ich nicht in der Lage bin, den gespawnten Exit-Rückkehrcode zu erhalten, um Skript zu erwarten. Ich möchte, dass der Exit-Code 3 von Spawned Script zu Main Script und Main Script mit Exit-Code 3 beendet wird.

Bitte helfen Sie mir, den erzeugten Exit-Code für das Hauptskript zu erhalten.

14
ANR

Mit Hilfe von glenn bekam ich eine Lösung .. und mein letztes Skript ist:

skript erwarten ist

 [Linux Dev:anr ]$ cat testexit.sh
 #!/bin/bash
 export tmp_script_file="/home/anr/tmp_script_temp.sh"
 cp /home/anr/tmp_script $tmp_script_file
 chmod a+x $tmp_script_file
 cat $tmp_script_file
 expect << 'EOF'
 set timeout -1
 spawn  $env(tmp_script_file)
 expect {
 "INVALID "  { exit 4 }
 timeout     { exit 4 }
 eof
 }

 foreach {pid spawnid os_error_flag value} [wait] break

 if {$os_error_flag == 0} {
     puts "exit status: $value"
     exit $value
 } else {
     puts "errno: $value"
     exit $value
 }
 EOF
 echo "spawned process status" $?
 rm -f $tmp_script_file
 echo "done"

Ausgegebenes Skript:

 [Linux Dev:anr ]$ cat tmp_script
 exit 3

Ausführung des Expect-Skripts:

 [Linux Dev:anr ]$ ./testexit.sh
 exit 3
 spawn /home/anr/tmp_script_temp.sh
 exit status: 3
 spawned process status 3
 done

Nochmals vielen Dank Glenn ..

9
ANR

Den Beendigungsstatus des erzeugten Prozesses erhalten Sie mit dem Befehl wait:

expect <<'END'
log_user 0
spawn sh -c {echo hello; exit 42}
expect eof
puts $expect_out(buffer)

lassign [wait] pid spawnid os_error_flag value

if {$os_error_flag == 0} {
    puts "exit status: $value"
} else {
    puts "errno: $value"
}
END
hello

exit status: 42

Aus der erwarten Manpage

wait [args]

verzögert sich, bis ein erzeugter Prozess (oder der aktuelle Prozess, wenn keiner benannt ist) beendet wird.

wait gibt normalerweise eine Liste von vier Ganzzahlen zurück. Die erste ganze Zahl ist die PID des Prozesses, auf den gewartet wurde. Die zweite ganze Zahl ist die entsprechende Spawn-ID. Die dritte ganze Zahl ist -1, wenn ein Betriebssystemfehler aufgetreten ist, oder 0. Wenn die dritte ganze Zahl 0 war, ist die vierte ganze Zahl der Status, der vom erzeugten Prozess zurückgegeben wird. Wenn die dritte ganze Zahl -1 ist, ist die vierte ganze Zahl der vom Betriebssystem festgelegte Wert von errno. Die globale Variable errorCode wird ebenfalls gesetzt.


Veränderung

expect {
"INVALID "  { exit 4 }
timeout     { exit 4 }
}

zu

expect {
    "INVALID "  { exit 4 }
    timeout     { exit 4 }
    eof
}

Fügen Sie dann die Befehle lassign und if hinzu.

26
glenn jackman

Nachdem ich einige Tage mit der Erweiterung der Variablen innerhalb des Expect Heredoc zu kämpfen hatte, stieß ich schließlich auf einen anderen Ansatz, von dem ich dachte, dass er für jemanden in Not hilfreich sein könnte. Meine Anforderung bestand darin, Befehl und Kennwort an eine Shell-Funktion zu übergeben, den Befehl im Remote-Host als Teil von expect heredoc auszuführen und den Rückkehr-Exit-Code abzurufen.

Beispiel:

function Shell_function {
   # Get the command and password as arguments
   # Run command using expect
   # Return the exit code
}

Shell_function <cmd> <password>
echo $?

Wie bei allen anderen war das Erweitern von Variablen in heredoc ein Problem, bei dem der Wert in eine Umgebungsvariable exportiert und env verwendet wurde, um die Variable in heredoc zu erhalten. Da Passwort eines der Argumente war, wollte ich es nicht als Teil einer Umgebungsvariablen speichern. Anstatt die Eröffnung von heredoc in einfache Anführungszeichen zu setzen, wurden die Variablen von heredoc ignoriert. Dies ermöglichte die direkte Verwendung der übergebenen Argumente.

Es folgt das letzte Skript:

#! /bin/bash
# This function runs a command like 'ssh' and provides the password
function run_with_password {
    cmd="$2"
    paswd="$1"
    expect << END
        set timeout 60
        spawn $cmd
        expect {
            "yes/no" { send "yes\r" }
            "*assword*" { send -- $paswd\r }
        }
        expect EOF
        catch wait result
        exit [lindex \$result 3]
END
}

my_password="AnswerIS42Really?"
cmd_to_run="ssh [email protected]"
cmd_to_run="$cmd_to_run ls .sawfish"
run_with_password $my_password "$cmd_to_run"
echo "Command run code: $?"

Im obigen Code lautet die maskierte Expect-Variable $result. Nach dem Ändern der Variablen zu \$result, begann das Skript wie Charme zu arbeiten.

Mein aufrichtiger Dank geht an Benutzer, die Antworten auf die folgenden Fragen gegeben haben, die als Sprungbrett dienten, um zu meiner Lösung zu gelangen.

Douglas Leeder: Hilf mit dem Erwartungsskript, starte cat auf einem entfernten Rechner und gib es in die Variable aus

glenn jackman: Wie kann ich den Exit-Code eines Spawn-Prozesses im Expect-Skript zurückgeben?

1
learningloop

Achten Sie darauf, das $ in der Expect-Eingabe zu entgehen, damit es von der Shell interpretiert wird.

0
Alex