base64로 인코딩된 bash 스크립트를 실행하면 오류가 발생합니다.

base64로 인코딩된 bash 스크립트를 실행하면 오류가 발생합니다.

나는 bash 스크립트를 가지고 있습니다. 스크립트는 임의의 숫자를 생성하고 사용자가 그것을 추측할 수 있게 합니다.

printf 'Guess the number (1-10) : '
read -r n
randint=$(( ( RANDOM % 10 )  + 1 ))
if [ $n = $randint ];
then
echo "You Won !"
else
echo "Sorry, try again !"
fi

작동하지만 다음 스크립트에서는 이 코드를 base64로 인코딩하고 다음 코드를 사용하여 실행해 보았습니다.

exec="cHJpbnRmICdHdWVzcyB0aGUgbnVtYmVyICgxLTEwKSA6ICcKcmVhZCAtciBuCnJhbmRpbnQ9JCgoICggUkFORE9NICUgMTAgKSAgKyAxICkpCgppZiBbICRuID0gJHJhbmRpbnQgXTsKdGhlbgplY2hvICJZb3UgV29uICEiCmVsc2UKZWNobyAiU29ycnksIHRyeSBhZ2FpbiAhIgpmaQ=="
base64 -d <<< $exec | sh

Cygwin 터미널에서 다음 오류가 발생합니다.

Guess the number (1-10) : sh: line 4: [: too many arguments
Sorry, try again !

온라인 컴파일러를 사용해 보았지만 역시 실패했습니다.

sh: 5: [: =: unexpected operator

이 문제를 해결하는 방법을 모르겠습니다.

답변1

이를 실행하여 set -x쉘이 실제로 실행되는 내용을 확인하십시오. 명령은 다음으로 시작하는 줄에 나타납니다 +.

+ printf 'Guess the number (1-10) : '
Guess the number (1-10) : + read -r n
+ '[' 'randint=$((' '(' RANDOM % 10 ')' + 1 '))' = ']'
bash: line 4: [: too many arguments
[...]

시험의 [ ... ]과제 (*)에는 무엇이 있나요 randint=...? 그것은 주어져야 한다 read n. 사용자에게 번호를 물어봐야 하는데 그렇지 않나요?

글쎄요, 한 가지, readstdin에서 읽는 것과 쉘이 파이프에서 실행하는 스크립트 base64 ... | bash도 stdin에서 나옵니다. 따라서 read입력 스트림의 다음 줄( randint=......이 있는 줄)을 충실히 읽고 변수에 넣습니다 n.

(물론 *는 참조가 없기 $n때문에 여러 개의 매개변수로 나누어집니다 .)$n

다른 파일 설명자에서 스크립트가 들어오도록 준비해야 합니다. 예를 들어 프로세스 대체를 사용하여 스크립트를 쉘(Bash/ksh/zsh)에 전달합니다.

bash <( base64 -d <<< "$exec" )

또는 read입력을 from 으로 리디렉션하여 read터미널에서 직접 읽는 것과 같이 다른 fd에서 읽습니다 /dev/tty. 거의 한 줄을 사용하여 테스트합니다. 작은 따옴표로 묶인 문자열은 두 번째 줄까지 이어집니다.

$ printf 'read -r -p "say something: " foo < /dev/tty; 
          echo "you entered: $foo"' | bash
say something: asdfsadf
you entered: asdfsadf

그런 다음 대화형으로 요청하는 대신 입력 데이터를 명령줄 인수로 전달하는 것을 고려할 수도 있습니다. 명령줄 인수는 스크립트하기가 더 쉽고, 터미널을 직접 읽는 것도 특히 짜증나는 일입니다. 프로그램을 제공하기 위해 스크립트를 쉽게 사용할 수 없기 때문입니다.

또한 이는 표준 셸 기능이 아니므로 RANDOM스크립트를 명시적으로 실행하는 대신 (또는 또는)을 사용해야 할 수도 있습니다.bashkshzshsh

관련 정보