특정 패키지가 원격 시스템에 설치되어 있는지 bash 스크립트에서 확인하려고 합니다.
컴퓨터 자체에서 다음 명령문을 실행하면 check.txt 파일의 결과는 1(설치됨)이며 이는 올바른 것입니다.
dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed" > /home/someuser/check.txt
그러나 SSH 세션에서 동일한 명령을 실행하면 결과는 항상 0입니다.
이 문제의 이유와 해결 방법을 설명할 수 있는 사람이 있습니까?
감사해요.
#!/bin/bash
ADDRESS=SOMEUSER@$SOMESERVER
function run {
ssh $ADDRESS /bin/bash $@
}
run << SSHCONNECTION
dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed" > /home/someuser/check.txt
SSHCONNECTION
답변1
스크립트를 변경하세요: run << \SSHCONNECTION
또는 dpkg-query -W -f='\${Status}' nano
. 현재 여기에 설명된 대로 로컬 셸이 확장을 시도하고 있습니다 ${Status}
(예, 작은따옴표로 묶인 경우에도 마찬가지입니다). (빈 문자열로 확장될 수 있습니다.)
첫 번째 부분은 상당히 잘 문서화되어 있습니다. POSIX쉘 명령 언어사양, 부품2.7.4 여기 문서설명하다:
형식은... ︙부분이 있다면
[n]<<word
word
참조됨...문서 줄은 여기에서 확장되어서는 안 됩니다.
︙
부품이 없는 경우word
이 인용되어 있으면 여기에 있는 문서의 모든 줄을 확장해야 합니다...
큰 타격(1)본질적으로 같은 말을합니다.
두 번째 부분은 명확하게 문서화되어 있지 않습니다. POSIX 사양의 위 문장은 계속됩니다.
부품이 없으면
word
인용할 경우 이 문서의 모든 행은 매개변수 확장, 명령 대체 및 산술 확장을 위해 확장되어야 합니다. 이 경우 입력의 <백슬래시>는 큰따옴표 안의 <백슬래시>와 동일하게 동작합니다(참조큰따옴표).
섹션에는 다음과 같은 내용도 나와 있습니다.
여기의 문서는 다음 <newline>으로 시작하여 구분 기호와 <newline>만 포함하는 줄이 있을 때까지 계속되는 한 단어로 처리되어야 합니다.
대조적으로, 일부2.3 토큰 인식설명하다:
언제io_여기토큰(예: a
<<
또는<<-
)이 문법에 의해 인식되었습니다(참조:쉘 구문), 다음 NEWLINE 태그 바로 다음에 오는 하나 이상의 후속 라인은 하나 이상의 here 문서의 본문을 형성하며 다음 규칙에 따라 구문 분석됩니다.여기 문서.처리하지 못할 때io_여기, 쉘은 아래의 첫 번째 적용 가능한 규칙을 적용하여 입력을 토큰으로 나누어야 합니다.
그런 다음 다음을 포함한 10가지 규칙을 나열하십시오.
- 현재 문자가 <백슬래시>, 작은따옴표 또는 큰따옴표이고 따옴표가 없으면 인용된 텍스트가 끝날 때까지 후속 문자의 인용에 영향을 줍니다.
따라서 여기에 있는 문서의 텍스트가 이미 큰따옴표로 묶여 있고 처리된 것처럼 거의 처리되는지 확인하려면 줄 사이를 읽어야 할 것 같습니다.오직매개변수 확장, 명령 대체, 산술 확장(및 제한된 백슬래시 처리)의 경우 설마따옴표를 삭제하는 데 사용됩니다.
또한, 그렇게 하지 않을 타당한 이유가 없고 자신이 무엇을 하고 있는지 확실히 알고 있지 않는 한 항상 쉘 변수 참조(예: "$ADDRESS"
및 )를 인용해야 합니다."$@"