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检查)。

但是,当我在 socat 超时之前Ctrl+c测试脚本时,数据会通过管道(即最终联系 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 抱怨计数器无效(与 timeout 命令有关)。

4

1 回答 1

1

我的第一个想法是,您尝试使用cat -or接收的数据中没有换行符<STDIN>。一旦有换行符或文件描述符的缓冲区已满(Linux 中默认为 4KB),这两个命令的默认行为都会返回数据。

于 2013-02-10T16:00:23.607 回答