SSH를 통해 명령을 실행할 수 없습니다

SSH를 통해 명령을 실행할 수 없습니다

FreeBSD 시스템(xxx.yyy.zzz.net)에서 명령을 실행하고 출력을 받고 있습니다.

명령

sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done

산출

media RPM             non-rotating
media RPM             non-rotating
media RPM             non-rotating

다른 컴퓨터에서 SSH를 사용하여 동일한 명령을 실행하려고 합니다.

명령

ssh xxx.yyy.zzz.net sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done

오류

sudo: camcontrol: command not found

답변1

명령에서 모든 것은 |로컬 셸에 의해 해석됩니다. 마지막 인수 ssh는 입니다 devlist. ssh로컬에서 호출되지만(놀랍지 않습니다) 첫 번째 이후의 모든 항목도 마찬가지입니다 |.

발생한 오류는 sudo이 스니펫에서 발생했습니다 do sudo camcontrol identify $a. 로컬로 실행되며 camcontrol로컬 컴퓨터에서는 사용할 수 없는 것 같습니다.

적절한 이스케이프 또는 인용이 필요합니다. 이 경우 전체 원격 명령을 작은따옴표로 묶을 수 있습니다.

ssh xxx.yyy.zzz.net 'sudo camcontrol devlist | grep -o "ada[0-9]" | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done'

참고 이미 가지고 있는 작은따옴표를 변경했습니다. (추가된) 작은따옴표는 전체 문자열을 그룹화할 뿐만 아니라 ssh이를 가져옵니다. 또한 $a.

sudo비밀번호를 요청하려면 의사 터미널이 필요합니다 . -t옵션을 사용하여 의사 터미널 할당을 강제로 수행할 수 있습니다 ssh(따라서 처럼 보입니다 ssh -t xxx.yyy.zzz.net …). Note는 ssh -t원격 측에 의사 터미널을 할당합니다. 원격은 sudostderr에 대한 프롬프트를 표시하지만 stdout과 stderr은 이 의사 터미널에 의해 "인쇄"되며(일반적으로 콘솔에 인쇄되는 것처럼) 이 시점에서는 더 이상 구별할 수 없습니다. 병합된 스트림은 캡처되어 stdout으로 이동하는 로컬 측으로 전송됩니다. 원격 stdout 및 stderr이 별도로 전송 되지 않으면 -t로컬 측의 stdout 및 stderr로 이동하면 결국 표시되는 내용으로 병합됩니다(또는 리디렉션되는 경우에는 병합되지 않음). 이는 -t로컬 측에서 원격 stderr과 원격 stdout을 구별할 수 없음을 의미합니다. 출력을 로컬에서 추가로 처리(리디렉션)해야 하고 사용하는 -t경우 프롬프트가 sudo방해됩니다.

$a또한 (를 사용하지 않는 첫 번째 명령에서도 ) 큰따옴표를 사용하고 싶을 수도 있습니다 ssh. 보다쉘 스크립트가 공백이나 기타 특수 문자로 인해 막히는 이유는 무엇입니까?

관련 정보