IFS=',' /usr/bin/read vs IFS=',' 读

WMC*_*WMC 6 shell bash which shell-builtin read

语境

$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.$ which read
/usr/bin/read

$ which read
/usr/bin/read
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么下面的示例 1 有效而示例 2 无效吗?

示例 1 - 裸读作品

这个:

declare data
data="pig,cow,horse,rattlesnake,"
declare -a my_array
IFS=',' read -r -a my_array <<< "$data"
for item in "${my_array[@]}"; do echo "$item"; done
Run Code Online (Sandbox Code Playgroud)

产生:

pig
cow
horse
rattlesnake
Run Code Online (Sandbox Code Playgroud)

示例 2 - /usr/bin/read 失败

这不会产生任何输出:

declare data
data="pig,cow,horse,rattlesnake,"
declare -a my_array
IFS=',' /usr/bin/read -r -a my_array <<< "$data"
for item in "${my_array[@]}"; do echo "$item"; done
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 25

read是一个shell 内置命令,即由shell 本身而不是外部程序提供的命令。有关 shell内置命令的更多信息,请参阅内置命令和非内置命令有什么区别?

read需要是一个内置函数,因为它修改了 shell 的状态,特别是它设置了包含输出的变量。外部命令不可能设置调用它们的 shell 的变量。另请参阅为什么 cd 不是程序?.

read出于有争议的合规性原因,一些系统还有一个称为外部命令的命令。外部命令不能完成命令的所有工作:它可以读取一行输入,但不能将shell变量设置为它读取的内容,因此外部命令只能用于丢弃一行输入,不去处理它。

which read不会告诉您内置函数存在,因为那不是它的工作。which本身是 bash 和其他 Bourne 风格的 shell(不包括 zsh)中的外部命令,因此它只报告有关外部命令的信息。很少有充分的理由调用which。找出命令名称代表什么的命令是type

bash-5.0$ type read
read is a shell builtin
Run Code Online (Sandbox Code Playgroud)

  • 使用 `type -a read` 是一个更有用的习惯。 (3认同)
  • 请注意,`which` 实际上是某些 shell(例如 ZSH)中的内置函数,其行为与 `type` 等效。或者,如果在脚本中寻找命令可用性,`command -v` 比两者都好,因为你可以直接执行它的输出。 (2认同)

Mic*_*zek 4

read也是shell内置的,这个which不知道。尝试运行:

$ type read
read is a shell builtin
Run Code Online (Sandbox Code Playgroud)

至于为什么/usr/bin/read不起作用,我不确定那是什么应用程序,因为我的系统上没有安装它,但很可能内置的 shell 就是您想要的应用程序。