awk 입력으로 2개의 SSH 출력

awk 입력으로 2개의 SSH 출력

시험해보고 있는 두 개의 원격 서버 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) localhosthost1다시 제공됩니다 . 따라서 Host1의 내용은 두 번 테드됩니다./tmp/test/*sshlocalhosthost2cat/tmp/test/*/tmp/testcat

답변3

ssh한 가지 가능한 접근 방식은 하위 쉘에서 명령을 실행 하고 결과를 파이프하는 것입니다 awk.

(ssh username@host1 "cat /tmp/test/*"; ssh username@host2 "cat /tmp/test/*" ) | awk ‘ command ‘

관련 정보