IFS=',' /usr/bin/read および IFS=',' 読み取り

IFS=',' /usr/bin/read および IFS=',' 読み取り

コンテキスト

$ 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

以下の例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

生産:

pig
cow
horse
rattlesnake

例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

答え1

readは、シェル組み込みコマンド、つまり外部プログラムではなくシェル自体が提供するコマンドです。シェル組み込み関数の詳細については、次を参照してください。組み込みコマンドと非組み込みコマンドの違いは何ですか?

readシェルの状態を変更するため、組み込み関数が必要です。特に、出力を含む変数を設定します。外部コマンドは、呼び出されるシェルの変数を設定できません。また、見ることができますCDはなぜプログラムではないのですか?

一部のシステムには、という外部コマンドもありますread議論の余地があるコンプライアンス理由。外部コマンドは、コマンドが実行するすべての操作を実行できません。入力行を読み取ることはできますが、読み取った内容でシェル変数を設定することはできないため、外部コマンドは入力行を処理せずに削除するためにのみ使用できます。

which read組み込み関数が存在するという事実を教えてくれません。なぜならそれがその機能ではないからです。whichそれ自体はbashや他のBourneスタイルのシェル(zshを除く)の外部コマンドなので、外部コマンドに関する情報だけを報告します。電話するのに十分な理由はほとんどありません。which。コマンド名が何を意味するのかを調べるコマンドは次のとおりです。type

bash-5.0$ type read
read is a shell builtin

答え2

readシェルにも組み込まれていますが、whichこれについてはわかりません。以下を実行してみてください。

$ type read
read is a shell builtin

うまくいかない理由は、/usr/bin/read私のシステムにインストールされていないので、どのアプリケーションなのかわかりませんが、組み込みシェルが望むアプリケーションである可能性があります。

答え3

read現在の環境に影響を与えるシェル組み込みコマンドです。 /usr/bin/readサブシェルで実行される外部コマンドなので実行できません。

/usr/bin/read事実上役に立たないのに、なぜ私たちはそれを持っているのでしょうか?答えはPOSIXです。外部コマンドとしても存在するには、組み込みコマンドが必要です!

たとえば、コマンドもあります/usr/bin/cd。見てみましょう...サブシェルを作成し、スクリプトを実行してbuiltin cd "$@"(デフォルトで)終了します...したがって、役に立つことはありません。

この奇妙な現象の基本原理は、次のように説明されています。https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap01.html#tag_23_01_07

答え4

他の人が述べたように、「読み取り」はシェル組み込みです。私のシステムには/usr/bin/readがありません。しかし、man read私に次のことを教えてください。

NAME 読み取り - ファイル記述子から読み込みます。

要約 #include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

説明read()は、ファイル記述子fdのcountバイトをbufから始まるバッファに読み込もうとします。

したがって、この種の読み取りはシステムコールおよびプログラミングツールです。

しかし!読み取りをまったく使用しないでください。 「データ」があり、配列が必要です。

IFS=',';my_array=( ${data[@]} )
for item in "${my_array[@]}"; do echo "$item"; done
pig
cow
horse
rattlesnake

関連情報