Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
阅读<<<$(myfunc)行为在Bash4.2和4.4之间有所不同_Bash - Fatal编程技术网

阅读<<<$(myfunc)行为在Bash4.2和4.4之间有所不同

阅读<<<$(myfunc)行为在Bash4.2和4.4之间有所不同,bash,Bash,下面有一些代码可以从列表中读取数组 #!/usr/local/bin/bash function getlist { printf "%q/\n" "foo" printf "%q/\n" "bar" } IFS="$(printf ' \n\t')" # IFS=" " while read -r tmp; do echo "test" echo $tmp done <<< $(getlist) 4.4产出 $ ./test.sh te

下面有一些代码可以从列表中读取数组

#!/usr/local/bin/bash

function getlist {
    printf "%q/\n" "foo"
    printf "%q/\n" "bar"
}

IFS="$(printf ' \n\t')"
# IFS=" "

while read -r tmp; do
    echo "test"
    echo $tmp
done <<< $(getlist)
4.4产出

$ ./test.sh
test
foo/
test
bar/

但是,如果我更改IFS=“”,它们的行为与4.4相同(但实际上分隔符是\n,对吗?)。想知道这两个版本之间有什么变化

问题不在于
阅读
而是你没有引用此处的字符串。如果您引用它,则在两种情况下都会得到4.4结果:

#!/usr/local/bin/bash

function getlist {
    printf "%q/\n" "foo"
    printf "%q/\n" "bar"
}

IFS="$(printf ' \n\t')"
# IFS=" "

while read -r tmp; do
    echo "test"
    echo $tmp
done <<< "$(getlist)"
#/usr/local/bin/bash
函数getlist{
printf“%q/\n”foo
printf“%q/\n”条
}
IFS=“$(printf'\n\t')”
#IFS=“”
而read-rtmp;做
回声“测试”
echo$tmp

完成问题不在于
read
而是你没有引用此处的字符串。如果您引用它,则在两种情况下都会得到4.4结果:

#!/usr/local/bin/bash

function getlist {
    printf "%q/\n" "foo"
    printf "%q/\n" "bar"
}

IFS="$(printf ' \n\t')"
# IFS=" "

while read -r tmp; do
    echo "test"
    echo $tmp
done <<< "$(getlist)"
#/usr/local/bin/bash
函数getlist{
printf“%q/\n”foo
printf“%q/\n”条
}
IFS=“$(printf'\n\t')”
#IFS=“”
而read-rtmp;做
回声“测试”
echo$tmp

另外,最好使用POSIX兼容的
getlist(){
声明语法,前面没有
function
function
就像
let
,一种向后兼容的痕迹(在本例中,对于ksh),与兼容的没有任何优势(因此是可移植的)另外,
IFS=$'\n\t'
比使用
printf
运行命令替换要高效得多(在ksh93中,shell实际上并不进行替换,只是在当前shell中运行printf——但bash没有这种优化)。另外,最好使用与POSIX兼容的
getlist(){
声明语法,前面没有
函数
函数
类似于
let
,是向后兼容的痕迹(在本例中为ksh),与兼容的(因此是可移植的)没有任何优势另外,
IFS=$'\n\t'
比使用
printf
运行命令替换要高效得多(在ksh93中,shell实际上并不进行替换,只是在当前shell中运行printf,但bash没有这种优化).添加报价确实使它们相同。但仍然对几个问题感到好奇。(1)为什么报价很重要?(2)4.4怎么不需要报价(3)为什么要将IFS更改为“”works@fushupinnanren, (1)双引号抑制字符串拆分和全局扩展。这是它们在shell中的主要用途——毕竟不是特定于
read
或heredocs的。(2)正如文档所说,4.4已经抑制了字符串拆分,所以如果它被抑制,即使没有引号也会被抑制。(3)字符串中不包含任何字符的IFS值意味着字符串不会被拆分。@fushupinnanren问题是bash正在对here字符串应用分词,因此字符串中的任何
IFS
字符都将被删除,并基本上替换为空格,然后
读取
woul我看到了这个结果。引号阻止了分词,在bash 4.4中他们修复了它,这样在这种情况下就不会再发生分词了。谢谢。但是为什么分词会使“read”在整个here字符串中读取?这不是相反吗?如果这是一个天真的问题,请接受我。@fushupinnanren比较
cat Adding quote的输出使它们相同。但仍对一些事情感到好奇。(1)为什么引用很重要?(2)4.4如何不需要引用(3)为什么将IFS更改为“”works@fushupinnanren,(1)双引号抑制字符串拆分和全局扩展。这是它们在shell中的主要用途——毕竟不是特定于
read
或herdocs的正如文档所说,4.4已经禁止了字符串的拆分,因此如果它被禁止,即使没有引号,它也会被禁止字符串中不包含任何字符的IFS值意味着字符串不会被拆分。@fushupinnanren问题是bash正在对here字符串应用分词,因此字符串中的任何
IFS
字符都将被删除,并基本上替换为空格,然后
读取
woul“我看到了这个结果。引号阻止了分词,在bash 4.4中,他们修复了它,这样在这种情况下就不会再发生分词了。”谢谢。但是为什么分词会让“read”在整个here字符串中读取?这不是相反吗?如果这是一个幼稚的问题,请接受我。@fushupinnanren比较
cat的输出