bash中双引号字符串中的单引号不值得尊敬

时间:2016-10-17 18:19:31

标签: bash shell variables terminal

我正在尝试在bash中分配一个变量:

assignssid="airport -I | awk '/ SSID/ {print substr($0, index($0, $2))}'"

当我目前这样做,然后运行echo "$assignssid"时,结果如下:

airport -I | awk '/ SSID/ {print substr(-bash, index(-bash, ))}'

如何让变量与引号内的代码一起使用?

3 个答案:

答案 0 :(得分:4)

问题:单引号在双引号中不是句法

当你有"'$0'"时,只有那些外部引号是语法的(并控制shell如何扩展值:内部引号只是文字值,并且不会改变$0的处理方式。

字面答案(仅限bash):$''

如果您不希望兑换扩展,请不要使用双引号。

# assign the directory separately, just to make the line shorter for easier reading
dir=/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/

# now, expand the directory name in double quotes, but use the $'' quoting style otherwise
assignssid="$dir"$'airport -I | awk \'/ SSID/ {print substr($0, index($0, $2))}\''

$''内,\'是一个文字单引号(同样,\n是换行符,\t是标签符号等),并且不会发生参数扩展($'$0''$0'相同,而非"$0")。

执行此操作后,您可以看到echo变量发出命令,单引号内容保持不变:

$ echo "$assignssid"
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | awk '/ SSID/ {print substr($0, index($0, $2))}'

...或者,与你想象中的用例更密切相关:

current_ssid=$(eval "$assignssid")

字面答案(POSIX sh):'"'"'

让我们以 bash-only的方式做第一个答案:

dir=/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/
assignssid="$dir"'airport -I | awk '"'"'/ SSID/ {print substr($0, index($0, $2))}'"'"''

此字符串的作用如下:

  • 第一个'关闭单引号上下文
  • 第一个"打开双引号上下文
  • 以下'是字面意义,因此成为您价值的一部分
  • 以下"关闭双引号上下文
  • 最终'恢复原始单引号上下文

最佳实践答案:使用函数存储代码

字符串变量根本不适合此作业。相反,使用函数:

airport_dir=/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/
assignssid() {
    "$airport_dir"/airport -I | awk '/ SSID/ {print substr($0, index($0, $2))}'
}

......之后:

current_ssid=$(assignssid)

答案 1 :(得分:2)

你可以分享和征服" 让我们将(非常)长目录放在一个变量中:

$ dir="/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources"

让我们把awk命令放在第二个变量中:

$ awkcmd='/ SSID/ {print substr($0, index($0, $2))}'

由于文字在单引号内,因此$0$2不会被外壳展开。

然后,让我们加入你想要的变量:

$ assignssid="$dir/airport -I | awk '$awkcmd'"

在这种情况下单引号起作用(出现在assignssid变量中),因为它们在双引号内使用。

而且,我假设您要执行的是:

$ eval "$assignssid"

以上内容适用于任何(合理的)shell。

答案 2 :(得分:0)

感谢所有人的贡献。我想我发现了一种不同的方式 var = $(/ System / Library / PrivateFrameworks / Apple80211.framework / Versions / Current / Resources / airport -I | awk' / SSID / {print substr($ 0,index($ 0,$ 2))}&#39 ;)