为什么我们这里不需要出口?

为什么我们这里不需要出口?
$ IFS=";"

$ read first second 
i am;a_i b c
$ echo $first
i am
$ echo $second
a_i b c

$ echo $IFS
  1. 我说得对吗,这read first second是当前 shell 进程的子进程?如果是的话,我们为什么不需要export IFS=";"
  2. 为什么是IFS空的?

答案1

我说得对吗,读第一秒是当前 shell 进程的子进程?如果是,为什么我们不需要 export IFS=";"?

不,read是一个bash 内置函数。这里没有创建子shell或子进程,所以我们不需要导出IFS

为什么 IFS 是空的?

因为您没有使用双引号。您已将值 IFS 更改为;,因此当您将 扩展为echo $IFS时,shell 将使用作为分隔符执行单词拆分和通配符。因此不会打印任何内容。$IFS;;

尝试:

$ IFS=";"
$ printf "%s\n" $IFS

$ printf "%s\n" "$IFS"
;

笔记

答案2

如果我们输入,type read我们会得到read is a shell builtin.因此它不作为子进程运行。

答案3

回答为什么 IFS 是空的。它不是。但其价值IFS在于改变 shell 的行为。下面不是解释,只是我在 Debian Gnu+Linux 上使用 bash 进行实验的结果。

a=";"; echo $a产生;.

IFS=";"; echo $IFS产生空行。 IFS=";"; echo "$IFS"产生;.

现在a=";"; echo $a产生空行,但又IFS=" "; a=";"; echo $a产生;

所以

现在IFS=";"; a=";"; echo $a产生空行,但IFS=" "; a=";"; echo $a产生;.

因此,IFS 的值会改变行为(然后在 echo 中不使用引号)。

答案4

IFS=\;; set -- $IFS; echo $#; echo "$*"

1
;

IFS=; set -- $IFS; echo $#; echo "$*"

0
#there doesn't seem to be anything here

正如您所看到的 -$IFS在第一种情况下不为空 - 它只包含一个字段分隔符。

当 shell 展开一个不带引号的变量时,它会根据 中定义的分隔符分割它的值$IFS。这样,每个变量都可能是一个$IFS单独的数组。默认情况下$IFS设置为 a <space>\tab 和\newline 。其中每一个都具有特殊的$IFS品质$IFS空白$IFS空白分隔符不会被保留,并且当 shell 执行分词时,任一序列都会被截断为单个字段,而所有其他序列将为每个分隔符分隔一个字段。$IFS空白也将从字段的开头或结尾完全删除。例如:

IFS=/; slashes=///////; printf '<%s>' $slashes
<><><><><><><>

IFS=' '; spaces='      '; printf '<%s>' $spaces
<>

printf '<%s>' $spaces$slashes
<///////>

$IFS空白显然是不是当它被删除时不是$IFS

IFS=/; printf '<%s>' $spaces$slashes
<      ><><><><><><>

相关内容