我正在编写一个sh
脚本来从 Windows SFTP 服务器下载文件。但在执行此操作之前,我想检查该文件是否存在。
有很多问题建议下载 winexe,或者使用ssh host@host test -f file
其他替代方法,但对我来说,这些方法都行不通。我不允许安装任何东西,必须使用现成的实用程序。
我之所以需要在实际下载之前进行测试,是因为已经设置了许多预先存在的流程,要求文件在到达下载部分之前必须存在。不要问我为什么会这样。我进来的时候就已经这样了。
答案1
标准(OpenSSH)SFTP 客户端不提供测试文件存在或类似功能。
我假设您唯一的接口是 SFTP 协议,以使解决方案独立于平台(因为您连接到 Windows)。因此,test
通过 SSH 终端执行的解决方案不可行(正如您自己所确认的那样)。
您可以使用 SFTP 命令来解决这个问题,这个命令开销很小,当文件不存在时会失败。然后测试sftp
退出代码(1 表示错误,0 表示正常)。
您可以滥用df
(磁盘释放)命令来实现这一点。
echo "df myfile.txt" | sftp -b - example.com
if [ $? -eq 0 ]
then
echo "File exists"
else
echo "File does not exist"
fi
虽然df
命令在内部使用了 SFTP 协议的专有 OpenSSH 扩展([email protected]
)。因此,您必须先测试您的 Windows SFTP 服务器是否支持该扩展。显然,如果您使用 OpenSSH(MS Win32 版本或 Cygwin),则没问题。
如果df
不起作用,唯一的其他选择就是尝试下载文件。
最好将下载代码移到所有“已经设置了需要该文件存在的预先存在的进程”。我认为这是最好的解决方案。正如@Kenster 评论的那样:该文件可能会在您检查和下载之间消失。或者该文件可能存在,但您可能没有读取它的权限。除了尝试下载文件之外,检查文件是否存在可能没有您想象的那么有用。
如果这不可能,您需要下载该文件两次。第一次是为了测试它是否存在。然后再一次真正地下载它。
虚假下载以测试文件是否存在:
echo "get myfile.txt /dev/null" | sftp -b - example.com
if [ $? -eq 0 ]
then
echo "File exists"
else
echo "File does not exist"
fi
/dev/null
如果可以将测试和下载步骤合并为一个,请用实际路径替换。
SFTP 协议本身可以测试文件是否存在。因此,如果您手边有除 OpenSSH 之外的其他 SFTP 客户端,您可能能够更轻松地执行此操作。
lftp -c "open sftp://example.com ; find myfile.txt"
if [ $? -eq 0 ]
then
echo "File exists"
else
echo "File does not exist"
fi
对于类似的问题,请参见测试是否使用 SFTP 命令下载了任何文件。