哪种引用风格的 GNU Bash 变量定义(主要用于路径)?

哪种引用风格的 GNU Bash 变量定义(主要用于路径)?

下列哪种引用风格适合GNU 重击变量,是首选,为什么?

  1. 两个双引号: VAR="/path/$V1/path with space/$V2"
  2. 多个双引号: VAR=/path/"$V1"/"path with space"/"$V2"
  3. 组合: VAR="/path/"$V1"/path with space/"$V2""
  4. 其他

这里首选的意思是,在尽可能多的情况下按预期工作,而不会不必要地冗长,这样就可以一致使用而不会出现任何问题。如果有(罕见?)特殊情况,那么请将其限制为文件系统路径。

假设该path部分可以包含空格或特殊字符。为了2这当然意味着这些path部分也需要被引用。

基本上这似乎可以归结为另一个问题:单独引用变量替换是否会做额外的事情?

如果这是真的,那么就会激励23(以避免必须path单独用空格引用每个部分)。如果没有,那么1似乎是首选,因为它是最简单的。

然而,寻找例子这里,2迄今为止最常见,但作为特殊情况VAR="$OTHER_VAR"/path/to/something

答案1

主要的是:双引号包含任何形式的扩展或空格的所有字符串,除非你知道你可以不这样做(例如参见“什么时候需要双引号?")。是否只引用实际的位需要引用并保留引号外静态的非空白位不太重要。

我将一次一个地检查您的选择:

  1. VAR="/path/$V1/path with space/$V2"

    这是迄今为止最容易阅读的变体(个人意见)。所有变量扩展都被引用,并且字符串不会在空格上分割(因为它被引用)。我会使用这个选项。

    唯一要记住的是Sergiy Kolodyazhny 在评论中指出,如果路径名包含实际的文字双引号字符,则必须通过将其转义为\",或临时终止双引号字符串并"在单引号字符串中插入 a 来处理,如 中所示"this is a string with a "'"'" in it"。同样,对于 shell 来说特殊的其他字符(例如$and\`)在双引号字符串中也需要进行相同的处理。请注意,这是不是如果在路径名字符串中扩展的变量包含这些字符之一(将被正确处理),则会出现问题。

  2. VAR=/path/"$V1"/"path with space"/"$V2"

    这(恕我直言)看起来有点乱,但是有效。它在斜杠之间双引号所有/大多数路径组件。另一种方法可能是在不扩展变量的情况下使用单引号:

    VAR=/'path'/"$V1"/'path with space'/"$V2"
    

无论您使用第二个还是第一个选项,都取决于您和您的个人品味(或者您的团队在您正在从事的项目中使用的任何约定)。我建议您保留单一约定,如果可能的话,不要混合使用两者。

两种“引用路径名的方式”之间没有实际区别,除了可能包含 shell 特有的文字字符的路径名(它们在单引号内不会是特殊的),以及使用的引号数量

你还提到

  • VAR="$OTHER_VAR"/path/to/something

    我认为这绝对没有问题,当路径的其余部分是静态且不包含空格时,这是我最常用的。有绝对没有区别在此和之间VAR="$OTHER_VAR/path/to/something"


第三个选项:

  1. VAR="/path/"$V1"/path with space/"$V2""

    不要这样做。这里,实际上$V1$V2剩下未引用的因为您终止了变量扩展周围的双引号位。

答案2

这里的首选意思是,在尽可能多的情况下按预期工作,而无需不必要的冗长,

然后使用第一个。其他的有不需要的引号字符。你只需要两个。

如果双引号内有很多具有特殊含义的字符,即$, \,"`,那么所有必需的转义都会变得很难看。但文件名和路径并不经常包含这些内容。

单独引用变量替换是否会做额外的事情?

不,除了"$foo"bar与 相同"${foo}bar"。也就是说,您可以使用引号而不是大括号来终止变量名称。 ("$foobar"当然会完全不同。)

答案3

第一个选项看起来更可取,但(不幸的是?)不适用于路径名扩展,因为 bash 手册明确指出:

可以通过以下形式的语句将变量赋值给

    name=[value]

所有值都会经历波形符扩展、参数和变量扩展、命令替换、算术扩展和引号删除。 (...)

不执行路径名扩展。

一个重要的例子是波形符扩展:

var=~/"path/to/dir"       # tilde is expanded to user's home directory
var="~/path/to/dir"       # literal string is substituted

有趣的是,无论有没有双引号,通配机制都可以工作bash(对于默认设置来说不是这样zsh)。

相关内容