試している2つのリモートサーバーssh
といくつかのファイルがあります。 sshの出力をコマンドcat
に供給したいと思います。awk
これは私が持っているものです。
ssh username@host1 “cat /tmp/test/*” ssh username@host2 “cat /tmp/test/*” | awk ‘ command ‘
しかし、これはうまくいきません。host2
ディレクトリが空の場合、出力はhost1
2回繰り返されます。
私がここで何を間違っているのか?
答え1
これらに注意してくださいカール引用符(“
および”
)一部のWindowsテキストエディタでは、真の引用符('
または"
)を使用します。変数の拡張など、sを'
使用する理由がない限り、sを使用する必要があります。"
https://mywiki.wooledge.org/Quotes。
awkパイプが必要な場合は、次のことを行う必要があります。
{ ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*'; } | awk ' command '
ただし、後でこれらの区別が必要な場合に備えて、awkが入力がどのコマンドから来たのかを区別できるようにすることを検討してください。
awk ' command ' <(ssh username@host1 'cat /tmp/test/*') <(ssh username@host2 'cat /tmp/test/*')
違いは次のとおりです。
$ seq 3 > file1
$ seq 2 > file2
無効な出力(FILENAME
常に含まれてい-
てARGV[1..2]
空であるため):
$ { cat file1; cat file2; } | awk '
FILENAME == ARGV[1] { host="host1" }
FILENAME == ARGV[2] { host="host2" }
{ print host, $0 }
'
1
2
3
1
2
無効な出力(同じ一時ファイル記述子が含まれているがFILENAME
空であるため):ARGV[1]
ARGV[2]
$ awk '
FILENAME == ARGV[1] { host="host1" }
FILENAME == ARGV[2] { host="host2" }
{ print host, $0 }
' <(cat file1; cat file2)
host1 1
host1 2
host1 3
host1 1
host1 2
正しい出力:
$ awk '
FILENAME == ARGV[1] { host="host1" }
FILENAME == ARGV[2] { host="host2" }
{ print host, $0 }
' <(cat file1) <(cat file2)
host1 1
host1 2
host1 3
host2 1
host2 2
この入力を提供する方法から正しい出力を取得する他の可能な方法は次のとおりです。
$ awk '{print host, $0}' host='host1' <(cat file1) host='host2' <(cat file2)
host1 1
host1 2
host1 3
host2 1
host2 2
答え2
コマンドをグループ化する必要があります。最も簡単な方法は、サブシェルを作成せずに中括弧を使用してグループ化することです。
{ ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*'; } |
awk ' command '
かっこを使用することもできますが、これは不要なサブシェルを生成するため、少しエレガントではありません。ただし、最終結果は同じであり、この場合実際には違いはありません。また、;
次のようにエンディングを追加する必要はありません{ }
。
( ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*' ) |
awk ' command '
重複した出力が表示されるのは、両方のコマンドがcat
同じホストで実行されるためです。localhost
両方のコマンドでホストとして使用され、実行後に出力を確認してくださいset -x
。
$ ls /tmp/test
file1
$ ssh localhost "cat /tmp/test/*" ssh localhost "cat /tmp/test/*"
+ ssh localhost 'cat /tmp/test/*' ssh localhost 'cat /tmp/test/*'
/tmp/test/file1
/tmp/test/file1
cat: ssh: Is a directory
cat: localhost: No such file or directory
cat: cat: No such file or directory
上記のように、これは "ssh localhost cat arg1 arg2 arg3 arg4"と解釈されるため、on(あなたの場合)を実行し、引数として、(あなたの場合cat
)localhost
、そしてhost1
再度提供されます。したがって、Host1の内容は2回テッドされます。/tmp/test/*
ssh
localhost
host2
cat
/tmp/test/*
/tmp/test
cat
答え3
ssh
1つの可能なアプローチは、サブシェルでコマンドを実行して結果をパイプすることですawk
。
(ssh username@host1 "cat /tmp/test/*"; ssh username@host2 "cat /tmp/test/*" ) | awk ‘ command ‘