3

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 が (タイムアウト コマンドに関連する) 無効なカウンターについて不平を言うためです。

4

1 に答える 1

1

cat -私の最初の考えは、またはで受信しようとしているデータにラインフィードがないことです<STDIN>。デフォルトの動作の両方のコマンドは、ラインフィードがあるか、ファイル記述子のバッファーがいっぱいになるとデータを返します(Linuxではデフォルトで4KB)。

于 2013-02-10T16:00:23.607 に答える