Mor*_*eze 12 variables bash shell
为什么变量赋值用shell中的空格替换制表符?
$ cat tmp
a b e c d
$ res=$(cat tmp)
$ echo $res
a b e c d
Run Code Online (Sandbox Code Playgroud)
Chr*_*our 14
您需要为$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
Run Code Online (Sandbox Code Playgroud)
从man bash
下QUOTING
:
引用用于删除shell中某些字符或单词的特殊含义.引用可用于禁用特殊字符的特殊处理,以防止保留字被识别,并防止参数扩展.
上面在定义下列出的每个元字符对shell具有特殊含义,如果要表示自身,则必须引用它.
Run Code Online (Sandbox Code Playgroud)... \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 $res
Run Code Online (Sandbox Code Playgroud)
做同样的事情:
$ echo a b e c d
Run Code Online (Sandbox Code Playgroud)
(该行中的大空格是制表符,可以通过按键输入Ctrl+V Tab
).如果你运行该命令,你也会得到:
a b e c d
Run Code Online (Sandbox Code Playgroud)
所以你的问题实际上是:为什么在命令的参数中缺少标签?
答案是命令(echo
在这种情况下)永远不会看到制表符,或者确实是空格.shell将您的命令行解析为命令名和参数列表.它使用空格(制表符和空格)将命令拆分为这些部分.然后它运行命令,并将参数列表传递给它.
因此,echo
作为其论点的是"a","b","e","c","d"列表; 它不知道哪些角色最初将它们分开.
什么echo
那么所做的是每个参数的输出,与它们之间的空间.因此你看到的输出.在原始命令行使用单个空格字符分隔每个参数的情况下,输出与输入匹配,因此它看起来很像输入中的空格也在输出中 - 但它们不是:shell吞噬原始空间和echo
插入一些新的.
引号可用于使shell将多个"单词"视为单个参数.例如,如果你这样做:
$ echo a "b c" d
Run Code Online (Sandbox Code Playgroud)
将3个参数传递给echo
:'a','b c'和'd'.中间参数包含4个空格; 那些传递给它echo
,所以会出现在它的输出中.引号外部的空格被shell用于分割参数,因此不会传递给echo
.因此输出是:
a b c d
Run Code Online (Sandbox Code Playgroud)
要检查这种事情,使用一个命令可以更清楚地显示它收到了多少参数以及它们中的每个参数.这个Perl单线程会做到这一点:
$ 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'
];
Run Code Online (Sandbox Code Playgroud)