bash - 使用管道安全地传输 FTP 文件

标签 bash ftp sftp

我有一个文件转发系统,其中一堆文件被下载到一个目录,解复用并复制到各个机器。 文件在主服务器收到后被转发。文件通常是突发的。 (通过 ssh key 验证)

此脚本创建 sftp session ,并使用管道监视 fifo 管道的头部。

HOST=$1
pipe=/tmp/pipes/${HOST%%.*}
ps aux | grep -v grep | grep  sftp | grep "user@$HOST" > /dev/null
if [[ $? == 0 ]]; then
    echo "FTP is Running on this Server"
    exit
else
    pid=`ps aux | grep -v grep | grep  tail  | tr -s ' ' | grep $pipe`
    [[ $? == 0 ]] && kill -KILL `echo $pid | cut -f2 -d' '`
fi
if [[ ! -p $pipe ]]; then
    mkfifo $pipe
fi
tail -n +1 -f $pipe | sftp -o 'ServerAliveInterval 60' user@$HOST > /dev/null &
echo cd /tmp/data >>$pipe #Sends Command to Host
echo "Started FTP to $HOST"

更新:我最终更改了清理代码以使用“ps aux”来查看 ftp session 是否正在运行,以及随后的 tail -f 是否仍在运行。分别通过 user@host 和管道名称进行 Grep。这是在调用脚本时完成的,每当我尝试上传文件时都会调用脚本。
即:

FILENAME=`basename $1`
function transfer {
    echo cd /apps/data >> $2 # For Safety
    echo put $1 .$FILENAME >> $2
    echo rename .$FILENAME $FILENAME  >> $2
    echo chmod 0666 $FILENAME  >> $2
}
./ftp.sh host
[ -p  $pipedir/host ] && transfer $1 $pipedir/host

在主服务器上接收到的文件被 Incron 捕获,Incron 将一个 put 命令和可用文件的位置写入 fifo 管道,由 sftp 发送(重命名也是预先形成的)。

我的问题是,这样安全吗?这会因 ftp 错误/事件而崩溃吗?不太担心登录错误。
目标是减少 ftp 登录的次数。单个 session /分钟(或更多)间隔。
并允许在收到文件时转发文件。动态命令。 如果可能的话,我更愿意使用标准的 ubuntu 库。

编辑:在测试和解决一些问题后,服务器简单地运行

[[ -p $pipe ]] && echo FTP is Running on this Server
ln -s $pipe $lock &> /dev/null || (echo FTP is Running on this Server && exit)
[[ ! -p $pipe ]] && mkfifo $pipe
( tail -n +1 -F $pipe & echo $! > $pipe.pid ) | tee >
        ( sed "/tail:/ q" >/dev/null && kill $(cat $pipe.pid) |& rm -f $pipe >/dev/null; )
        | sftp -i ~/.ssh/$HOST.rsa -oServerAliveInterval=60 user@$HOST &
rm -f $lock

它相当简单,但效果很好。

最佳答案

您可能有兴趣建立一个更简单(和健壮)的同步基础设施: 如果在文件到达时给定主机未连接......它永远不会收到它(如果我理解正确你的代码)

我会做类似的事

 rsync -a -e ssh user@host:/apps/data pathToLocalDataStore

在客户端机器上,定期或按事件...rsync 通过时间戳和大小(-a 包含 -t)智能地同步文件

事件将是一些进程终止,例如: 客户端确实(在主机的 ~/.ssh/config 中配置私钥使用):

#!/bin/bash
while :;do
  ssh user@host /srv/bin/sleepListener 600
  rsync -a -e ssh user@host:/apps/data pathToLocalDataStore
done

在服务器上 /srv/bin/sleepListener 是指向 /bin/sleep 的符号链接(symbolic link) 收到新文件后的服务器:

killall sleepListener

注意:每 10 分钟执行一次全面检查...如果节点离线/在线没关系...

关于bash - 使用管道安全地传输 FTP 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15688814/

相关文章:

bash - 在 bash/awk 中检测一系列数字是否连续

c# - WinSCP:如何确保 SFTP 上传从 .zip.filepart 重命名为 .zip?

c# - SharpSSh : Restart file transfer if current file transfer too slow?

bash - 获取其他变量扩展的 quoted-dollar-at ( "$@") 行为?

bash - 求和 csv 文件第二列的命令

bash - 如何在 bash 中使用 N! 进行排列输入?

python - 如何使用Python中的套接字库将服务器连接到其他计算机?

Windows文件输出重定向问题

excel - 从 FTP 站点获取最新文件的批处理/宏代码

php - 在 Phpseclib 中恢复下载