환경 변수는 명령줄 인수 내에서 확장되지 않습니다.

환경 변수는 명령줄 인수 내에서 확장되지 않습니다.

user-pid.out2"사용자 ID"와 "프로세스 ID"가 두 개의 열로 구성된 파일이 있습니다 . 사용자 번호를 기반으로 해당 프로세스 ID를 찾고 싶습니다. 아래 처음 두 줄은 올바른 출력을 표시하지 않지만, 3행과 4행에서 사용자를 62로 하드코딩하면 사용자 62에 해당하는 프로세스 ID가 표시됩니다. 누구든지 도와줄 수 있나요?

USR=62
usrpid=`awk '$1 == "$USR" {print $2}' /home/hu/batchhu/dbscripts_tst2/user-pid.out2`
echo "first:" $USR $usrpid
# This shows 62 and blank for process id

usrpid=`awk '$1 == "62" {print $2}' /home/hu/batchhu/dbscripts_tst2/user-pid.out2`
echo  "second:" $USR $usrpid
# This shows 62 and process id corresponding to this user in the file user-pid.out2

답변1

@artm은 awk 스크립트를 큰따옴표로 묶고 다양한 문자를 이스케이프하는 기술을 시연했습니다. 여기에 3가지 기술이 더 있습니다.

쉘이 변수를 확장할 수 있도록 작은따옴표를 분리합니다.

usrpid=$(awk '$1 == "'"$USR"'" {print $2}' file)

쉘 변수를 awk 변수에 전달

usrpid=$(awk -v usr="$USR" '$1 == usr {print $2}' file)

변수를 내보내는 경우 awk의 ENVIRON 배열을 사용하십시오.

usrpid=$(awk '$1 == ENVIRON["USR"] {print $2}' file)

후자를 선호해야 합니다.

@artm의 접근 방식과 같은 첫 번째 접근 방식에서는 쉘 변수의 내용이 코드에 포함되어 있습니다 awk.명령 주입 취약점변수의 내용이 엄격하게 제어되지 않는 경우(예: 를 사용하여 ) USR='blah" || system("reboot") || "'호출됩니다 reboot.

두 번째는 명령 주입 취약점을 유발하지 않지만 백슬래시 문자가 포함된 경우 C와 유사한 백슬래시 이스케이프 시퀀스가 ​​확장되므로 $USR변수에 셸 변수와 동일한 내용이 포함되지 않습니다 .usr awk$USRawk

사용시 ENVIRON그런 문제는 없습니다 .

답변2

첫 번째 예의 는 "$USR"작은따옴표로 묶인 문자열 안에 나타나기 때문에 확장되지 않습니다 '$1 == "$USR" { print $2 }'. 따라서 이 코드는 첫 번째 열이 62가 아닌 "$USR"인 줄을 찾습니다.

다음이 작동합니다.

usrpid=$(awk "\$1 == \"$USR\" {print \$2}" /home/hu/batchhu/dbscripts_tst2/user-pid.out2)

다양성:

  1. awk 명령줄은 큰따옴표를 사용하므로 $USR이 확장됩니다.
  2. awk 프로그램에서 달러 기호와 따옴표 문자가 이스케이프됩니다.
  3. $()백틱 대신 사용하십시오.백슬래시가 올바르게 처리됩니다.

의 값은 USRawk 스크립트에 직접 삽입되므로 awk가 문자 그대로 해석할 문자만 값에 포함된 경우에만 작동합니다. 또는 가 $USR포함된 경우 모든 것이 분해됩니다.  이는 awk 문자열 리터럴 끝이 됩니다. 다음 문자를 인용합니다.\""\

관련 정보