Bash 为什么变量赋值用空格替换制表符

Bash 为什么变量赋值用空格替换制表符,bash,shell,variables,Bash,Shell,Variables,为什么变量赋值在shell中用空格替换制表符 $ cat tmp a b e c d $ res=$(cat tmp) $ echo $res a b e c d 您需要引用变量$res,以保留空白 $ cat file a b e c d $ res=$(cat file) $ echo $res a b e c d $ echo "$res" a b e c d 从QUOTING下的manbash:

为什么变量赋值在shell中用空格替换制表符

$ cat tmp
a    b e    c    d
$ res=$(cat tmp)
$ echo $res
a b e c d

您需要引用变量
$res
,以保留空白

$ cat file
a       b e     c       d

$ res=$(cat file)

$ echo $res
a b e c d

$ echo "$res"
a       b e     c       d
QUOTING
下的
manbash

引用用于删除某些字符的特殊含义 或者对贝壳说些什么。 引用可用于禁用特殊字符的特殊处理,以防止 避免将保留字识别为保留字,并防止参数扩展

上面定义中列出的每个元字符对shell都有特殊意义 如果要表达自己,就必须引用

...

\a     alert (bell)
\b     backspace
\e
\E     an escape character
\f     form feed
\n     new line
\r     carriage return
\t     horizontal tab
\v     vertical tab
\\     backslash
\'     single quote
\"     double quote
\nnn   the eight-bit character whose value is the octal value nnn
\xHH   the eight-bit character whose value is the hexadecimal value HH
\cx    a control-x character

...

丢失选项卡的不是分配,而是调用
echo
命令

res
被分配一个包含选项卡的值。在shell中写入
$res
时,这相当于在该点键入
res
变量的内容

因此:

是否与以下内容相同:

$ echo a    b e     c       d
(其中该行中的大空格是制表符,可通过按Ctrl+V制表符键入)。如果您运行该命令,您还将获得:

a b e c d
因此,您的问题实际上是:为什么在命令的参数中缺少制表符

答案是命令(
echo,在本例中为
)永远看不到选项卡,甚至看不到空格。shell将命令行解析为命令名和参数列表。它使用空白(制表符和空格)将命令拆分为这些部分。然后它运行命令,将参数列表传递给它

因此,
echo
作为其参数接收的是列表“a”、“b”、“e”、“c”、“d”;它不知道最初是什么字符把它们分开的

然后,
echo
输出它的每个参数,并在它们之间留一个空格。因此,您将看到输出。当原始命令行使用单个空格字符分隔每个参数时,输出与输入匹配,因此看起来输入中的空格也在输出中,但它们不是:shell吞噬原始空格并插入一些新空格

引号可用于使shell将多个“单词”视为单个参数。例如,如果您这样做:

$ echo a    "b    c"    d
将3个参数传递给echo:“a”、“bc”和“d”。中间参数包含4个空格;这些将被传递到echo,因此将显示在其输出中。引号外的空格由shell用于分割参数,因此不会传递给
echo
。因此,输出为:

a b    c d
为了检查这种情况,更清楚的是使用一个命令来显示它接收到了多少个参数以及每个参数中包含了什么。此Perl one liner将实现以下功能:

$ perl -MData::Dumper -E 'say Dumper \@ARGV' a    b    c    d
$VAR1 = [
          'a',
          'b',
          'c',
          'd'
        ];

$ perl -MData::Dumper -E 'say Dumper \@ARGV' "a    b    c    d"
$VAR1 = [
          'a    b    c    d'
        ];

$ perl -MData::Dumper -E 'say Dumper \@ARGV' a    "b    c"    d
$VAR1 = [
          'a',
          'b    c',
          'd'
        ];

$ res="a    b c     d"
$ perl -MData::Dumper -E 'say Dumper \@ARGV' $res
$VAR1 = [
          'a',
          'b',
          'c',
          'd'
        ];

$ perl -MData::Dumper -E 'say Dumper \@ARGV' "$res"
$VAR1 = [
          'a    b c     d'
        ];
$ perl -MData::Dumper -E 'say Dumper \@ARGV' a    b    c    d
$VAR1 = [
          'a',
          'b',
          'c',
          'd'
        ];

$ perl -MData::Dumper -E 'say Dumper \@ARGV' "a    b    c    d"
$VAR1 = [
          'a    b    c    d'
        ];

$ perl -MData::Dumper -E 'say Dumper \@ARGV' a    "b    c"    d
$VAR1 = [
          'a',
          'b    c',
          'd'
        ];

$ res="a    b c     d"
$ perl -MData::Dumper -E 'say Dumper \@ARGV' $res
$VAR1 = [
          'a',
          'b',
          'c',
          'd'
        ];

$ perl -MData::Dumper -E 'say Dumper \@ARGV' "$res"
$VAR1 = [
          'a    b c     d'
        ];