【发布时间】:2013-01-25 09:39:35
【问题描述】:
我在 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 命令有关)。
【问题讨论】:
-
这个脚本是用 Perl 写的吗?
my $answer = <$socket>;的左/右尖括号是什么?此外,在 shell 脚本中,当您从标准输入 (cat -) 接收数据时,它何时终止? -
是的,测试脚本是用perl写的。括号的意思是“阅读任何可读的内容”,我很乐意阅读一个字节。是的,当测试脚本被杀死时,我从标准输入中得到了整个东西。
-
对不起,我肯定没说清楚;我的第二个问题是,标准输入流何时终止?如果你没有收到
EOF,是的,cat将被卡在它的执行中——直到你按下 Ctrl+c,正如你所说的。 -
我的帖子更新了,谢谢提示
-
所以现在你真的在接收数据一段时间后杀死
cat -。数据从何而来,数据发送者本身不能向cat -发送终止消息吗?我的意思是,它进入了标准输入,但是是你在向文件中输入内容,还是来自打开的连接?