gpt4 book ai didi

linux - 为 for 循环设置 IFS 然后在 for 循环内取消设置是否安全?

转载 作者:IT王子 更新时间:2023-10-29 00:51:09 26 4
gpt4 key购买 nike

考虑以下我打算在任何 POSIX.1-2004 上运行的 shell 脚本一致的 shell 。

log()
{
echo debug: "$*"
}

A=foo:bar:baz

IFS=:
for i in $A
do
log token ">> >>" "$i"
done

unset IFS
# Do more stuff here

我想遍历以冒号分隔的值。在循环中,我想调用一个日志函数,它应该能够完整地回显传递给它的所有参数,并在每个参数中保留多个空格。当我运行这段代码时,这是我得到的输出。

debug: token:>>  >>:foo
debug: token:>> >>:bar
debug: token:>> >>:baz

好在">>>>"中的两个空格因为"$*"的使用被保留了下来,即引用特殊参数星号如 Section 2.5.2 Special Parameters 中定义POSIX.1-2004。

但不好的是,由于相同的用法,传递给 log 的三个参数现在用冒号分隔(IFS)。

我通过在 for 循环中取消设置IFS 来解决这个问题。

log()
{
echo debug: "$*"
}

A=foo:bar:baz

IFS=:
for i in $A
do
unset IFS
log token ">> >>" "$i"
done

unset IFS
# Do more stuff here

现在,输出如我所愿。

debug: token >>  >> foo
debug: token >> >> bar
debug: token >> >> baz

但我想知道是否有可能在某些 POSIX shell 中,在 for 循环中取消设置 IFS 会产生修改 的副作用IFS for for 循环正在进行中?

例如,我担心某些 POSIX shell 可能会为我的第二个代码示例生成以下输出。

debug: token >>  >> foo
debug: token >> >> bar:baz

有人可以通过引用 POSIX.1-2004 中的相关部分告诉我吗?如果我的第二个代码示例是安全的,并且是否保证在所有 POSIX 兼容的 shell 中产生相同的行为?

如果我的第二个代码示例不安全,那么我可能不得不接受类似这样的不修改 IFS 的代码。

log()
{
echo debug: "$*"
}

A=foo:bar:baz

echo "$A" | tr : "\n" | while read i
do
log token ">> >>" "$i"
done

最佳答案

这是安全的。

$A 变量将在 for 循环开始执行之前展开一次:

for i in foo bar baz

一旦发生这种情况,对 IFS 的任何更改都将无效。

引用资料:
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_05

如果您使用 IFS 只是为了解析该字符串,您可以这样做:

oldIFS=$IFS IFS=:
set -- $A # save the elements of the list as positional parameters
IFS=$oldIFS

for i; do
log "$i"
done

关于linux - 为 for 循环设置 IFS 然后在 for 循环内取消设置是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28858970/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com