我有一个 sub sh 文件,它接收本地目录和远程目录路径的输入,并将文件发送到远程目录。如果远程路径无效,则无法检测到错误。
sh 脚本内的示例内容:
sftp [email protected] <<==
cd $remote_dir <= error happens here
lcd $local_dir <= error did not happen so the return code resets
put a.tar
bye
==
$result=$?
return $result
有些应用程序调用sh文件,然后通过返回码来判断文件是否发送成功。如果是,则将本地文件备份到某处然后将其删除。
问题是即使文件发送失败,shell 也会返回零。文件确实没有被复制,您可以看到当您手动执行命令时会发生错误,屏幕上显示找不到路径,但是当作为作业运行时,它会失败。
我知道另一种方法是执行两个步骤,首先检查路径是否存在,然后输出到日志文件并检查日志是否包含错误,如果没有错误则可以调用 sftp put shell 脚本。我想知道是否还有其他方法。
答案1
sftp
使用以下选项运行-b
:
sftp -b - [email protected] <<==
cd etc.
==
来自sftp
手动的:
-b批处理
模式从输入批处理文件而不是标准输入中读取一系列命令。由于它缺乏用户交互,因此应与非交互式身份验证结合使用。批处理文件“-”可用于指示标准输入。sftp 将中止如果以下任何命令失败:get、put、reget、reput、rename、ln、rm、mkdir、目录, ls,目录、chmod、chown、chgrp、lpwd、df、符号链接和 lmkdir。通过在命令前添加“-”字符(例如,-rm /tmp/blah*),可以逐个命令地抑制错误终止。
答案2
处理 SFTP 中的错误是一件痛苦的事情:SFTP 脚本语言没有条件结构;要执行预定义命令序列之外的任何操作,您需要在每个命令之后解析服务器的输出。您可以使用诸如 之类的工具来完成此操作expect
,但这需要相当多的工作,并且很难确保您涵盖了所有情况。
对于您展示的示例,您可以使用
echo "put $local_dir/a.tar $remote_dir" | sftp [email protected]
但一般来说错误处理很复杂。
所以不要使用SFTP。相反,使用安装远程服务器SSHFS。这不需要在服务器上进行任何特殊配置,因为 SSHFS 在底层使用 SFTP。你只需要拥有保险丝为客户工作。
SSHFS 将远程文件的视图呈现为本地计算机上已安装的文件系统。因此,您可以使用诸如 、 等普通命令cd
来cp
操作文件,而无需关心每个文件所在的位置(性能方面除外 - 例如,将文件从本地位置复制到远程位置不会比您的上传带宽更快) )。
set -e
mkdir myserver
sshfs [email protected]/ myserver
cp -p "$local_dir/a.tar" "myserver/$remote_dir/"
…
fusermount -u
答案3
遵循提示/建议 吉尔斯的回答,重定向 stderr 对我们有用。
sftp -q host <<--- > script.log 2> scripterr.log
get nonex.txt
bye
---
之后,检查scripterr.log
“未找到”。