이 스크립트를 실행할 수 없는 이유는 무엇입니까?

이 스크립트를 실행할 수 없는 이유는 무엇입니까?
$ sh bashtrrrrrr 

# whats my pub. ip?
bashtrrrrrr: line 19: unexpected EOF while looking for matching `''
bashtrrrrrr: line 20: szintaktikai hiba:  váratlan fájl vég


$  cat bashtrrrrrr 
#!/bin/bash

echo '
# what's my pub. ip?
alias myip="curl -s "http://checkip.dyndns.org/" | grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | head -1"

# shorten ssh connection with tsocks
function t() { read THEIP; tsocks ssh root@$THEIP; }

# red/green terminals regarding exit code
export PROMPT_COMMAND='PS1="`
if [[ \$? = "0" ]];
then echo "\\[\\033[0;32m\\]";
else echo "\\[\\033[0;31m\\]";
fi`[\u@\h \w]\[\e[m\] "'

export PS1

' >> /home/USER/.bashrc

내가 무엇을 놓치고 있나요?

답변1

다른 답변에서 언급했듯이 문제는 중첩된 따옴표입니다.

검토해 보시길 권합니다Bash에서 참조가 작동하는 방식. 간단히 말해서, 따옴표(모든 유형, 단일 ', 이중 "또는 역따옴표`)는거의항상 동일한 유형의 참조가 처음으로 나타나는 것과 일치해야 합니다.탈출하다일치하지 않도록 따옴표를 사용합니다(그러나 작은따옴표는 이스케이프할 수 없습니다 ').

따라서 (1)의 아포스트로피는 what's작은따옴표를 다음과 같이 묶습니다 echo '.

echo '
# what's my pub. ip?

즉, echo명령이 끝나 자마자 ... ip?나머지는 bash에 의해 명령으로 실행되는데, 이는 분명히 의도한 바가 아닙니다.

~처럼라제쉬의 답변제안, 사용여기 문서많은 인용 문제를 수정했습니다.

echo >> /home/USER/.bashrc <<'__EOF__'
# what's my pub ip?
echo "we can nest quotes in here"
__EOF__

(2) 그러면, 보고된 바와 같이슈퍼소우 블레이드 답변, 해당 줄의 따옴표가 올바르게 일치하지 않습니다.

alias myip="curl -s "http://checkip.dyndns.org/" | grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | head -1"

줄의 첫 번째와 마지막(큰따옴표) 문자를 일치시키고 싶을 수도 있지만 "bash는 줄에 나타나는 순서(왼쪽에서 오른쪽)로 일치하므로 왼쪽에 있는 큰따옴표가 "http://...뒤에 오는 따옴표를 닫습니다 alias myip=". 마찬가지로, | grep -o| head -1은 다음과 같이 취급됩니다.이내에따옴표 , 그리고 http://...그리고[0-9]*\....아니요. (이 경우 백슬래시가 표시되지 않는 것 외에는 심각한 구문 결과는 없지만 grep나중에 사용할 수 있도록 이 점을 염두에 두십시오.)

한 가지 해결책은 큰따옴표(및 백슬래시를 이스케이프 처리하는 것입니다. 백슬래시는 큰따옴표 안의 특별한 의미를 잃지 않기 때문입니다):

alias myip="curl -s \"http://checkip.dyndns.org/\" | grep -o \"[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*\" | head -1"

이 경우에 작동하는 또 다른 해결 방법은 별칭을 정의하기 위해 작은따옴표를 사용하는 것입니다 '.

alias myip='curl -s "http://checkip.dyndns.org/" | grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | head -1'

또는 별칭 정의에 있는 명령의 경우:

alias myip="curl -s 'http://checkip.dyndns.org/' | grep -o '[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*' | head -1"

(3) 마지막으로 다음 줄에서:

export PROMPT_COMMAND='PS1="`
if [[ \$? = "0" ]];

'다음(작은따옴표) 문자는 PROMPT_COMMAND=한 줄로 끝나는 새로운 여러 줄 작은따옴표 문자열을 시작하는 것으로 해석됩니다.

fi`[\u@\h \w]\[\e[m\] "'

'따라서 또 다른 작은따옴표로 묶인 문자열은 마지막 줄의 문자로 시작하지만 bash는 일치하는 작은따옴표를 결코 볼 수 없습니다. 따라서 다음과 같은 오류가 발생합니다.

unexpected EOF while looking for matching `''

답변2

또한 전체 echo '...'명령을

cat  <<'EOF' >> /home/USER/.bashrc

...

EOF

많은 내부 인용문을 제거하는 데 도움이 될 수 있습니다.

답변3

그런데 이 줄에는 문제가 있습니다.

myip="curl -s "http://checkip.dyndns.org/" | grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | head -1"

bash문자열 중간에 따옴표가 있어서 혼동됩니다. "따옴표 안에 따옴표"를 넣을 때 일반적으로 다음과 같이 이스케이프 처리를 원합니다.

myip="curl -s \"http://checkip.dyndns.org/\" | grep -o \"[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\" | head -1"

관련 정보