2017-12-07 5 views
1

Ich bin ein Anfänger lernen das Werkzeug "erwarten", ich probiere mehrere Übungen in diesem Stadium.Grundübung auf "erwarten" - Anfänger

Unten ist eine einfache Übung, die die Verwendung von zwei aufeinander folgenden "Spawn" -Befehlen zeigt - um das Passwort des Unix-Systems zu ändern und dann das alte wiederherzustellen. Grundsätzlich automatisiert, was man tut manuell:

$passwd 
Changing password for <username>. 
(current) UNIX password: 
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully 

Das Problem ist, dass „erwarten“ stoppt auf mysteriöse Weise am Eingang des zweiten Spawn für die prompten warten .. mich in einem endlosen Geheimnis zu halten.

Ich würde auch gerne alle schlechten Praktiken hören, die Sie bemerken, und alle guten Praktiken, die Sie vielleicht erzählen möchten.

Unten ist die Ausgabe von expect -d (ersetzt expect -f in der ersten Shebang-Linie), nach dem Vorschlag des Benutzers @pynexj. Das sieht wie das Debug-Dienstprogramm des aktuellen Codierers aus, von dem ich nicht wusste.

$./exercise1.sh 
expect version 5.45 
argv[0] = /usr/bin/expect argv[1] = -d argv[2] = ./exercise1.sh 
set argc 0 
set argv0 "./exercise1.sh" 
set argv "" 
executing commands from command file ./exercise1.sh 
spawn passwd 
parent: waiting for sync byte 
parent: telling child to go ahead 
parent: now unsynchronized from child 
spawn: returns {7848} 

expect: does "" (spawn_id exp4) match glob pattern "(current)"? no 
Changing password for <username>. 
(current) UNIX password: 
expect: does "Changing password for <username>.\r\n(current) UNIX password: " (spawn_id exp4) match glob pattern "(current)"? yes 
expect: set expect_out(0,string) "(current)" 
expect: set expect_out(spawn_id) "exp4" 
expect: set expect_out(buffer) "Changing password for <username>.\r\n(current)" 
send: sending "PW-OLD\r" to { exp4 } 

expect: does " UNIX password: " (spawn_id exp4) match glob pattern "Enter"? no 


expect: does " UNIX password: \r\n" (spawn_id exp4) match glob pattern "Enter"? no 
Enter new UNIX password: 
expect: does " UNIX password: \r\nEnter new UNIX password: " (spawn_id exp4) match glob pattern "Enter"? yes 
expect: set expect_out(0,string) "Enter" 
expect: set expect_out(spawn_id) "exp4" 
expect: set expect_out(buffer) " UNIX password: \r\nEnter" 
send: sending "PW-NEW\r" to { exp4 } 

expect: does " new UNIX password: " (spawn_id exp4) match glob pattern "Retype"? no 


expect: does " new UNIX password: \r\n" (spawn_id exp4) match glob pattern "Retype"? no 
Retype new UNIX password: 
expect: does " new UNIX password: \r\nRetype new UNIX password: " (spawn_id exp4) match glob pattern "Retype"? yes 
expect: set expect_out(0,string) "Retype" 
expect: set expect_out(spawn_id) "exp4" 
expect: set expect_out(buffer) " new UNIX password: \r\nRetype" 
send: sending "PW-NEW\r" to { exp4 } 
spawn passwd 
parent: waiting for sync byte 
parent: telling child to go ahead 
parent: now unsynchronized from child 
spawn: returns {7861} 

expect: does "" (spawn_id exp7) match glob pattern "(current)"? no 
Changing password for <username>. 
(current) UNIX password: 
expect: does "Changing password for <username>.\r\n(current) UNIX password: " (spawn_id exp7) match glob pattern "(current)"? yes 
expect: set expect_out(0,string) "(current)" 
expect: set expect_out(spawn_id) "exp7" 
expect: set expect_out(buffer) "Changing password for <username>.\r\n(current)" 
send: sending "PW-NEW" to { exp7 } 

expect: does " UNIX password: " (spawn_id exp7) match glob pattern "Enter"? no 
^Csighandler: handling signal(2) 
async event handler: Tcl_Eval(exit 130) 
+0

Sie müssen warten, bis der erste 'Spawn' beendet wird, oder es werden zwei' passwd' Prozesse für einen einzelnen Benutzer ausgeführt. – pynexj

+0

@pynexj Ich habe eine ganze Sekunde gewartet, oder? passwd geht schneller als das nach dem Eintippen des Passworts .. Jedenfalls habe ich es mit sogar 10 Sekunden versucht, es hat nicht funktioniert. Ich habe auch "exit" -Befehl explizit vor dem zweiten Spawn verwendet, immer noch hat es nicht funktioniert. Ich habe auch versucht "warten", "schließen". –

+0

ok wenn du sicher bist, obwohl es genau die * schlechten Praktiken sind, nach denen du fragst. – pynexj

Antwort

1

Ich würde ein RegexMuster verwenden, die alle das Passwort gilt folgende Meldung aus:

expect -re "password: $" 

Veränderung sowohl sleep 1 und interact zu expect eof

# create new password 
spawn passwd 
expect -re "password: $"; send -- "PW-OLD\r" 
expect -re "password: $"; send -- "PW-NEW\r" 
expect -re "password: $"; send -- "PW-NEW\r" 
expect eof 

# restore old password 
spawn passwd 
expect -re "password: $"; send -- "PW-NEW\r" 
expect -re "password: $"; send -- "PW-OLD\r" 
expect -re "password: $"; send -- "PW-OLD\r" 
expect eof 

Mit glob Muster, wenn Sie geben keine Wildcards an, Sie tun im Grunde String equ Überprüfung der Sie könnten tun:

expect "*(current) UNIX password: " 
expect "*Enter new UNIX password: " 
expect "*Retype new UNIX password: " 

Beachten Sie die abschließenden Leerzeichen, die in den Passwd-Eingabeaufforderungen vorhanden sind.

+0

'expect * foo' ist das gleiche wie' expec foo'. genau wie bei RE 'expect -re. * foo' ist das selbe wie' expect -re foo'. – pynexj