LoginSignup
1
1

More than 5 years have passed since last update.

シェルスクリプトで、現状の標準入力を全て受け取ってから再度標準入力受付状態に戻す

Posted at

シェルスクリプトで、標準入力を開きっぱなしにしていると、標準入力を取得するところで停止してしまい次のコードへ進まない。標準入力を閉じれば進むが、閉じたくない。
readを使用すると、改行コードなどがない場合にデータが取れない。
そんな状況になったので、解決方法を探してみた。

テスト実行

入力待ち1
nc -l 6666 | while read -r line  ; do cat - ; echo next ;done
入力待ち2
nc -l 6666 | while read -r line  ; do echo "${line}" test ;done
データ送信
curl 'http://127.0.0.1:6666' --data 'aaa&bbb'
結果1
Host: 127.0.0.1:6666
User-Agent: curl/7.51.0
Accept: */*
Content-Length: 7
Content-Type: application/x-www-form-urlencoded

aaa&bbb
結果2
 test/ HTTP/1.1
 test 127.0.0.1:6666
 testAgent: curl/7.51.0
 testt: */*
 testnt-Length: 7
 testnt-Type: application/x-www-form-urlencoded
 test

解決案

標準入力を閉じれば、全部のデータが取れて、次のコードへ進める。
しかし閉じたくないのであれば、標準入力を差し替えて止めれば、あるいは。。
それならば、下記のことをすればできるはず。

  1. 標準入力を一旦逃して、今ある分をcatで標準入力させる
  2. catkillする
  3. 標準入力を取得すると、最初にcatされたものが取得でき、入力が閉じているので、次のコードへ進む
  4. 最初に逃した標準入力を標準入力に戻す

コード

in.sh
#!/bin/bash

while read -r line
do
    exec 5>&0 < <(cat -) 2>/dev/null
    while true
    do
        pid=$(ps -o pid --ppid $! --no-header)
        [ "${pid}" ] || continue
        kill ${pid}
        break
    done
    data+=$(cat)
    exec <&5
    echo "##### output #####"
    echo "${data}"
    echo "##### next #####"
done

echo "###### END ########"

実行と結果

入力待ち
$ nc -l 6666 | bash in.sh                                                               
データ送信
curl 'http://127.0.0.1:6666' --data 'aaa&bbb'
結果
aa.sh: 5 行:  1266 Terminated              cat -
##### output #####
Host: 127.0.0.1:6666
User-Agent: curl/7.51.0
Accept: */*
Content-Length: 7
Content-Type: application/x-www-form-urlencoded

aaa&bbb
##### next #####

なんか動いた! が、なんだこれw
一行目が抜けているけど、これは、最初のexecの直前で別途取ればいいだけ。
あと、一行目のエラーメッセージの消し方は分からなかった。

。。。力技すぎるので、正規のやり方や良いやり方を知ってる方がいたら、教えてください。
この解決策については、ググり方が分からない。。

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1