쉘 스크립트 매개변수를 사용하시나요?

쉘 스크립트 매개변수를 사용하시나요?

다음 스크립트가 있습니다.

#!/bin/bash
if [ "$1" == "" ]
then
        echo "To start monitor, please provide the server ip:"
        read STRIP
else
        STRIP=$1
fi

ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t  | awk '{print $5 " " $1 " " $2}'"

따라서 터미널에 입력하면 다음과 같습니다.

./my_script.sh 192.168.5.210

내 포털 209에 SSH로 연결한 다음 210에 SSH로 연결하여 하드 드라이브 정보를 가져와야 합니다. 문제는 예상대로 작동하지 않고 대신 다음과 같이 5줄만 출력한다는 것입니다.

192.1680.50.21
192.1680.50.21
192.1680.50.21
192.1680.50.21
192.1680.50.21

IP를 스크립트의 변수나 echo 매개변수의 값으로 수동으로 설정하려고 했는데 제대로 작동합니까?

예를 들어 다음은 잘 작동합니다.

STRIP=192.168.5.210
ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t  | awk '{print $5 " " $1 " " $2}'"

하지만 매개변수를 사용하지 않고 전달하면 5개의 빈 줄이 표시됩니다.

답변1

따옴표는 중첩되지 않습니다. ssh원격 명령을 작은따옴표 인수가 포함된 큰따옴표 문자열로 전달하고 awk해당 인수에 큰따옴표 문자열을 여러 개 포함하려고 합니다 . 그러나 쉘은 각 큰따옴표를 큰따옴표로 묶인 문자열의 시작이나 끝으로 처리하므로 상당히 혼란스러울 수 있습니다.

특히 "df -khP | column -t | awk '{print $5 " " $1 " " $2}'"매개변수 목록에서 이를 사용 하면 ssh여러 개의 개별 따옴표로 묶인 문자열로 구문 분석됩니다. 첫 번째는 이고 "df -khP | column -t | awk '{print $5 ", $variable교체는 큰따옴표로 묶인 문자열 내에서 수행되고 스크립트는 5개의 인수를 얻지 못하므로 해당 $5부분은 아무것도 교체되지 않고 "df -khP | 열 -t | awk '{ print"가 됩니다. 다음은 " $1 "" 192.168.5.210 "으로 확장됩니다(이것이 스크립트의 첫 번째 매개변수이기 때문입니다). 마지막으로 " $2}'"두 번째 매개변수가 없으므로 "}'"로 확장됩니다. ssh그런 다음 실행 중인 명령으로 `df -khP |column -t|awk '{print 192.168.5.210}'을 제공하여 사이에 공백을 두고 붙여넣습니다. 당신이 원하는 것은 전혀 아닙니다.

이 기능이 작동하려면 큰따옴표로 묶인 단일 문자열 내의 특정 문자를 이스케이프(백슬래시 사용)해야 합니다. 특히, 모든 큰따옴표(따옴표 붙은 문자열이 끝나지 않도록 방지) 및 달러 기호(매개변수 등으로 확장되지 않도록 방지)입니다. 백틱이나 백슬래시가 있는 경우에도 이스케이프해야 합니다. 따라서 원하는 명령은 다음과 같습니다.

ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t  | awk '{print \$5 \" \" \$1 \" \" \$2}'"

그런데, 내가 올바르게 이해한다면, 이것이 인쇄되는 이유는 awk192.168.5.210을 세 개의 실수인 ​​192.168, .5 및 .210으로 구문 분석하여 인쇄하기 때문입니다(필요한 경우 앞에 0을 추가하고 뒤에 오는 0을 추가함(관련 없음)) "192.168", "0.5", "0.21"과 같습니다. 하지만 둘 사이의 공백은 인쇄하지 않으므로 "192.1680.50.21"로 표시됩니다.

관련 정보