저는 Linux 터미널용 쉘 스크립트를 작성 중입니다. 프롬프트에서 변수 이름을 입력할 수 있기를 원합니다. 예를 들어:
테스트.sh:
test="Monkey in the middle..."
read -p "Enter input: " input
echo $input
산출:
Enter input: $test
$test
read -p
스크립트의 프롬프트 부분에 "$test"를 입력하고 스크립트가 지금처럼 "$test"를 에코하는 대신 끝에 "Monkey in the middle..."을 에코 하도록 할 수 있기를 바랍니다 .
어떻게 해야 하나요?
고쳐 쓰다:
여기와 여기에서 나에게 제공된 답변을 사용하여이 스레드(기여자와 평론가들에게 큰 감사를 드립니다!) 저는 다음 문장을 하나로 묶었는데, 제게는 완벽하게 맞았습니다.
newvariable="$(eval echo $input)"
eval을 사용하면 보안 위험이 발생할 수 있다는 경고를 여러 번 받았습니다. 이 솔루션을 선택할 경우 이 점을 염두에 두십시오.
답변1
바꾸다
echo "$input"
노력하다
eval echo "$input"
bash에만 국한되지 않고 /bin/sh에서 작동합니다!
이는 eval
사용자가 제공한 것만 실행하므로 심각한 보안 위험을 초래합니다. 이 경우 쉘은 문자열을 해석 $input
한 $test
다음 eval
실행합니다 echo $test
. 하지만 사용자가 입력하면 어떻게 될까요 $test; rm -rf *
? eval
렌더링됩니다 echo $test; rm -rf *
. 이렇게 하면 주의하세요.
답변2
Bash에서는 다음을 사용할 수 있습니다.간접 매개변수 확장통사론:
test="Monkey in the middle..."
read -p "Enter input: " input
echo ${!input}
이 경우 사용자는 test
달러 기호 없이 문자열만 제공하면 됩니다.
답변3
사용자가 명령 대체를 포함하여 임의의 명령을 실행할 수 있다는 점만 고려하면 내장 함수 $(…)
에 문자열을 제출할 수 있습니다 . 입력에 따옴표가 포함된 경우 구문 오류가 발생할 수 있는 셸 조각이 필요합니다 eval
. eval
따옴표를 처리하는 (상대적으로) 쉬운 방법은 여기에 있는 설명서를 사용하여 교체를 수행하는 것입니다. 종료되지 않은 변수 또는 명령 대체(예 $(foo
: )가 여전히 적용됩니다.
IFS= read -r -p "Enter input: " input
eval "string=\$(cat <<EOF
_${input}
EOF
)"
string=${string#_}