How to get the exit code of spawned process in expect shell script?

ANR picture ANR · May 12, 2014 · Viewed 28k times · Source

I am trying to execute a script that executes an EXPECT script and a spawned process which has exit code in it. But I'm unable to get the exit code of the spawned process to main script. I'm always getting zero as success.

expect script is :

 [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

Execution of Expect script:

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

Problem is I am unable to get the spawned exit return code to expect script. I want the exit code 3 of spawned script to main script and main script should be exit with exit code 3.

Please help me to get the spawned exit code to main script.

Answer

glenn jackman picture glenn jackman · May 13, 2014

You get the exit status of the spawned process with the wait command:

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

From the expect man page

wait [args]

delays until a spawned process (or the current process if none is named) terminates.

wait normally returns a list of four integers. The first integer is the pid of the process that was waited upon. The second integer is the corresponding spawn id. The third integer is -1 if an operating system error occurred, or 0 otherwise. If the third integer was 0, the fourth integer is the status returned by the spawned process. If the third integer was -1, the fourth integer is the value of errno set by the operating system. The global variable errorCode is also set.


Change

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

to

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

Then add the lassign and if commands.