终端SFTP命令正常,Shell脚本仅连接不执行put命令的问题排查
SFTP自动化脚本仅连接不执行
put命令的问题分析与解决 问题场景
你手动在终端执行以下SFTP命令时一切正常:
sftp -i ~/.ssh/id_rsa username@host put csv_file put manifest_file
但将这些命令写入run.sh脚本后,执行sh run.sh却只会成功连接到目标主机,后续的文件传输命令完全没被执行。
问题原因
这是因为交互式SFTP会话和脚本执行的逻辑差异导致的:
当你在脚本中直接调用sftp -i ~/.ssh/id_rsa username@host时,这个命令会启动一个交互式的SFTP会话,脚本会卡在这个会话中等待你手动输入命令——而脚本里后面的put语句,其实是要等SFTP会话退出之后,才会被shell尝试执行,自然不会在SFTP会话里生效。
解决方法
这里提供几种实用的方案,帮你实现SFTP命令的自动化执行:
方案1:使用Here Document(Heredoc)传递命令
修改run.sh的内容为:
#!/bin/bash sftp -i ~/.ssh/id_rsa username@host << EOF put csv_file put manifest_file EOF
原理:<< EOF是shell的here document语法,它会把EOF之间的所有内容作为输入传递给前面的sftp命令。这样SFTP会话启动后,会自动执行这两个put命令,完成后自动退出会话。
方案2:使用-b参数指定批处理命令文件
- 先创建一个存放SFTP命令的文件,比如
sftp_commands.txt,内容如下:
put csv_file put manifest_file
- 修改
run.sh脚本:
#!/bin/bash sftp -i ~/.ssh/id_rsa -b sftp_commands.txt username@host
原理:-b参数让SFTP以批处理模式运行,直接读取指定文件中的命令并执行,无需交互式输入,适合命令较多的场景。
方案3:单行管道写法(适合简单命令场景)
如果你的SFTP命令不多,也可以用管道直接传递命令:
#!/bin/bash echo -e "put csv_file\nput manifest_file" | sftp -i ~/.ssh/id_rsa username@host
原理:通过echo -e输出带换行的命令,再通过管道|将内容作为sftp的输入,实现自动执行。
额外注意事项
- 确保脚本中指定的
csv_file和manifest_file路径正确,如果文件不在脚本执行的当前目录,建议使用绝对路径 - 给脚本添加执行权限:
chmod +x run.sh,之后可以直接通过./run.sh执行 - 若遇到私钥权限报错,检查
~/.ssh/id_rsa的权限是否为600(执行chmod 600 ~/.ssh/id_rsa修正),SFTP对私钥的权限要求非常严格
内容的提问来源于stack exchange,提问作者chandra sutrisno
相关产品推荐
相关产品推荐

