【问题标题】:Stop bash from escaping a string inside a string阻止 bash 在字符串中转义字符串
【发布时间】:2012-11-19 02:11:31
【问题描述】:

我一直在搞乱.bashrc,试图获得一个新的彩色PS1,如果我使用的是Python virtualenv,它可以自动告诉我。我对 Bash 非常非常陌生,所以经过一些研究后,我创建了这样的东西(为了清晰起见进行了简化):

function virtualenv {
    if [ -n "$VIRTUAL_ENV" ]; then
        VIRTUAL=" $BLACK($GREEN`basename $VIRTUAL_ENV`$BLACK)"
    else
        VIRTUAL=""
    fi
}

PS1="$BLUE\u@\h\$VIRTUAL $YELLOW\\$ $RESET"

希望$BLACK$GREEN 变量会在PS1 中解释,但我得到了这样的结果:

gabe@notebook \e[30m(\e[32mmyproject\e[30m) $

好像 Bash 正在独自转义我的整个 VIRTUAL 变量...我已经尝试了我有限技能所允许的斜线、引号和命令的所有组合...有什么帮助吗?

【问题讨论】:

  • 查看 Bash Hackers Wiki 上的引用和转义:wiki.bash-hackers.org/syntax/quoting 您需要在颜色字符串上加上单引号。
  • @ReubenMorais 我刚刚在颜色字符串 ($BLUE) 和 $VIRTUAL 变量中尝试了不同的单引号组合。我得到相同的结果或像 gabe@notebook $BLACK($GREENmyproject$BLACK) 这样的文字表示
  • 什么版本的 bash?如果是 pre-4.x,那么它不理解 \e 转义;您必须改用\033(或\x1b,或通过键入control-V 输入的文字转义,或...)。
  • @MarkReed bash 版本 4.2.24。其他彩色文本工作正常,只是设置在不同变量中的那些行为不端
  • 您的括号可能被解释为对子外壳的调用。现在试着把它们拿出来。此外,进一步简化您的测试。看看你是否不能先让一种颜色起作用。正如 Gabe 所说,单引号应该保护那些变量值。在此处搜索堆栈溢出以查找[bash] prompt problems,因为这类问题经常被问到。 (你的项目比大多数项目更有趣!)。祝大家好运。

标签: bash ps1


【解决方案1】:

你在这里转义了美元符号:\$VIRTUAL,因此$VIRTUAL 在分配给PS1 时不会被扩展(因为它变成了文字$,你看)。

因此,$VIRTUAL 仅在生成提示时才会展开,这就是为什么您看到的不是 formatting 而是定义格式的 字符串

基本上你只需要在分配给PS1时去掉\$VIRTUAL中的\

【讨论】:

  • 我试过了,但忘了提及...我正在使用该反斜杠来让 \$VIRTUAL 每次都被评估(我学到的一个技巧here)。如果我删除它,着色工作,但变量内容不会更新,直到我再次加载 bashrc(或重新打开终端)
  • @Gabe 如果您不重新运行 virtual 函数以赋予其新值,那么每次评估 $VIRTUAL 并没有任何好处。
【解决方案2】:

首先——virtualenv 函数不会像你那样被调用。在PS1 评估期间,以下内容实际上调用了您的函数(最好不要命名为virtualenv):

function virtualenv_prompt {
    [[ -n $VIRTUAL_ENV ]] && \
      printf %s " $BLACK($GREEN"'$(basename "$VIRTUAL_ENV"'"$BLACK)"
}

PS1="$BLUE\u@\h"'$(virtualenv_prompt)'" $YELLOW\\$ $RESET"

也就是说,这仍然无法按您想要的方式工作,因为需要直接包含 \[\] 转义(有必要防止外壳将颜色代码计算为打印字符以进行换行)在PS1,不能被替换。

为了使它正确,您不仅需要添加此类转义符(如果它们尚未在代码定义中),还需要将颜色代码移出 virtualenv 函数并让它们无条件存在(即使颜色在没有可见内容的情况下来回切换)。另见http://mywiki.wooledge.org/BashFAQ/053

【讨论】:

    【解决方案3】:

    当您将字符串括在单引号中时,您可以防止 bash 替换字符串中的变量

    VIRTUAL=' $BLACK($GREEN`basename $VIRTUAL_ENV`$BLACK)'
    

    这会将字符串按原样存储在变量VIRTUAL 中。如果你想替换它的一部分,你必须关闭单引号并将替换部分嵌入到双引号中

    A=x
    B=y
    C=z
    
    V='$A$B$C'
    W='$A'"$B"'$C'
    

    V 保留为$A$B$C,将W 保留为$Ay$C

    【讨论】:

    • W='$A'"$B"'$C'(保持 $B 引用以防止分词和全局扩展)将是更安全的做法。
    • @CharlesDuffy 谢谢,已修复。
    猜你喜欢
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 2020-02-24
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多