为什么我无法运行这个脚本?

为什么我无法运行这个脚本?
$ 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"

相关内容