【问题标题】:Inconsistent behavior when replacing substring with tilde "~" in a BASH parameter expansion在 BASH 参数扩展中用波浪号“~”替换子字符串时的行为不一致
【发布时间】:2018-06-13 16:10:06
【问题描述】:

在尝试编写快速函数时,我在几个不同服务器上的 BASH 参数扩展中遇到了一些奇怪的不一致行为。

在某些版本的 BASH 上,要在子字符串替换中使用波浪号,波浪号必须被转义,否则它将重新展开到主目录:

foo=~/data # ~ is expanded to $HOME
bar1="${foo/#$HOME/\~}" # returns ~/data
bar2="${foo/#$HOME/"~"}" # returns ~/data
bar3="${foo/#$HOME/~}" # returns /home/user/data

而在其他系统上,它不会被重新扩展,并且尝试转义波浪号会将文字转义字符添加到字符串中:

foo=~/data # ~ is expanded to $HOME
bar1="${foo/#$HOME/\~}" # returns \~/data
bar2="${foo/#$HOME/"~"}" # returns "~"/data
bar3="${foo/#$HOME/~}" # returns ~/data

请注意,我的目标是插入文字字符串“~”。


无需转义的 BASH 版本在这里:

GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.3.0)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

需要转义的 BASH 版本在这里:

GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

那到底是怎么回事?

【问题讨论】:

  • 听起来他们认为这是 4.2 中的错误,在 4.3 中修复了它,然后确定原件是正确的并将其放回 4.4。

标签: linux bash shell sh bash4


【解决方案1】:

eval 是另一种选择。

eval bar1="${foo/#$HOME/\~}"
eval bar2="${foo/#$HOME/"~"}"
eval bar3="${foo/#$HOME/~}"

现在你得到/home/foo/data 用于所有三种情况。

【讨论】:

  • 您不加解释的投反对票非常有帮助:)
  • 不是我,伙计。
  • @LukeDavis 我知道你不是 :)
【解决方案2】:

@iBug 发布了如何确保我们始终扩展波浪号。为确保我们始终在任何系统上获取波浪字符本身,请使用以下命令:

bar="${foo/#$HOME/~}" # returns ~/data or /home/user/data
[[ "$bar" =~ "$HOME"* ]] && bar="${foo/#$HOME/\~}"

仅当原始的非转义代字号被展开时,才用转义代字号重做替换。

【讨论】:

    猜你喜欢
    • 2011-06-06
    • 2015-04-28
    • 2016-11-05
    • 2019-01-13
    • 1970-01-01
    • 2013-03-29
    • 2015-04-07
    • 2012-08-27
    • 1970-01-01
    相关资源
    最近更新 更多