使用单引号作为变量值时,在Bash中如何使用单引号?

3
我有以下脚本(用于从外部服务获取我的当前IP):
#!/bin/bash
####################################################################
# Gets the public IP address of current server
####################################################################

cmd='curl -s'
#cmd='wget -q -O'
#cmd='lynx -dump'

ipservice=checkip.dyndns.org

pipecmd="sed -e 's/.*Current IP Address: //' -e 's/<.*\$//'"

# Run command
echo $($cmd $ipservice | $pipecmd)

但是sed命令报错:
sed: -e expression #1, char 1: unknown command: `''

我一直在谷歌上搜索如何在变量中使用单引号,但没有成功。

谢谢!

2个回答

5

这个命令被分解成诸如sed, -e, 's/.*Current, IP, Address:, //'等的单词。因此,sed程序中的第一个命令确实以'开头,这不是有效的sed命令。请使用数组和引用代替:

cmd=(curl -s)
pipecmd=(sed -e 's/.*Current IP Address: //' -e 's/<.*$//')
"${cmd[@]}" "$ipservice" | "${pipecmd[@]}"

请注意,echo "$(command)"command等效。通常情况下,请确保始终引用所有变量(虽然有一些例外)。

谢谢!它执行了命令,但由于某种原因,sed提取并没有按照需要的方式工作(我得到的不仅是IP地址,还有尾随内容)。 - yorch
@yorch:可能需要对美元符号进行反转义(除非结果文本包含一个字面的美元符号)。 - Philipp

3
你需要使用 eval 使 shell 解释变量的内容。
echo $($cmd $ipservice | eval $pipecmd)

由于额外的求值,您可能需要进行额外的转义,尽管在这种特殊情况下,我认为现状是可以接受的。


1
Eval不是邪恶的。Eval意味着“将此字符串视为要执行的shell源代码”。但这正是您编写脚本时已经在做的事情。只需确保您控制您eval的任何内容,就像它是您正在编写的代码一样。 - Kaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接