リモートコマンドを実行し、ローカルファイルを入力として渡す方法


22

これを行うことは可能ですか?

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

つまり、最初scpにファイルのコピーに使用せずに、ローカルファイルを使用して1つの手順でリモートコマンドを実行したいということです。


リモートコンピューターにローカルマシンのファイルの親ディレクトリのネットワークマウントがある場合、またはファイルをsshコマンドにリダイレクトする場合
-h3rrmiller

回答:


23

シンボルを1つだけ逃した=)

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

もちろん!なぜssh経由の入力リダイレクトを考慮しなかったのだろうか?
jsj

リモートコマンドがファイル引数のみを取り、標準入力から読み取れない場合はどうなりますか?
-iruvar

@ChandraRavooriの場合、scp以前にそれをコピーする必要があります。
ラッシュ

4
@ChandraRavooriファイル引数/dev/stdinまたはを指定してみてください-。動作する場合と動作しない場合/dev/stdinがあります(ファイルですが、検索は失敗します)
-derobert

1
@derobertとrushが少し遊んで、bashの下でプロセス置換を使用してそれを行うハックな方法を発見しました。これは依然としてシークの制限の対象であり、必要な追加のクォートすべてでは扱いにくい場合があります。次に例を示します。cat test.file | ssh user @ machine 'bash -c "wc -l <​​(cat-)"'
iruvar

4

コマンドに関係なく機能する1つの方法は、リモートファイルシステムを介してリモートマシンでファイルを使用可能にすることです。SSH接続があるため:

  1. 逆SSHトンネルを確立します。ファイルをローカルシステムに簡単にコピーするSSHも参照してください。
  2. SSHFSを使用してリモートマシンで共有するファイルを含むマシンのディレクトリツリーをマウントします。(

とにかくこの方法では、コマンドの実行前に追加の移動が必要です。
ラッシュ

@Gilles:元のタイトルは誤解を招くものだったと思いますが、誤解を招くタイトルに基づいて彼の質問を理解しました。私の知る限り、彼は実際にはしたくなかった、と思った行動上のローカルファイルが、ちょうど入力として、それを渡します。(しかし、私が正しく理解していれば、あなたの答えは素晴らしいです!たぶん、あなたが答えた質問を聞いて、答えを置く場所を与えるべきです。体と選択された答えとの整合性を保つために。
iconoclast 14

@iconoclast私がこれを書いたときの心の状態は覚えていませんが、この答えで行きます。ある程度のセットアップが必要ですが、入力をコピーするだけでは十分でない他の場合に、即時の要件を超えて一般化するという利点があります。他の誰かがそれをしなかった場合、私はまたリダイレクトについて言及したでしょう。より一般的な質問は、わずかに異なる形式で何度も尋ねられています。
ジル 'SO-悪であるのをやめる' 14

さて、あなたの答えを誤解したに違いありません。私はそれを試しませんでしたが、(リモートからローカルホストへの)リバーストンネルを確立しているので、リモートマシンによるローカルファイルの変更を許可していると推測しました。そうではありませんか?
iconoclast 14

@iconoclastはい、これにより、リモートマシンがローカルファイルを変更できるようになります(それに加えて、読み取りが可能になります)。
ジル 'SO-悪であるのをやめる' 14

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)あなただけ使用することができます(下記参照)xargscatに指定されたファイルの内容をパイプに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)"'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.