通过一个ssh连接捕获多个文件并获取每个文件的返回值

Tor*_*ten 1 linux ssh cat

如标题中所述,我试图通过一个ssh连接捕获多个文件(内容需要附加到主机上的现有文件),并获取每个文件的返回值,即特定文件的cat是否成功.到目前为止,我单独为每个文件执行此操作,只需对每个文件重复以下命令并检查返回值.

cat specific_file | ssh user@host -i /root/.ssh/id_rsa "cat >> result/specific_file"
Run Code Online (Sandbox Code Playgroud)

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

提前致谢 !

编辑:

(b)如下所示,我为一个特定文件生成一个命令,然后检查返回码.然后为不同类型o调用包含该部分程序的方法

如果文件已成功记录,则可以从客户端删除该文件,并且(仍)允许进一步记录到文件类型.如果文件超出其限制,则在程序的另一部分中取消设置该位.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

第二次编辑:

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

seh*_*ehe 5

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

代码:我强烈考虑在接收端编写脚本/程序,通过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
Run Code Online (Sandbox Code Playgroud)

要处理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 :)
    ## e.g. (?):
    cat "$TEMPDIR/$filename" >> "result/$filename"

    ## HERE COMES THE FEEDBACK PART: '<code> <filename>'
    echo "$?" "$filename"
done
Run Code Online (Sandbox Code Playgroud)

这样做的很整洁的部分是,因为一切都在流模式,第一个文件(S)的反馈可到达,同时发送焦油后文件仍然发送到接收主机.没有不必要的延误

我包含了一些理智的错误处理/清理,但我建议

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

希望有所帮助!


老答案:

你通常会使用狡猾的小技巧(不是):

tar c file1 file2 file3 | ssh user@host -i /root/.ssh/id_rsa "tar x -C result/ -"
Run Code Online (Sandbox Code Playgroud)

添加详细标记以查看进度详细信息

tar c file1 file2 file3 | ssh user@host -i /root/.ssh/id_rsa "tar xvC result/ -"
Run Code Online (Sandbox Code Playgroud)

如果需要,可以替换cpiotar.添加选项以获得更多功能(-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
Run Code Online (Sandbox Code Playgroud)