猫通过一个SSH连接多个文件,并获得每个返回值

正如在标题中所说,我试图通过一个SSH连接多个文件(内容需要附加到主机上的现有文件),并获得每个返回值,即如果该特定文件的猫是成功的。 到目前为止,我对每个文件单独做了这个,只需重复下面的命令,并检查返回值。

cat specific_file | ssh user@host -i /root/.ssh/id_rsa "cat >> result/specific_file" 

然后我只是检查每次传输的返回值(自动),从而可以确定每个文件的状态。 我的问题是:是否有可能通过一个单一的SSH连接,但获得每个单一文件的返回值?

提前致谢 !

编辑:

(b)正如你在下面看到的,我为一个特定的文件生成一个命令,然后检查返回码。 包含程序的这部分的方法然后被调用为不同的typeso

如果文件已成功logging,则可以从客户端删除该文件,并且还允许进一步logging到该文件的types。 如果文件超出限制,则该位在程序的另一部分未被设置。

 sprintf(command,"/bin/cat /root/%s%s | /usr/bin/ssh log-bot@192.168.5.1 -i" " /root/.ssh/id_rsa \"/bin/cat >> result/%s%s\"", apmac, ending_str[source], apmac, ending_str[dest]); rc = system(command); if(rc != 0) { sprintf(buffer, "[%i] - LOG ERROR from %s to %s CODE %i ", (int)time(0), ending_str[source], ending_str[dest], rc); sprintf(filename,"%s%s%s", LOCAL, apmac, ending_str[source]); } else { sprintf(filename,"%s%s%s", LOCAL, apmac, ending_str[source]); remove(filename); sprintf(buffer, "[%i] - LOG process from %s to %s ok", (int)time(0), ending_str[source], ending_str[dest]); switch(source) { case PROBE_FILE: LOG_MASK_SET(globals->log_mask, LOG_MASK_PROB); break; case LIST_FILE: LOG_MASK_SET(globals->log_mask, LOG_MASK_LIST); break; case SCAN_FILE: LOG_MASK_SET(globals->log_mask, LOG_MASK_SCAN); break; default: /* Other cases not YET considered */ break; } } 

第二次编辑:

作为程序的一部分,我在路由器上运行这个代码。 请注意,我不允许向系统添加新库或非基本function。 另外,系统本身的ssh客户端不允许“-M”模式。

Solutions Collecting From Web of "猫通过一个SSH连接多个文件,并获得每个返回值"

编辑响应添加的信息(和代码):

对于代码:我强烈地考虑在接收端编写一个脚本/程序,通过ssh 管道与发送进程交谈。 这样你有充分的灵活性。

最简单的工作,仍然可能是将档案发送给接收主机。 在接收端,使用脚本过滤存档

  • 将每个文件解压到一个临时位置
  • 尝试追加操作cat >> specific_file
  • 打印“结果记录”作为stdout作为反馈给发件人

所以你会这样做:

 tar c file1 file2 file3 | ssh log-bot@remote /home/log-bot/handle_logappends.sh | while read resultcode filename do echo "$filename" resulted in code "resultcode" done 

为了处理C / C ++中的反馈,你可以看看popen ,这将允许你从文件中读取流式反馈,很简单!

接收端的这种handle_logappends.sh脚本的一个例子:

 #!/bin/bash set -e # bail on error TEMPDIR="/tmp/.receiving_$RANDOM" mkdir "$TEMPDIR" trap "rm -rf '$TEMPDIR/'" INT ERR EXIT tar x -v -C "$TEMPDIR/" | while read filename do echo "unpacked file $filename" > /dev/stderr ## implement your file append logic here :) ## eg (?): cat "$TEMPDIR/$filename" >> "result/$filename" ## HERE COMES THE FEEDBACK PART: '<code> <filename>' echo "$?" "$filename" done 

其中真正整洁的部分是, 由于所有内容都处于流模式 ,所以第一个文件的反馈可能正在到达, 发送的tar仍然在将后面的文件发送给接收主机。 没有不必要的延误

我包括了一点理智的错误处理/清理,但我会建议

  • 也许首先接收整个档案,然后遍历文件?
  • 以原子方式进行附加操作(即在副本上,然后只有在整个附加操作成功时才将副本移动到位;这样可以防止部分附加日志)

希望有所帮助!


较老的答案:

你通常会使用狡猾的小技巧( ),如:

 tar c file1 file2 file3 | ssh user@host -i /root/.ssh/id_rsa "tar x -C result/ -" 

添加一个详细的标志来查看进度的详细信息

 tar c file1 file2 file3 | ssh user@host -i /root/.ssh/id_rsa "tar xvC result/ -" 

如果你愿意,你可以用cpio替换焦油。 添加选项以获得更多功能( -p保留权限,例如)


要通过单个逻辑连接执行各个单独的步骤,可以使用ssh Master连接:

 ssh user@host -i /root/.ssh/id_rsa -MNf # login, master, background without a command for specific_file in file1 file2 file3 do cat "$specific_file" | ssh user@host -Mi /root/.ssh/id_rsa "cat >> 'result/$specific_file'" # check/use error code done 

如何构建libssh2而不是脚本ssh,并使用sftp子系统而不是在shell中构建自己的文件传输系统?

有一个在libssh2 / examples / sftp_append.c中执行一个文件附加的例子 ,只需要为你想要的多个文件重复一遍。

如果从不同的战术角度看问题,则可以从另一个主文件中获取所有文件。 该主文件是一个shell脚本,在这里有嵌入文件内容的文档。 然后执行主shell脚本和ls文件 – 全部在一个ssh会话中。 这不是漂亮或优雅,但会成功。