Bash 我应该在环境路径名中使用引号吗?

Bash 我应该在环境路径名中使用引号吗?,bash,shell,dotfiles,Bash,Shell,Dotfiles,我正在清理我所有的配置文件,以使它们尽可能可读。我一直在寻找有关导出路径时使用引号的样式指南,例如,在~/.bashrc文件中: export PATH="/users/me/path:$PATH" vs 谷歌指南建议避免在路径名中加引号。相比之下,许多流行的点文件回购协议(如扎克·霍尔曼的)都使用引号。在路径中使用引号有什么好处吗?test 123是UNIX上的有效路径名。试一试 PATH=test 123 它将返回: 123: command not found 甚至 export P

我正在清理我所有的配置文件,以使它们尽可能可读。我一直在寻找有关导出路径时使用引号的样式指南,例如,在
~/.bashrc
文件中:

export PATH="/users/me/path:$PATH"
vs


谷歌指南建议避免在路径名中加引号。相比之下,许多流行的点文件回购协议(如扎克·霍尔曼的)都使用引号。在路径中使用引号有什么好处吗?

test 123是UNIX上的有效路径名。试一试

PATH=test 123
它将返回:

123: command not found
甚至

export PATH=test 123
哪个会回来

bash export: `123': not a valid identifier
它回答了你的问题吗

老实说,我不会遵循这种第四方风格的指南。尽管我很惊讶,即使是谷歌也在宣传这样错误的建议

我谨此陈辞:

(需小心延长)

向和感谢他们的帮助

tl;dr

为了安全起见,双引号:它在所有情况下都能工作,可以跨所有类似POSIX的外壳。

如果要添加基于
~
的路径,请有选择地保留
~/
不带引号,以确保
~
已展开;e、 g.:
导出路径=~/“bin:$PATH”
。 有关变量赋值中展开的规则,请参见下文。
或者,只需在单引号字符串中使用
$HOME

export PATH=“$HOME/bin:$PATH”


注:以下内容适用于
bash
ksh
zsh
,但(大部分)不适用于严格符合POSIX的外壳,如
dash
;因此,当您以
/bin/sh
为目标时,必须双引号引用
导出的RHS
[1]

  • 只有在RHS的文字部分(要指定的值)既不包含空格也不包含其他shell元字符时,双引号才是可选的。
  • 引用的变量值是否包含空格/元字符并不重要-请参见下文。
    • 再次说明:当使用
      export
      时,它与
      sh
      有关系,因此始终在那里使用双引号
在这种情况下,不需要双引号就可以避免,原因是类似POSIX的shell中的变量赋值语句对其RHS的解释不同于传递给命令的参数,如POSIX规范的中所述:

  • 具体地说,即使执行了初始分词,它也只应用于未展开(原始)RHS(这就是为什么需要在文本中引用空格/元字符),而不应用于其结果

  • 仅适用于形式为
    =
    在所有类似POSIX的shell中
    ,即变量名之前没有命令名;请注意,这包括在命令前面添加的赋值,用于为其定义特殊环境变量,例如,
    foo=$bar cmd…

  • 为安全起见,其他命令上下文中的赋值应始终使用双引号

    • 对于
      sh
      (在(大多数情况下)严格兼容POSIX的shell中,如
      dash
      ),使用
      export
      的赋值被视为常规命令,而
      foo=$bar
      部分被视为
      export
      内置的第一个参数,因此被视为常规命令(也可根据结果进行分词)。
      (POSIX没有指定任何其他涉及(显式)变量赋值的命令;
      declare
      typeset
      local
      是非标准扩展)

    • bash
      ksh
      zsh
      ,在与POSIX的一个可以理解的偏差中,将赋值逻辑扩展到
      export foo=$bar
      typeset/declare/local foo=$bar
      。换句话说:
      bash
      ksh
      zsh
      zsh
      export/typeset/declare/local
      com命令被视为作业,因此引用不是绝对必要的

      • 也许令人惊讶的是,
        dash
        ,它也选择实现非POSIX
        local
        builtin[2] ,不将赋值逻辑扩展到它;但是,它与它的
        导出
        行为一致
    • 传递给
      env
      (例如,
      env foo=$bar cmd…
      )的赋值也会作为命令参数进行扩展,因此需要双引号-除了在
      zsh

      • env
        ksh
        bash
        中的
        export
        在这方面的作用不同,这是因为
        env
        是一个外部实用程序,而
        export
        是一个shell内置程序。
        zsh
        的行为与其他shell在未引用变量引用时的行为根本不同)
  • 在真正的赋值语句中,波浪(
    ~
    )扩展如下所示:

    • 除了需要取消引号的
      ~
      之外,它通常也只适用于:
      • 如果整个RHS为
        ~
        ;例如:
        • foo=~#与:foo=“$HOME”
      • 否则:仅当满足以下两个条件时:
        • 如果
          ~
          开始字符串或前面有一个不带引号的
        • 如果
          ~
          后面跟着一个不带引号的
          /
        • e、 g.,
          foo=~/bin#与foo=“$HOME/bin”

          foo=$foo:~/bin#与foo=“$foo:$HOME/bin”相同
示例

此示例演示了在
bash
ksh
zsh
中,即使使用
export
,您也可以避免重复引用
bash export: `123': not a valid identifier
#!/usr/bin/env bash
# or ksh or zsh - but NOT /bin/sh!

# Create env. variable with whitespace and other shell metacharacters
export FOO="b:c &|<> d"

# Extend the value - the double quotes here are optional, but ONLY 
# because the literal part, 'a:`, contains no whitespace or other shell metacharacters.
# To be safe, DO double-quote the RHS.
export FOO=a:$foo # OK - $FOO now contains 'a:b:c &|<> d'