环境。变量与“和没有”的回显不同

环境。变量与“和没有”的回显不同

我正在学习 bash shell 和环境变量。

我已经测试了 echo a env。 var 用引号括起来,没有它们(我把它放在我的终端上):

user@pc:~$ echo "$BASE_DEPENDENCIES"
build-essential \
                   cmake           \
                   debhelper       \
                   mesa-utils      \
                   cppcheck        \
                   xsltproc        \
                   python-psutil   \
                   python          \
                   bc              \
                   netcat-openbsd  \
                   gnupg2          \
                   net-tools       \
                   locales
user@pc:~$ echo $BASE_DEPENDENCIES
build-essential \ cmake \ debhelper \ mesa-utils \ cppcheck \ xsltproc \ python-psutil \ python \ bc \ netcat-openbsd \ gnupg2 \ net-tools \ locales

第一个有新的线条和空间。第二个只有一行。

为什么会发生这种情况?

顺便说一下,我的系统是Ubuntu 17.04。

答案1

有一个扩展顺序bash 对输入执行的操作:

展开的顺序是:大括号展开;波形符扩展、参数和变量扩展、算术扩展和命令替换(以从左到右的方式完成);分词;和文件名扩展。

未加引号的版本允许分词(我强调):

shell 扫描参数扩展、命令替换和算术扩展的结果没有出现在双引号内用于分词。

...默认值为$IFS,这意味着build-essential \(newline)(other spaces)cmake ...会变成多个单词:

  • build-essential
  • \
  • cmake
  • ...

...有效地删除换行符以及每个空格字符中的所有字符。

引用变量可以防止分词(除其他外)。

进一步阅读:

答案2

shell 使用 1 个或多个空白(即空格、制表符、换行符)字符将参数与命令分隔开。当您不包含引号时, 的值$BASE_DEPENDENCIES将扩展为 N 个参数。 echo获取其所有参数并打印每个参数,并用单个空格分隔,因此您得到:

build-essential<space>\<space>cmake<space>\...

引号覆盖空格分隔;引号内的所有内容都作为单个参数传递。在这种情况下, gets 的值$BASE_DEPENDENCIES将 1 参数传递给echoecho然后打印所提供的一个参数(空格、换行符等完好无损)。

为了更好地理解,请考虑这个简单的 shell 函数,在本例中它相当于一个命令:

foo() {
    for i in "${@}"; do
        echo "->'${i}'"
    done
}

假设我有一个如下所示的变量:

x="    1         2 3    4   "

没有引号我得到 4 个参数:

$ foo $x
->'1'
->'2'
->'3'
->'4'

带引号我只得到一个:

$ foo "$x"
->'    1         2 3    4   '

答案3

这是因为引用保留了空格。与此比较:

# a=$(cal)
# echo $a
October 2017 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
# echo "$a"
    October 2017      
Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
15 16 17 18 19 20 21  
22 23 24 25 26 27 28  
29 30 31  

首先,cal命令输出存储在a.然后打印不带引号和带引号的内容。正如您所看到的,引用会保留空格,而没有引用会将文本分成代币,它们之间用空格分隔。

相关内容