【问题标题】:Store output of command in sftp to variable and list将 sftp 中的命令输出存储到变量和列表中
【发布时间】:2019-11-29 06:49:26
【问题描述】:
我的目标是创建一个 shell 脚本,以便它登录并过滤可用文件列表并选择要获取的文件。在这里,我需要像在 bash 中一样运行命令。
我的示例代码是:
sshpass -p password sftp user@10.10.10.10 <<EOF
cd /home/
var=$(ls -rt)
echo $var
echo "select a folder"
read folder
cd $folder
filen=&(ls -rt)
echo $filen
echo "select a file"
read name
get $name
bye
EOF
【问题讨论】:
-
您想从您的程序中控制一个 FTP 会话,同时保持与用户的对话。我不会在 bash 中这样做。例如,看一下 Perl 与 Net::SFTP,例如讨论 here 或 Ruby。
-
标签:
bash
shell
unix
sh
sftp
【解决方案1】:
上述方法行不通。请记住,“此处文档”(<<EOF ... EOF)被评估为sftp 会话的输入。将显示提示,并在 sftp 提供任何输出(在本例中为 ls)之前请求用户输入。
考虑使用lftp,它具有更灵活的构造。特别是,它可以让你使用变量、动态创建命令等。
lftp sftp://user@host <<EOF
cd /home
ls
echo "Select Folder"
shell 'read folder ; echo "cd $folder" >> temp-cmd'
source temp-cmd
ls
echo "Select Folder"
shell 'read file ; echo "get $file" >> temp-cmd'
source temp-cmd
EOF
理论上,您可以使用管道和sftp(可能是协同过程?)创建类似的构造,但这要困难得多。
当然,另一种选择是为列表创建不同的sftp 会话,但这会很昂贵/效率低下。
【解决方案2】:
经过一些研究和实验,找到了一种使用 sftp 创建批处理/交互式会话的方法。 作为单独的答案发布,因为我仍然相信更简单的方法是使用 lftp(请参阅其他答案)。可以在没有 lftp 的系统上使用
最初的exec 创建FD#3——指向原来的标准输出——可能是用户终端。发送到标准输出的任何内容都将由管道中的 sftp 执行。
管道需要允许两个进程同时运行。使用 here doc 将导致顺序执行。需要 sleep 语句才能让 SFTP 从远程主机完成数据检索。
exec 3>&1
(
echo "cd /home/"
echo "ls"
sleep 3 # Allow time for sftp
echo "select a folder" >&3
read folder
echo "cd $folder"
echo "ls"
sleep 3 # Allow time for sftp
echo "select a file" >&3
read name
echo "get $name"
echo "bye"
) | sshpass -p password sftp user@10.10.10.10
【解决方案3】:
我建议您创建一个包含您要下载的文件模式的文件,然后您可以在一行中下载文件:
sftp_connection_string
如果要查看多个确定的文件夹,则:
**Script version**
for fldr in folder1 folder2 folder3;do
sftp_connection_string <<< $"ls -lrt ${fldr}/"|grep -v '^sftp'|grep -f pattern_file|awk '{print $9}'|sed -e "s/^/get -P ${fldr}/g"|sftp_connection_string
done
单线
for fldr in folder1 folder2 folder3;do sftp_connection_string <<< $"ls -lrt ${fldr}/"|grep -v '^sftp'|grep -f pattern_file|awk '{print $9}'|sed -e "s/^/get -P ${fldr}\//g"|sftp_connection_string;done
让我知道它是否有效。