AIX ホスト myscript.sh に次のような bash スクリプトがあります。
MODE="$1"
if [ "$MODE" == "start" ]; then
socat -T100 -lf $LOGF -d -d -d -x TCP4-LISTEN:$LISTENINGPORT,bind=$LISTENINGADDR,reuseaddr,fork EXEC:"$0 proxy" &
PID=$!
echo $PID > $PIDFILE
echo "$0 $MODE started (pid=$PID)"
elif [ "$MODE" == "proxy" ]; then
cat - > $TMPFILE
# process $TMPFILE before the SSL connection.
cat $TMPFILE | socat -T 100 -lf $LOGF -d - OPENSSL:$HOST
rm -f $TMPFILE
私が実行すると、すべてがうまくいきます:
$ cat somefile | myscript.sh proxy | xxd
テストスクリプトを使用して socat リスナーに接続すると、問題が発生します。
my $file = $ARGV[0];
my $fsize = -s $file;
my $socket = IO::Socket::INET->new("127.0.0.1:$port")
or die "Couldn't connect to remote host: $!";
$socket->autoflush(1);
binmode($socket);
open (FILE,$file);
binmode(FILE);
my $buffer ;
while(sysread(FILE, $buffer, $blocksize)) {
print $socket $buffer ;
}
print "sent\n" ;
close (FILE) ;
my $answer = <$socket>;
if (defined($answer)) {
print $answer; # never reached
print "...\n" ;
} else {
die "connection reset by peer\n";
}
myscript.sh では、次の行でブロックされます。
cat - > $TMPFILE
テスト スクリプトでは、次の行でブロックされます。
my $answer = <$socket>;
この時点で、データは socat リスナーによって受信されています (tcpdump で確認)。
ただし、Ctrlsocatcタイムアウトの前にテスト スクリプトを追加すると、データはパイプを通過します (つまり、最終的に SSL サーバーに接続されます)。
私は何を間違っていますか?
更新: cat と EOF に関するヒントをありがとう。当分の間、私は次のように問題を回避しました:
timeout 0.2 cat -u - > $TMPFILE 2>>/dev/null
# process $TMPFILE before the SSL connection.
cat $TMPFILE | socat -T 100 -lf $LOGF -d - OPENSSL:$HOST
それは醜く、0.2秒も無駄です。より良い解決策を見つけたいと思っています。しかし、それは今のところ仕事をしています。2>>/dev/null の部分は、AIX が (タイムアウト コマンドに関連する) 無効なカウンターについて不平を言うためです。