通过的s_client.First在shell脚本关闭连接 [英] Closing connections via s_client in a shell script

查看:180
本文介绍了通过的s_client.First在shell脚本关闭连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个shell脚本中到IMAP服务器的连接。虽然我可以连接并发出命令,关闭连接适当似乎是不可能的。

I am trying to make a connection to an IMAP server within a shell script. While I can connect and issue the commands, closing the connection suitably seems impossible.

这是我使用的测试命令:

This is the test command I am using:

openssl s_client -crlf -connect server:993 <<EOF
01 login USERNAME PASSWORD
02 LIST "" "*"
03 logout
EOF

由于连接只要输入用完关闭,这发生时收到任何输出之前,所以我从来没有收到所需的数据。

Because the connection is closed as soon as the input runs out, this occurs before any output is received so I never receive the required data.

根据需要如果我添加的选项 -ign_eof 选项,这样它会忽略结束保持连接打开输出输入被返回。但连接已关闭之后,而不是...

If I add the option -ign_eof option so that it will ignore the input ending to keep the connection open the output is returned as desired. But instead after the connection has been closed...

* BYE Logging out
03 OK Logout completed.

...的s_client.First仍然活着所以执行永远不会返回到脚本。

...s_client remains alive so execution never returns to the script.

有没有这将导致的s_client.First在服务器关闭的连接终止的解决方案?

Is there a solution which will cause s_client to terminate when the server closes the connection?

还是有使用标准工具的替代方法?该脚本会在Mac OS X,Debian和一个红帽衍生物运行,并有可能在Android终端模拟器,所以我想用相当标准的工具的便携性,而不是专门的软件包。

Or is there an alternative method using standard tools? The script would be run on Mac OS X, Debian, and a Redhat derivate, and possibly an Android terminal emulator so I would like to use fairly standard tools for portability rather than specialist packages.

更新:我想出了,我不是完全满意的答案,但它确实工作。它使用一个脚本来管命令OpenSSL的,但,然后进入一个无限循环,保持开放的标准输入,直到收到一个信号,告诉它退出。下面是我的测试脚本:

Update: I have come up with an answer that I am not entirely happy with, but which does work. It uses a script to pipe commands to the openssl but which then enters an infinite loop to keep stdin open until it receives a signal to tell it to quit. Here is my test script:

#!/bin/sh

if [ "$1" = "doit" ]; then
   trap "echo \"04 logout\"; exit" SIGUSR1
   echo "00 login USERNAME PASSWORD"
   echo "01 SELECT PID-$$"
   echo "02 SELECT FOLDER"
   echo "03 FETCH 1:* (BODY[HEADER.FIELDS (Subject)])"
   while :; do :; done
fi

MYFLAG=
$0 doit | openssl s_client -crlf -connect server:993 2>/dev/null | while read LINE; do
   LINE=`echo "$LINE" | tr -d '\r'`
   [ "${LINE:0:4}" = "* OK" ] && MYFLAG=Y 
   [ "${LINE:0:33}" = "01 NO Mailbox doesn't exist: PID-" ] && PID="${LINE##*PID-}"
   [ "$MYFLAG" ] && echo "$LINE"
   [ "$PID" -a "$LINE" = "03 OK Fetch completed." ] && kill -USR1 $PID
done
echo "Finished."

该脚本调用本身就带有参数输出,通过管道输送到OpenSSL中IMAP命令,它的输出管道成循环,这样就可以处理。该MYFLAG变量只是用来隐藏由OpenSSL的输出的信息,只是呼应从服务器连接的输出。

The script calls itself with a parameter to output the IMAP commands which is piped to openssl, whose output is piped into a read loop so it can be processed. The MYFLAG variable is just used to hide the information output by openssl and just echo the output from the server connection.

我选择一个虚拟文件夹名,其中包括脚本的一种方式的二审PID通过这回,明显是临时文件会好些,但对于测试我想保持自给自足的一切,并能看发生了什么事。

I select a dummy folder name which includes the PID of the second instance of the script as a way to pass this back, obviously a temporary file would have been better but for the testing I wanted to keep everything self contained and be able to watch what was happening.

一旦获取信息已经显示,服务器返回OK响应,它发送一个SIGUSR1信号给脚本的第二个实例,即然后发送注销消息,并退出,关闭标准输入导致的s_client.First断开连接。

Once the fetch information has been displayed and the server returns the OK response, it sends a SIGUSR1 signal to the second instance of the script, that then sends the logout message and quits, closing stdin which causes s_client to disconnect.

本来我包括 04注销在初始设置回波命令,但是当我这样做的读取循环只能尽可能的提取输出则止步不前,它显示甚至没有显示操作正常状态,但收到的一切。

Originally I included the 04 logout command in the initial set of echos, but when I did this the read loop only displayed as far as the fetch output then stalled, it did not even show the OK status for the operation, though everything was received.

此外,我需要使用 TR 剥离后回车,但如果我管从OpenSSL的通过则没有被读取循环好评。输出

Also I need to use tr to strip trailing carriage returns, but if I pipe the output from openssl through then nothing is received by the read loop.

推荐答案

您可以修复由计时您的输入OpenSSL的。
我能想出的最简单方法是使用回声输入到标准输出的函数:

you could fix that by timing your input to openssl. the simplest way i can come up with, is by using a function that echos the input to the stdout:

#!/bin/sh

imapscript () {
echo '01 login USER PASSWD'
echo '02 LIST "" "*"'
echo '03 logout'
while sleep 1; do
  echo "04 logout"
done
}

imapscript | openssl s_client -crlf -connect server:993

这篇关于通过的s_client.First在shell脚本关闭连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆