簡體   English   中英

通過一個ssh連接管理多個文件,並為每個文件獲取返回值

[英]cat multiple files over one ssh connection and get return value for each

如標題中所述,我正在嘗試通過一個ssh連接管理多個文件(內容需要附加到主機上的現有文件),並為每個文件獲取返回值,即,該貓是否適用於特定文件。 到目前為止,我僅對每個文件重復執行以下命令並檢查返回值,從而分別對每個文件進行了此操作。

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

然后,我只是自動檢查了每次傳輸的返回值,從而可以確定每個文件的狀態。 我的問題是:是否可以通過單個ssh連接來實現此目的,但可以為每個文件獲取返回值?

提前致謝 !

編輯:

(b)如下所示,我為一個特定文件生成了一條命令,然后檢查了返回代碼。 然后,針對不同類型的對象,調用包含程序這一部分的方法

如果文件已成功記錄,則可以將其從客戶端中刪除,並且允許(仍然)進一步記錄文件類型。 如果文件超出其限制,則該位在程序的另一部分中未設置。

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;
    }
}

第二編輯:

我正在路由器上將此代碼作為程序的一部分運行。 請注意,我不允許向系統添加新庫或非基本功能。 另外,系統本身的ssh客戶端不允許使用“ -M”模式。

編輯響應添加信息(和代碼):

對於代碼:我強烈考慮在接收端編寫一個腳本/程序,以通過ssh pipe與發送過程進行對話。 這樣,您就具有了充分的靈活性。

可能起作用的最簡單的方法似乎仍然是將存檔發送到接收主機。 在接收端,使用以下腳本過濾歸檔文件

  • 將每個文件解壓縮到一個臨時位置
  • 嘗試追加操作cat >> specific_file
  • 將“結果記錄”打印到標准輸出,作為對發件人的反饋

所以你會做:

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 :)
    ## e.g. (?):
    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代替tar。 添加選項以獲得更多功能(例如-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

如果您從不同的戰術角度看問題,則可以從另一個主文件中查找所有文件。 該主文件是一個shell腳本,在此腳本中嵌入了文件內容。 然后執行主Shell腳本並執行ls文件-全部在一個ssh會話中進行。 它不是漂亮或優雅,但會成功。

如何在libssh2構建而不是對ssh腳本編寫腳本,以及如何使用sftp子系統而不是在shell中構建自己的文件傳輸系統呢?

libssh2 / examples / sftp_append.c中有一個執行一個文件追加的示例 ,只需對所需的多個文件重復該操作即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM