Bash脚本连接SFTP成功后无法直接执行内置命令如何解决
问题根因
两种失败写法的核心问题都是没有把SFTP操作命令作为sftp进程的标准输入传入:
- 顺次写命令的写法:Bash执行
sftp命令后会阻塞等待sftp进程退出,后续的put、exit是Bash shell的待执行命令,sftp进程完全收不到,等手动退出sftp后Bash才会尝试执行这两行,自然报命令不存在。 - here-document写法的错误:
<<-EOF重定向标记写在了sftp命令的下一行,没有作为sftp命令的输入重定向附属部分,Bash会把这个here-document当成独立的输入块,不会传给sftp进程;另外贴出的业务脚本里sftp命令本身还被注释了,根本不会触发上传。 - 循环场景的额外坑:
while read循环默认占用标准输入流,sftp启动后如果不加参数会默认从标准输入读内容,会意外吃掉CSV文件的后续行,导致循环直接跳过上传步骤进入下一次迭代,和观测到的异常输出完全吻合。
无需外部命令文件的正确实现
直接把here-document跟在sftp命令的同一行末尾,同时给sftp加-n参数,禁止sftp从标准输入额外读取内容,避免和while循环的输入流冲突,完整修正后的脚本如下:
#!/bin/bash set -x #echo on while IFS="," read -r col1 col2 do echo "user: $col1" echo "id: $col2" cd /efs/$col1/ftpout || exit 1 cp * /efs/$col1/backup # 注意<<EOF必须紧跟sftp命令,不要换行;-n参数避免sftp抢占循环的CSV输入流 sftp -n -oIdentityfile=/root/.ssh/id_rsa user@sftpsite.domain.com:/home/folder <<EOF put test.txt exit EOF #rm test.txt done < <(tail -n +2 us_craig.csv)
写法注意事项
- 如果想给here-document内部的命令加缩进,要把
<<EOF改成<<-EOF,且所有缩进必须用Tab字符,不能用空格,否则Bash无法识别结束的EOF标记。 - 如果是单条简单命令,也可以用管道直接传输入,不需要here-document:
echo -e "put test.txt\nexit" | sftp -n -oIdentityfile=/root/.ssh/id_rsa user@sftpsite.domain.com:/home/folder
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

