시험해보고 있는 두 개의 원격 서버 ssh
와 일부 파일이 있습니다. ssh의 출력을 명령 cat
에 공급하고 싶습니다 .awk
이게 내가 가진 거야
ssh username@host1 “cat /tmp/test/*” ssh username@host2 “cat /tmp/test/*” | awk ‘ command ‘
그러나 이것은 작동하지 않습니다. host2
디렉토리가 비어 있으면 출력이 host1
두 번 반복됩니다.
내가 여기서 뭘 잘못하고 있는 걸까?
답변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의 내용은 두 번 테드됩니다./tmp/test/*
ssh
localhost
host2
cat
/tmp/test/*
/tmp/test
cat
답변3
ssh
한 가지 가능한 접근 방식은 하위 쉘에서 명령을 실행 하고 결과를 파이프하는 것입니다 awk
.
(ssh username@host1 "cat /tmp/test/*"; ssh username@host2 "cat /tmp/test/*" ) | awk ‘ command ‘