Як виконати віддалену команду і передати в локальний файл як вхід?


22

Чи можливо це зробити:

ssh user@socket command /path/to/file/on/local/machine

Тобто, я хочу виконати віддалену команду, використовуючи локальний файл за один крок, попередньо scpне скопіювавши файл.


Це можливо, якщо на віддаленому комп’ютері встановлено мережеве кріплення батьківського каталогу файлу локальної машини або якщо ви перенаправляєте файл у команду ssh
h3rrmiller

Відповіді:


23

Ви пропустили лише один символ =)

ssh user@socket command < /path/to/file/on/local/machine

Звичайно! Цікаво, чому я не вважав переадресацію входу через ssh ?!
jsj

Що робити, якщо віддалена команда може приймати лише аргумент файлу, а не читати з stdin?
iruvar

@ChandraRavoori у такому випадку вам потрібно скопіювати його scpраніше.
пік

4
@ChandraRavoori Ви можете спробувати надати йому аргумент файлу /dev/stdinабо -. Може працювати, а може не працювати ( /dev/stdinфайл, але шукати його не вдасться)
derobert

1
@derobert і кидайтеся, трохи пограли з ним і виявили шалений спосіб зробити це, використовуючи підстановку процесу під bash. Це все ще підлягає обмеженню, яке шукає, і може отримати непростий з усіма додатковими котируваннями, які знадобляться. Приклад наступний. кішка test.file | ssh user @ machine 'bash -c "wc -l <(cat -)"'
iruvar

4

Один із способів роботи незалежно від команди - це зробити доступним файл на віддаленій машині через віддалену файлову систему. Оскільки у вас SSH-з'єднання:

  1. Встановити зворотний тунель SSH . Дивіться також SSH легко копіювати файл у локальну систему
  2. Встановіть дерево каталогів на вашій машині, що містить файл для спільного використання на віддаленій машині з SSHFS . ( Приклад )

У будь-якому випадку цей спосіб вимагає додаткових рухів перед виконанням команди.
пік

@Gilles: Я думаю, що оригінальна назва була введеною в оману, і ви зрозуміли його питання на основі оманливої ​​назви. Наскільки я можу сказати, подумав, він насправді не хотів діяти на локальному файлі, а просто передав його як вхідний файл. (Але ваша відповідь є дивовижною, якщо я правильно її зрозумів! Можливо, я повинен поставити запитання, на яке ви відповіли, просто щоб дати вам місце, де можна поставити відповідь, де ви отримаєте належну заслугу за це.) Я відредагував заголовок питань щоб він відповідав тілу та обраній відповіді.
іконоборство

@iconoclast Я не пам’ятаю свого душевного стану, коли писав це, але я йду за цією відповіддю. Це вимагає певних налаштувань, але має перевагу узагальнення, що перевищує негайну вимогу до інших випадків, коли для копіювання введення недостатньо. Я б також згадав про переадресацію, якби хтось інший цього не робив. Більш загальне питання задавали багато разів у дещо різних формах.
Жил 'ТАК - перестань бути злим'

Гаразд, я, мабуть, неправильно зрозумів вашу відповідь. Я не пробував цього, але зробив висновок, що оскільки ви створювали зворотний тунель (від віддаленого до локального хоста?), Ви дозволяли змінювати локальний файл віддаленою машиною. Це не так?
іконоборство

@iconoclast Так, це дозволяє віддаленій машині змінювати локальний файл (на додаток до того, щоб він міг його читати, що вимагає запитання).
Жил 'ТАК - перестань бути злим'

1
# What if remote command can only take a file argument and not read from stdin? (1_CR)
ssh user@socket command < /path/to/file/on/local/machine
...
cat test.file | ssh user@machine 'bash -c "wc -l <(cat -)"'  # 1_CR

В якості альтернативи bashпроцесу заміни <(cat -)або < <(xargs -0 -n 1000 cat)(див. Нижче) ви можете просто використовувати xargsта catпередавати вміст зазначених файлів wc -l(який є більш портативним).

# Assuming that test.file contains file paths each delimited by an ASCII NUL character \0
# and that we are to count all those lines in all those files (provided by test.file).

#find . -type f -print0 > test.file
# test with repeated line count of ~/.bash_history file
for n in {1..1000}; do printf '%s\000' "${HOME}/.bash_history"; done > test.file

# xargs & cat
ssh localhost 'export LC_ALL=C; xargs -0 -n 1000 cat | wc -l' <test.file

# Bash process substitution
cat test.file | ssh localhost 'bash -c "export LC_ALL=C; wc -l < <(xargs -0 -n 1000 cat)"'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.