나는 이것이 불가능하다고 확신하지만 과거에는 틀렸습니다.
기본적으로 내가 원하는 것은 컬 명령의 JSON 출력을 가져와서 jq로 파이프하여 깔끔하게 유지하는 것입니다. 좋은 결과. 하지만 OSX에는 이 기능이 없으므로 Brew나 다른 방법을 통해 설치해야 합니다. 나에게는 문제가 되지 않습니다. 그러나 기업 환경에서는 타사 애플리케이션을 설치하는 것이 눈살을 찌푸리게 합니다. 그러나 다수의 Linux 서버에는 jq가 설치되어 있습니다.
jq를 실행하기 위해 로컬 출력을 ssh로 파이프할 수 있습니까?
curl https://whatever.site/json | ssh linuxHost "jq '.'" > output.json
많은 수의 Linux 서버에는 외부 액세스 권한이 없으므로 그곳에서 컬 명령을 실행하면 작동하지 않는다는 점에 유의하는 것이 중요합니다. 예, scp를 만들 수 있지만 더 많은 단계가 있습니다.
답변1
당신이 하고 싶은 게 전부라면아름다운 인쇄JSON 문서(고급 필터링, 집계 또는 기타 항목 제외)를 사용하면 macOS 기본 시스템 유틸리티의 더 간단한 유틸리티인 json_pp
( )를 사용할 수 있습니다 . /usr/bin/json_pp
이 json_pp
유틸리티는 Perl 모듈용 명령줄 래퍼입니다 JSON::PP
.
$ echo '{ "hello": "world!" }' | json_pp
{
"hello" : "world!"
}
man json_pp
사용자 정의 출력 형식( -json_opt
옵션) 에 대한 설명은 참고자료를 참조하세요 .
예:
$ echo '{ "hello": "world!" }' | json_pp -json_opt pretty,indent_length=2,space_before=0
{
"hello": "world!"
}
답변2
예, ssh
명령을 실행 하는 경우 모드 대신에 ssh
가상 터미널의 원격 시스템에서 사용자 로그인 셸을 실행하는 대신 세 가지 다른 파이프라인에 연결된 stdin, stdout 및 stderr을 사용하여 지정된 명령을 실행합니다.rsh
rlogin
sshd
이러한 파이프의 내용은 암호화된 터널을 통해 전송되며 프로세스의 stdin, stdout 및 stderr에서 읽거나 씁니다 ssh
.
그래서:
local-cmd | ssh 'remote-cmd' > file
ssh
stdin은local-cmd
기록되는 파이프를 읽는 것입니다.ssh
표준 출력은file
쓰기 전용 모드로 열립니다.ssh
터미널에서 실행하는 경우 stderr은 아마도 터미널 장치일 것입니다.
그리고
- 표준 입력의 판독값은
ssh
암호화된 채널을 통해 전송되어remote-cmd
입력으로 파이프됩니다. - 표준 출력의 파이프에 기록된 내용은
remote-cmd
암호화된 채널을 통해 전송되고sshd
(해당 파이프의 다른 쪽 끝에서 읽음)ssh
수신 시 표준 출력에 기록됩니다. 즉, 파일에 기록됩니다. remote-cmd
별도의 파이프에서 stderr과 동일합니다.
lsof를 사용하여 이를 관찰할 수 있습니다.
$ sleep 3 | ((sleep 1; lsof -wc ssh -ad 0-99 +E >&2) <&- & ssh [email protected] 'lsof -wp "$$" -ad 0-2 +E; sleep 2') > file
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
screen 7561 chazelas 9u CHR 5,2 0t0 89 /dev/ptmx ->/dev/pts/5 63562,zsh,0u 63562,zsh,1u 63562,zsh,2u 63562,zsh,10u 63608,sleep,0u 63608,sleep,2u 63609,ssh,2u 63609,ssh,6u 63610,lsof,1u 63610,lsof,2u
sleep 63608 chazelas 1w FIFO 0,14 0t0 698683 pipe 63609,ssh,0r 63609,ssh,4r
ssh 63609 chazelas 0r FIFO 0,14 0t0 698683 pipe 63608,sleep,1w 63609,ssh,4r
ssh 63609 chazelas 1u CHR 1,3 0t0 5 /dev/null
ssh 63609 chazelas 2u CHR 136,5 0t0 8 /dev/pts/5 7561,screen,9u
ssh 63609 chazelas 3u IPv4 697921 0t0 TCP localhost:50006->localhost:ssh (ESTABLISHED)
ssh 63609 chazelas 4r FIFO 0,14 0t0 698683 pipe 63608,sleep,1w 63609,ssh,0r
ssh 63609 chazelas 5w REG 0,39 540 8488375 /home/chazelas/file
ssh 63609 chazelas 6u CHR 136,5 0t0 8 /dev/pts/5 7561,screen,9u
~$ cat file
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 63612 root 5w FIFO 0,14 0t0 698269 pipe 63692,bash,0r 63695,lsof,0r
sshd 63612 root 7r FIFO 0,14 0t0 698270 pipe 63692,bash,1w 63695,lsof,1w
sshd 63612 root 10r FIFO 0,14 0t0 698271 pipe 63692,bash,2w 63695,lsof,2w
bash 63692 root 0r FIFO 0,14 0t0 698269 pipe 63612,sshd,5w
bash 63692 root 1w FIFO 0,14 0t0 698270 pipe 63612,sshd,7r
bash 63692 root 2w FIFO 0,14 0t0 698271 pipe 63612,sshd,10r
ssh
fds 4와 5(fds 0과 1에서 복사됨)가 각각 절전 모드에서 파이프로 들어오는 것을 볼 수 있으며 file
, 원격 측(출력이 lsof
나타나는 곳 file
)에서 원격의 fds 0, 1, 2 쉘에는 3개의 다른 쉘이 있습니다. 파이프는 모두 sshd
.
따라서 이러한 방식으로 실행은 표준 IO의 경우 ssh cmd
로컬 실행과 기능적으로 유사 cmd
하지만 여전히 주목해야 할 몇 가지 사항이 있습니다.
- 위에 표시된 대로
cmd
원격 시스템의 stdin/stdout/stderr은ssh
클라이언트에서의 목적(예: 이 예에서는 각각 파이프, 일반 파일 및 tty 장치)에 관계없이 모두 파이프입니다. 예를 들어 로 리디렉션하지 않는 경우 출력 이 tty 장치로 이동할 때만 색상이 지정되므로 출력에 색상이 지정되지 않은 것을file
알 수 있습니다 .jq
jq
ssh
원격 호스트에서 읽혔는지 여부 에 관계없이 stdin에서 출력을 소비하고 sshd로 보냅니다.cmd
예를 들어 원격 명령이 한 줄만 읽었음에도 불구하고 to의 전체 출력이 전송되었으므로seq 1000 | (ssh localhost 'IFS= read -r one_line_only'; cat)
아무 것도 출력되지 않습니다 (대부분의 이유는 읽히지 않음) 읽을 것이 없습니다.read
ssh
seq
sshd
read
cat
여기서도 다음을 수행할 수 있습니다.
curl... | ssh 'jq . > remotefile'
원격 출력은 jq
원격 파일(원격 사용자의 홈 디렉터리)에 저장됩니다. 또는:
curl... | ssh 'jq . | tee remotefile' > localfile
(또는 단순히 curl | ssh 'jq >&1 > remotefile' > localfile
원격 사용자의 로그인 셸이 zsh인 경우) 출력이 jq
로컬 및 원격으로 저장됩니다.
적어도 openssh의 경우에는stdin과 stdout이 다른 fd에서 반복됩니다.어떤 것이 사용되고 있으며표준 출력은 다음에 다시 열립니다./dev/null
, 그러나 이는 구현 세부 사항이며 실제로는 아무런 차이가 없습니다.