Предоставить параметры для scp с помощью xargs

10

Когда я бегу svn st | awk '{print $2}', я получаю:

a.py
b.py
c.py

Затем я хочу, чтобы scpэти файлы на удаленном сервере. Я пытался:

svn st | awk '{print $2}' | xargs scp my_name@my_server:~/

Но это не работает. Какова правильная команда, чтобы сделать это?

Спасибо!

mitnk
источник

Ответы:

10

попробуй это. должен работать с последними версиями xargs.

svn st | awk '{print $2}' | xargs -iz scp z my_name@my_server:

поочередно, вы можете просто зациклить файлы.

for file in $(svn st | awk '{print $2}'); do scp $file my_name@my_server: ; done

Тим Кеннеди
источник
2
Спасибо, Тим. Я много гуглил и нашел решение: svn st | awk '{print $2}' | xargs -J % scp % my_name@my_server:~/я должен был прочитать man-страницу, xargsпрежде чем спрашивать;)
mitnk 18.11.11
И ваше решение тоже работает! Но есть опечатка, это -Izне так-iz
MITNK
какую ОС вы используете? Я использую -izна Солярисе, и он всегда работает. Спасибо за указатель.
Тим Кеннеди
4
POSIX xargs имеет -I. Справочная страница AIX (6.1) говорит, -iчто устарела и -Iдолжна использоваться. Солярис 10 (и 9) имеет как -iи -I.
Мат
1
Ах, мои знания устарели! Я использую -iс Solaris 2.5. состариться, это печальное дело, друзья мои. :)
Тим Кеннеди
4

Причина, по которой это не работает, в том, что вы говорите xargsбежать

scp my_name@my_server:~/ a.py b.py c.py

Порядок аргументов не соответствует тому, что вы хотите сделать. Одно из решений заключается в том, чтобы имена файлов отображались перед адресатом в командной строке. Для этого требуется GNU xargs (то есть Linux или Cygwin). Пока мы работаем над этим, мы можем передать, -d '\n'что любое имя файла, которое не содержит символов новой строки, будет работать (без -d, xargs ожидает некоторого странного цитирования своего ввода); в этом нет необходимости, если вы работаете с типичными деревьями исходного кода программного обеспечения, в которых имена файлов имеют тенденцию быть очень ручными.

svn st | awk '{print $2}' |
xargs -d\\n -I{} scp {} my_name@my_server:~/

Недостатком этого метода является то, что он scpвызывается отдельно для каждого файла. Если вы копируете много маленьких файлов, это может иметь существенное значение, так как для установки SSH-соединения требуется немного времени. Вы можете значительно сократить каждое подключение времени с помощью мастер SSH - соединения (это outstide рамки этого ответа, смотрите руководство, особенно ControlMasterи ControlPathварианты в .ssh/config).

Чтобы заставить аргументы быть в нужном месте, нужно пройти через промежуточную оболочку. Это общая техника для изменения порядка аргументов при использовании xargsили find … -exec.

svn st | awk '{print $2}' |
xargs -d\\n sh -c 'scp "$@" "$0" my_name@my_server:~/

Другая возможность заключается в использовании rsyncвместо scp. Вы можете передать rsyncсписок имен файлов на стандартный ввод. Так как rsyncожидает список шаблонов, а не список имен файлов, для этого необходимо, чтобы имена файлов не содержали подстановочных знаков (в частности, без перевода строки, без \[*?и без начальных #или ;).

svn st | awk '{print $2}' |
rsync -a --include-from=- --exclude='*' . my_name@my_server:~/
Жиль "ТАК - перестань быть злым"
источник