openssl从脚本中传递前几行,然后从stdin中读取



我想运行openssl,并将以下命令发送到服务器:

t authenticate <dynamically generated base64 string from calling script>
t select Inbox

然后从那里获得来自stdin的输入。我对shell脚本和openssl工具包非常无知,当然我不知道如何简单地通过管道/重定向stdin来做到这一点,除非我尝试设置一个同时从stdin本身绘制的文件,或者诸如此类。

我不太确定openssl用于读取其输入的技术。例如:

$ echo "t login testacct@yahoo.com password" | openssl s_client -connect imap.mail.yahoo.com:993

不做与相同的事情

openssl s_client -connect imap.mail.yahoo.com:993
# openssl dialogue opens...
C: t login testacct@yahoo.com password
S: t NO [AUTHENTICATIONFAILED] Incorrect username or password. (#YSH002)

我想象openssl正在打开一个新的shell会话(我在这里的理解很弱),并且它不会将其参数从stdin传递到它创建的内部shell。

我建议将问题拆分为两个脚本:

首先,您有一个脚本,它会回显要发送的初始命令,然后从stdin读取并写入stdout。像这样(例如称之为script1.sh):

#!/bin/bash
echo "first command"
echo "second command"
while read x
do
echo "$x"
done

然后,第二个脚本将参数绑定到openssl,这样您就不必一直键入它们(例如,调用这个script2.sh。请注意,与上面的script1.sh一样,您应该在第一行使用#!/bin/bash来告诉操作系统这是一个bash脚本。

然后你可以键入:

script1.sh | script2.sh

您将获得传递给openssl的前两行,然后您键入的所有内容都将在这之后传递。如果你想总是用一些命令来完成,你可以在script1.sh.中的while循环之后添加它们

你用Ctrl-D 终止整个过程

如果openssl响应您键入的输入,那么您将得到显示两次的您键入的行(这有点烦人)。在这种情况下,"read"的"-s"参数将抑制第一行(例如,用于键入密码)

请注意,此解决方案类似于前面建议的使用临时文件和尾部-f的解决方案,但它避免了对临时文件的需要,并且所有操作都在一行中完成。

问题中给出的解决方案的问题是,当"echo"t login…"命令完成时,openssl命令的stdin将关闭,这通常会导致程序退出。使用这里给出的解决方案,管道将第一个脚本的stdout连接到第二个脚本的tdin,所有输入到read的内容都将传递到openssl

这些解决方案都没有将stdin的控制权返回给用户。这应该将第一个命令和第二个命令传递给openssl,然后读取stdin:

cat <<EOF - | openssl ....
first command
second command
EOF

可以通过s_client:建立到启用SSL的IMAP服务器的基本SSL/TLS连接

openssl s_client -connect imapserver.example.com:143 -starttls imap

请注意后面的-starttls imap:openssl"知道"如何告诉IMAP服务器它希望从纯文本连接(如telnet所示)移动到SSL安全连接。

之后,openssl的工作完成了,您需要对服务器使用正确的IMAP,包括身份验证

您可以更改脚本以将命令写入文件,然后使用tee -astdin重定向到同一文件。让我给你看一个例子:

jweyrich@pharao:~$ echo "command1" > cmds
jweyrich@pharao:~$ tee -a cmds > /dev/null
command2
command3
^C

与此同时,我在另一个tty:中运行tail -f cmds

jweyrich@pharao:~$ tail -f cmds 
command1
command2
command3

这将使该文件成为您必须读取和处理的单一源文件。

我想补充一点,您可以使用Nick的解决方案作为一行脚本:

$ sh -c 'echo "first command"; echo "second command"; while read x; do  echo "$x"; done' | whatever

最新更新