使用Expect远程执行shell脚本报错:文件不存在的问题求助
问题原因与解决方法
问题原因
- 执行
ssh_cmd.sh xxx.xxx.xxx.xxx root 12345 pwd.sh时,expect脚本是把pwd.sh作为远程服务器要执行的命令直接传递的,但远程服务器上并没有这个文件,所以触发bash: pwd.sh: No such file or directory错误。 - 而终端直接执行的
ssh root@xxx.xxx.xxx.xxx 'bash -s' < pwd.sh,是将本地pwd.sh的内容通过标准输入(stdin)传给远程的bash -s进程,远程bash直接读取stdin里的脚本内容执行,完全不需要远程服务器存在pwd.sh文件。
解决方法
方法1:修改expect脚本,传递本地脚本内容给远程bash
调整ssh_cmd.sh,模拟你终端成功的执行逻辑,把本地脚本内容通过标准输入传给远程的bash -s。示例代码:
set host [lindex $argv 0] set user [lindex $argv 1] set password [lindex $argv 2] set script_path [lindex $argv 3] # 读取本地脚本内容 set fh [open $script_path r] set script_content [read $fh] close $fh # 启动ssh连接 spawn ssh $user@$host expect "password:" send "$password\r" expect -re {\$ } # 触发远程bash读取标准输入执行 send "bash -s\r" expect -re {\$ } # 发送本地脚本内容 send "$script_content\r" send "exit\r" expect eof
如果脚本包含特殊字符(比如引号、反斜杠),可以用quoted命令处理内容,避免转义问题。
方法2:先上传脚本到远程,再执行
用expect先通过scp把本地pwd.sh传到远程临时目录(比如/tmp),再ssh执行该脚本,执行后可选择删除。示例:
set host [lindex $argv 0] set user [lindex $argv 1] set password [lindex $argv 2] set script_path [lindex $argv 3] set remote_script "/tmp/[file tail $script_path]" # 上传脚本到远程 spawn scp $script_path $user@$host:$remote_script expect "password:" send "$password\r" expect eof # 执行远程脚本 spawn ssh $user@$host "$remote_script" expect "password:" send "$password\r" expect eof # 可选:删除远程临时脚本 spawn ssh $user@$host "rm $remote_script" expect "password:" send "$password\r" expect eof
方法3:直接嵌入脚本内容(适合短脚本)
如果pwd.sh内容简单(比如只有pwd命令),可以直接把命令写进expect脚本,不用单独传文件:
set host [lindex $argv 0] set user [lindex $argv 1] set password [lindex $argv 2] spawn ssh $user@$host expect "password:" send "$password\r" expect -re {\$ } send "pwd\r" send "exit\r" expect eof
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

