我的应用程序/进程正在 HostA 中运行。它需要使用用户名和密码(不允许公钥身份验证)连接到 HostB,以便发送另一个脚本和命令文件。然后,我需要连接到 HostB 并远程执行该脚本,该脚本使用公钥身份验证连接到 HostC 以实际生成导出文件。
在 HostA 中我有这个脚本 (
script_in_HostA.sh
)
#!/bin/bash
user=myuser
password=mypassword
HostB=myHostB_name
WKDIR=${HOME}/utils
# [1] Send "generate_export.sh" to HostB using SCP, using ${user} and ${password} variables
expect -c "
set timeout 600
spawn scp -q -p -P 5023 ${WKDIR}/generate_export.sh ${user}@${HostB}:./generate_export.sh
match_max 100000
expect "*?assword:*"
send \"${password}\r\"
send \"\r\"
expect eof"
# [2] Send commands file to HostB using SCP, using ${user} and ${password} variables
expect -c "
set timeout 600
spawn scp -q -p -P 5023 ${WKDIR}/commands.cmd ${user}@${HostB}:./commands.cmd
match_max 100000
expect "*?assword:*"
send \"${password}\r\"
send \"\r\"
expect eof"
# [3] Remotely execute generate_export.sh in HostB
output_file=results.txt
expect -c "
set timeout 3600
spawn ssh -q -p 5023 ${user}@${HostB} sh ./generate_export.sh ./commands.cmd ./${output_file}
match_max 100000
expect "*?assword:*"
send \"${password}\r\"
send \"\r\"
expect END
exit"
echo "I have finished"
generate_export.sh
看起来像这样
#!/bin/bash
# Args
if [[ $# -eq 2 ]]; then
command_file=$1
output_file=$2
else
# Incorrect number of args
exit 10
fi
SCRIPTNAME=$(basename $0)
USER=username_in_HostC
host=HostC
export_command=/usr/local/bin/appexport
# Connection to HostC
echo -e "$(date '+%Y%m%d %H%M%S') ..${SCRIPTNAME}.. START ${command_file}"
# Public key authentication, no password or "expect" needed
ssh ${USER}@${host} ${export_command} -file ${HOME}/${command_file} > ${HOME}/${output_file}
if [[ $? -eq 0 ]]; then
echo -e "$(date '+%Y%m%d %H%M%S') ..${SCRIPTNAME}.. END ${command_file}"
gzip -f ${HOME}/${output_file}
#exit 0
else
# Error code
exit 20
fi
当我在HostA中执行
script_in_HostA.sh
时,它会发送generate_export.sh
和commands.cmd
到HostB,然后它远程执行
generate_export.sh -file commands.cmd > results.txt
期望的结果是
results.txt.gz
,这就是我所看到的。我可以使用另一个终端连接到 HostA、HostB 和 HostC,我看到results.txt.gz
已生成。
但是,
script_in_HostA.sh
陷入了步骤[3]。看起来 script_in_HostA.sh
没有注意到生成的 SSH 已经结束,它可以继续写入“I have finished
”。我可以在 HostA 中执行 ps
并看到 expect
和 ssh
在生成 .txt.gz 文件后仍在运行。
我已经尝试过了
expect eof
而不是
expect END
exit
但是不起作用。
我使用“
expect END
”,因为这就是 generate_export.sh
在生成导出时写入标准输出的内容。
如果
generate_export.sh
在HostB中结束,为什么HostA没有意识到它已经完成了?
提前致谢。
只需使用
expect
启动经过身份验证的控制主机,其他进程可以使用它而无需再次显式身份验证。一旦完成,您可以手动关闭主连接。 (此外,一旦 scp
命令可以将两个文件复制到远程主机,因为您没有更改远程端的文件名。)
类似的东西
#!/bin/bash
user=myuser
password=mypassword
HostB=myHostB_name
WKDIR=${HOME}/utils
socket=~/.ssh/%C
expect -c "
spawn ssh -N -p 5023 $user@HostB -o ControlMaster -o ControlPath=\"$socket\"
match_max 100000
expect \"*?assword:*\"
send \"${password}\r\"
send \"\r\"
expect eof"
scp -o "ControlPath=$socket" -q -p -P 5023 \
"${WKDIR}/generate_export.sh" \
"${WKDIR}/commands.cmd" \
${user}@${HostB}:
ssh -o "ControlPath=$socket" -q -p 5023 ${user}@${HostB} "sh ./generate_export.sh ./commands.cmd ./${output_file}"
ssh -o "ControlPath=$socket" -O exit
echo "I have finished"