【シェルスクリプト】readコマンドを使用したwhile文内で、処理を一時停止できなかった件（解決）

# テキスト読込みreadとwhile文がうまく動かない！！！
シェルスクリプトで遊んでいたのですが、下記の問題に当たってしまいました・・・。

```text:check.txt
100
200
300
400
```
```text:while文(ループ)
while read line; do
  echo $line
  read -p "--> 確認してください。【Enter】" stop
done < /work/check.txt
```
```text:実行結果
100
300
```
あれ、処理が止まらずに一気に実行されてしまっている！！？
しかも値が足りない！！！
試しに【 <font color="Red">read -p "--> 確認してください。【Enter】 stop</font> 】を抜いてみて実行してみた。
```text:while文(ループ)
while read line; do
  echo $line
done < /work/check.txt
```
```text:実行結果
100
200
300
400
```
値は、想定通り出力されている。
てことは、やはり抜いた部分がおかしい・・・？
今度は、下記のようにしてみる。

```text:while文(ループ)
while read line; do
  echo $line
  read -p "--> 確認してください。【Enter】" stop
　echo "確認：$stop"
done < /work/check.txt
```
```text:実行結果
100
確認：200
300
確認：400
```
【 <font color="Red">stop</font> 】のやつが、値を拾ってしまっているやないかい！！

# なぜこういうことが起こったか・・・？
そもそもreadコマンドって何だっけ・・・？

:::note warn
readコマンド
標準入力からの入力をシェル変数に読み込むコマンド
書式：read 変数 [変数 変数...]

\~~参考リンク~~
[read - 標準入力から変数に代入する](https://linuxcommand.net/read/#_-u)
[[シェルスクリプト] readコマンドについて整理してみた](https://shiro-secret-base.com/?p=1125)
:::
どうやら readコマンド で複数の変数を指定するパターンと同じことが起きているようだ。
```text:例えば
[root]# read line stop
test1 test2
[root]# echo $line
test1
[root]# echo $stop
test2
```
別々でwhile文で指定した【read line】とその中で指定した【read stop】は、別物として扱われると思ってたのだが、一つの【read line stop】として扱われてしまうのですね・・・。
```text:while文(ループ)
while read line; do
  echo $line
  read -p "--> 確認してください。【Enter】" stop
done < /work/check.txt
```
# これをどのようにして想定通りの結果にしようか？
気持ち的には、下記のようにしたい！！！
妥協して、sleepコマンドを使って数秒待機させるか・・・？
もう少し方法を探してみたいと思います。
```text:実行結果
100
--> 確認してください。【Enter】
200
--> 確認してください。【Enter】
300
--> 確認してください。【Enter】
400
--> 確認してください。【Enter】
```
# 解決しました！
まず下記の認識は、間違っていました。
>別々でwhile文で指定した【read line】とその中で指定した【read stop】は、別物として扱われると思ってたのだが、一つの【read line stop】として扱われてしまうのですね・・・。
>

@angel_p_57 さんによると、今回うまくいかなかった原因は、
While文で使用していた２つの【readコマンド】でFD(ファイルディスクリプタ)がバッティングし、値が交互にそれぞれの変数に代入されてしまったから。とのこと！

そもそもFD(ファイルディスクリプタ)って何だっけ？
そういえば、LPIC１勉強してた時にちらっと出てきてたなー・・・。

:::note warn
FD(ファイルディスクリプタ)
プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子のこと

\~~参考リンク~~
[ファイルディスクリプタ (FD)とは](https://wa3.i-3-i.info/word14383.html)
[Linuxのファイルディスクリプタ数を変更・確認する方法](https://www.koikikukan.com/archives/2013/03/14-005555.php)
:::

またFDを指定していない read コマンドは、標準入力 ( FD：0 ) を使用するとのこと。

---- 上記の情報を踏まえたうえで解決するとしたら ----

① readコマンドで使用するDFを指定する　【by @angel_p_57 さんより】
　--> 指定する方法 [オプション（-u）を使用する](https://linuxcommand.net/read/#_-u)

```text:check.txt
100
200
300
400
```
```text:while文(ループ)
# FDを10に指定（使用可能FD範囲で、0-2以外なら何でもOK？）
# 内部の read は、デフォルトでOK！

while read -u 10 line; do
  echo $line
  read -p "--> 確認してください。【Enter】" stop
done 10< /work/check.txt
```
:::note warn
[上記の構文の参考リンク](https://ideone.com/6ybmC8)
:::
```text:実行結果
100
--> 確認してください。【Enter】
200
--> 確認してください。【Enter】
300
--> 確認してください。【Enter】
400
--> 確認してください。【Enter】
```




② 確認用 read 部分で入力を端末に指定する　【by @papiron さんより】
　（入力リダイレクトで /dev/tty を指定）
```text:while文(ループ)
# /dev/tty は、今使っている端末を示す

while read line; do
  echo $line
  read -p "--> 確認してください。【Enter】" stop < /dev/tty
done < /work/check.txt
```
:::note warn
/dev/tty（端末デバイス）
[参考リンク：ttyとは？](https://qiita.com/hoge_5555/items/f677f9ec7cd859380426)
[参考リンク：ttyとかptsとかについて確認してみる](https://qiita.com/toshihirock/items/22de12f99b5c40365369)
[参考リンク：</dev/ttyについて](https://teratail.com/questions/165417)
:::
```text:実行結果
100
--> 確認してください。【Enter】
200
--> 確認してください。【Enter】
300
--> 確認してください。【Enter】
400
--> 確認してください。【Enter】
```

これでやりたかったことができる！！！
@papiron さん @angel_p_57 さん ご教授、ありがとうございました！！！