我正在尝试执行一个执行EXPECT脚本的脚本和一个包含退出代码的衍生进程。但是我无法将生成的进程的退出代码获取到主脚本。我的成功总是为零。
期望脚本是:
[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"
产生的脚本:
[Linux Dev:anr ]$ cat tmp_script
exit 3
执行Expect脚本:
[Linux Dev:anr ]$ ./testexit.sh
exit 3
spawn /home/anr/tmp_script_temp.sh
spawned process status 0
done
问题是我无法获得生成的退出返回代码以期望脚本。我希望生成的脚本的退出代码3到主脚本,主脚本应该退出,退出代码为3。
请帮我将衍生的退出代码发送到主脚本。
答案 0 :(得分:27)
使用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
等待 [args]
延迟到产生的进程(或当前进程,如果没有命名)终止。
等待通常会返回四个整数的列表。第一个整数是等待进程的pid。第二个整数是相应的spawn id。如果发生操作系统错误,则第三个整数为-1,否则为0。如果第三个整数为0,则第四个整数是生成进程返回的状态。如果第三个整数是-1,则第四个整数是操作系统设置的errno的值。全局变量errorCode也已设置。
更改
expect {
"INVALID " { exit 4 }
timeout { exit 4 }
}
到
expect {
"INVALID " { exit 4 }
timeout { exit 4 }
eof
}
然后添加lassign
和if
命令。
答案 1 :(得分:9)
在glenn的帮助下,我得到了解决方案......我的最终脚本是::
期待脚本是
[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"
产生的脚本:
[Linux Dev:anr ]$ cat tmp_script
exit 3
执行Expect脚本:
[Linux Dev:anr ]$ ./testexit.sh
exit 3
spawn /home/anr/tmp_script_temp.sh
exit status: 3
spawned process status 3
done
再次感谢格伦。
答案 2 :(得分:1)
经过几天的努力,在期望的heredoc中扩展变量,最后我遇到了另一种方法,我认为这可能对有需要的人有所帮助。我的要求是将命令和密码传递给Shell函数,作为Expect Heredoc的一部分在远程主机中执行命令,并获取返回退出代码。
示例:
function shell_function {
# Get the command and password as arguments
# Run command using expect
# Return the exit code
}
shell_function <cmd> <password>
echo $?
就像其他所有人一样,在heredoc中扩展变量是一个问题,它需要将值导出到环境变量中,并使用env
来将变量获取到heredoc中。因为,密码是我不想将其存储为环境变量的一部分的参数之一。因此,不是将单引号括在heredoc中,而是对heredoc的变量进行了转义。这样可以直接使用传递的参数。
以下是最终脚本:
#! /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 userid@hostname"
cmd_to_run="$cmd_to_run ls .sawfish"
run_with_password $my_password "$cmd_to_run"
echo "Command run code: $?"
在上面的代码中,转义的期望变量为$result
。将变量更改为\$result
后,脚本开始像魅力一样工作。
衷心感谢用户提供了以下问题的答案,这些问题为实现我的解决方案奠定了基础。
Douglas Leeder: help with expect script, run cat on remote comp and get output of it to the variable
glenn jackman: How to return spawned process exit code in Expect script?