read-r 対 read-r ラインと IFS

read-r 対 read-r ラインと IFS

私はIFSに関するコンテンツに触れましたが、さまざまなコードスニペットの動作を説明できません。要約すると、次のようになります。

$ read -r < <(printf "%s\n" " x ")  && echo \<"$REPLY"\>
< x >
$ read -r line < <(printf "%s\n" " x ")  && echo \<"$line"\>
<x>

もちろんman bash、必要なものはすべて揃っています。

名前が指定されていない場合、読み取った行は REPLY 変数に割り当てられます。。ファイルの終わりが発生した場合、読み取りタイムアウトが発生した場合(この場合は戻りコードが128より大きい場合)、変数割り当てエラーが発生した場合(読み取り専用変数に割り当てられるなど)、誤ったファイルでない限り、戻りコードは0です。記述子は -u の引数として提供されます。

IFS関連の答えの1つにこれに関する文が含まれていれば良いと思いました。理由。一部は公に間違っていることが明らかになった。例は、この段落の編集です。この回答:

読み取りは、IFSがパラメーターと共に呼び出されない限り、IFSを使用しません。 (編集する:これは完全に正確ではありません。 IFSの空白文字(スペースやタブなど)は、入力行の先頭/末尾で常に無視されます。 )

疑問符のない捜査的質問です。しかし、私が間違っている場合は訂正してください。

答え1

すべてのBourne / POSIXシェル(dash、ksh、pdksh、mksh、bash、zsh、shエミュレーションモードでない場合でもBusyBox sh、Bourneシェルなど)で続く一般的な動作は、前後の空白read -r line文字を削除することです。より一般的には、read -r line空白文字で構成される先行区切り文字は空白文字から削除され、IFS空白以外の文字は最大1つだけ削除されますIFS。行末では、空白文字のみを削除できます。なぜなら、行が空白ではなく区切り文字で終わると、空のフィールドで終わるからです。これはより一般的なケースの特殊なケースです。最初の変数は最初のフィールドを取得し、2番目の変数は2番目のフィールドを取得する式で、変数よりもフィールドが多い場合、最後の変数は行の残りの部分を取得します。末尾のスペース。

暗黙的な変数名を使用した呼び出しは、readbashとzshでエミュレートされたksh拡張です。 ksh(ATTとpdksh / mksh)とzshには、変数read名があるのとまったく同じ変数名はありません。 Bashでは、何らかの理由で動作が異なります。言い換えれば、変数名が暗黙的である場合、空白除去は行われません。意図的に違う理由を知りません。 (ストリッピングを望まない場合は、標準的なアプローチは実行することです。)readREPLYIFSIFS= read -r

  /* If there are no variables, save the text of the line read to the
     variable $REPLY.  ksh93 strips leading and trailing IFS whitespace,
     so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
     same way, but I believe that the difference in behaviors is useful
     enough to not do it.  Without the bash behavior, there is no way
     to read a line completely without interpretation or modification
     unless you mess with $IFS (e.g., setting it to the empty string).
     If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
  if (list == 0)
    {
#if 0
      orig_input_string = input_string;
      for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t
        ;
      input_string = t;
      input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw
#endif

関連情報