コンテキスト
$ 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