Cat несколько файлов через одно соединение SSH и получить возвращаемое значение для каждого - PullRequest
1 голос
/ 01 декабря 2011

Как сказано в заголовке, я пытаюсь перебрать несколько файлов (контент должен быть добавлен к существующим файлам на хосте) через одно соединение ssh и получить возвращаемое значение для каждого, то есть, если этот кот для конкретного файла был успешнымили нет.До сих пор я делал это для каждого файла отдельно, просто повторяя следующую команду для каждого и проверяя возвращаемое значение.

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

Затем я просто проверял возвращаемое значение для каждой передачи (автоматически) и тем самымможет определить статус для каждого файла.Мой вопрос: возможно ли это через одно соединение 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;
    }
}

ВТОРОЕ РЕДАКТИРОВАНИЕ:

Я выполняю этот код на маршрутизаторе как частьпрограмма.Обратите внимание, что мне не разрешено добавлять новые библиотеки или неосновные функции в систему.Кроме того, клиент ssh в самой системе не разрешает режим «-M».

Ответы [ 3 ]

5 голосов
/ 01 декабря 2011

Редактировать в ответ на добавленную информацию (и код):

К коду: я настоятельно рекомендую написать скрипт / программу на принимающей стороне, чтобы поговорить с процессом отправки по 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

0 голосов
/ 18 августа 2017

Если вы посмотрите на проблему с другой тактической точки зрения, вы можете перебрать все файлы из другого мастер-файла.Этот мастер-файл является сценарием оболочки, в который встроены документы с содержимым файлов.Затем выполните сценарий мастер-оболочки и откройте файлы - все в одном сеансе ssh.Это не красиво или элегантно, но будет успешным.

0 голосов
/ 02 декабря 2011

Как насчет создания libssh2 вместо сценариев ssh и использования подсистемы sftp вместо создания собственной системы передачи файлов в оболочке?

Есть пример выполнения добавления одного файлав libssh2 / examples / sftp_append.c просто повторите это для нескольких файлов, которые вы хотите.

...