我正在阅读有关bash内部变量的阅读,并遇到了此IFS
示例:
output_args_one_per_line()
{
for arg
do
echo "[$arg]"
done # ^ ^ Embed within brackets, for your viewing pleasure.
}
case1
IFS=" "
var=" a b c "
output_args_one_per_line $var
#OUTPUT
# [a]
# [b]
# [c]
case2
IFS=:
var=":a::b:c:::" # Same pattern as above
CASE2
# but substituting ":" for " " ...
output_args_one_per_line $var
# []
# [a]
# []
# [b]
# [c]
# []
# []
现在,根据我的理解, IFS
的值是否为默认的 tn
,而不是删除领先和尾随的范围。因此,对于case1 bash,将 var
视为 a b c
,因此输出。
对于我说,根据我的看法,bash将 var
视为 |a||b|c|||
在此处将 |
视为 space
。我使用
Noob@Noob:~/tmp$ IFS=$':' FOO=$":a::b:c:::"; echo $FOO $'x'
a b c x
所以,我对案例2的预期输出是
# []
# [a]
# []
# []
# [b]
# [c]
# []
# []
# []
所以,有人可以在内部向我解释Bash在情况2中如何治疗var
,而我在哪里误会了我的理解。
您的主张(编辑为使用':'而不是'|'):
对于我的case2,根据我的bash bash看到var as:a :: b:b:c ::: treat:在这里空间。
是错误的。IFS
导致bash
将:
视为单词分离器,而不是空格。不要仅仅因为空格是默认 word saparator。
on 案例2 您的":a::b:c:::"
带有IFS=:
因此,您正在做的是在每个MET :
因此,从字符串的开头,直到第一个:
您有":
这是 nothing ,因此[]
从第一个:
到下一个:
您有:a:
是a
,因此[a]
从那里到下一个:
您有::
这是 nothing ,因此[]
从那里到下一个:
您有:b:
是b
,因此[b]
从那里到下一个:
您有:c:
是c
,因此[c]
从那里到下一个:
您有::
这是 nothing ,因此[]
从那里到下一个:
您有::"
这是 nothing ,因此[]
所以你得到了结果。
如@mark Reed,您可以使用printf
与bash -x
一起,您可以得到:
$ bash -x
$ IFS=':'; var=':a::b:c:::'; printf "[%s]n" $var
[12]+ IFS=:
[12]+ var=:a::b:c:::
[12]+ printf '[%s]n' '' a '' b c '' '' # notice this
[]
[a]
[]
[b]
[c]
[]
[]
:
是定界符。a:b
分为a
和b
,两者之间没有。在您的预期行为中,您将如何编码以下内容?
[a]
[]
[b]
唯一奇怪的是,最后没有三个空字符串。这可能是因为
未引用的隐式null参数,是由于没有值的参数的扩展而产生的。
原因很简单:
IFS=" "
var=" a b c "
output_args_one_per_line $var
这意味着使用此参数调用output_args_one_per_line
:
output_args_one_per_line a b c
解析命令行时,bash将删除额外的空白,因此实际呼叫将使用
output_args_one_per_line a b c
即。多个空间合并为一个,a
之前的空间将成为命令和第一个参数之间的空间。
这意味着在应用 IFS
之前,空间将消失。这也意味着您不能写
IFS=:
output_args_one_per_line:$var
命令后必须有一个空白,而不是单词分离器。
您可以使用set -x
运行脚本以查看跟踪输出(即Bash如何展开行)。
在第二种情况下,定界符一词不是空间字符,因此命令和第一个参数之间的必要空格与参数没有合并,该行变为
output_args_one_per_line :a::b:c:::
唯一奇怪的是,输出应该是c
之后的三个空参数,但这可能是因为删除了空的尾随参数(就像Bash在参数后删除了白空间一样)。这是另一个奇怪的输出:
IFS=:
var=":a::b:c::: " # Blank after C
> output_args_one_per_line $var
[]
[a]
[]
[b]
[c]
[]
[]
[ ]
因此,如果var
在最后一个结肠后确实包含任何内容,我们会得到缺失的参数。