通过批处理在openssl中运行命令

6

我正在尝试在运行时间监控中设置自定义脚本,并使用该命令运行openssl并传入我提供的参数。

openssl s_client -CAfile C:\apcerts\certs\ -quiet -connect ${HOST}:${PORT} > ${TMPF} 2>&1 < EOF
<TF80DOC><XPLN/></TF80DOC>
EOF

if (Select-String "Update Level" ${TMPF} > /dev/null)
{
    exitstatus=$STATE_OK
    Select-String "Update Level" ${TMPF} | sort | uniq}
elseif (Select-String "Regulatory" ${TMPF} > /dev/null)
{
    exitstatus=$STATE_OK
    Select-String "Regulatory" ${TMPF} | sort | uniq}
else{
    echo `date` >> /tmp/caught_errs.out
    cat ${TMPF} >> /tmp/caught_errs.out
    echo " "    >> /tmp/caught_errs.out
    exitstatus=$STATE_CRITICAL
    }
rm -f ${TMPF} 2> /dev/null

exit ${exitstatus}

我希望 ${host}:${port} 这些变量保持为空白,我需要手动输入信息并将该信息填充到字段中。
例如,我需要连接到 blank-xml.myinfo.com:30011。
我遇到的问题是,在自定义监视器上设置时,我有一个 .bat 文件打开了 OpenSSL 但无法打开 .txt 文件以运行给定的命令。
我需要做什么才能使其正常工作?
更新:
我已经创建了一个较小的批处理文件,将信息传递给 OpenSSL。
@echo off
c:\OpenSSL-Win64\bin\openssl s_client -connect help-xml.helpme.com:443

这个部分很好地展示了屏幕上需要的信息。我需要向窗口发送另一个命令,但是出现了错误,指出“<”命令不是可执行或批处理进程。
那个命令是<TF80DOC><XPLN/></TF80DOC>,我尝试使用“&”符号并在它之前使用echo,但仍然得到相同的错误,或者屏幕会立即弹出并关闭而没有任何信息。
如果我不能在s_client -connect help-xml.helpme.com:443运行后将<TF80DOC><XPLN/></TF80DOC>发送到openssl,则if then语句将永远不起作用,因为此命令包含要显示的信息,if语句正在查找该信息。
更新:
我已更改powershell命令以在s_client -connect help-xml.helpme.com:443之后管道传输命令。
新代码如下:
@' 
<TF90DOC><XPLN/></TF90DOC>
'@ | C:\OpenSSL-Win64\bin\openssl s_client -quiet -connects_client -connect help-xml.helpme.com:443 > test1.txt 2>&1

如果我知道如何修复if then语句,那么这不是问题。代码的powershell部分可以工作,但需要我按下回车键,这不是我所需要的。我需要它在没有用户输入的情况下自动执行命令。

对于批处理命令,我做了一些小改动,具体如下:

@echo off
setlocal enabledelayedexpansion 
set "var=<TF90DOC><XPLN/></TF90DOC>"

echo echo !var! | C:\OpenSSL-Win64\bin\openssl s_client -connect tf90-xml.bsi.com:443> test1.txt 2>&1 

这个命令还是给我报错了。

< 在此处是意料之外的。


我该如何将<TF80DOC><XPLN/></TF80DOC>写成一个变量? - bgrif
好的,我会尝试一下。我会告诉你发生了什么。 - bgrif
我遇到了和之前一样的问题,就是“<”在这个位置上是意料之外的。 - bgrif
那个脚本的语言是什么?是PowerShell吗?bash?如果是PowerShell,请尝试使用反引号(通常位于[Tab]上方的\``字符)转义<>。因此,$xml = "<TF80DOC><XPLN/></TF80DOC>"无法正常工作,请尝试`<TF80DOC`>`<XPLN/`>`</TF80DOC`>。有关在PowerShell中转义的更多信息,请参见[此处](http://ss64.com/ps/syntax-esc.html)。如果您没有使用PowerShell,请忽略所有内容。这很令人困惑。Select-String看起来像是PowerShell cmdlet,但/dev/null`是Linux的东西。 - rojo
1
看起来你根据评论对代码进行了几次更改 - 你能否发布最新的代码,以便我们可以看到它当前的工作状态(或者不工作)? - ice13berg
显示剩余2条评论
2个回答

1

一开始我完全误解了你的问题,没有意识到你需要将命令发送到新打开的openssl实例。为了做到这一点,你需要将想要发送的命令通过管道传递给openssl。

@echo off
echo ^<TF80DOC^>^<XPLN/^>^</TF80DOC^>|c:\OpenSSL-Win64\bin\openssl s_client -connect help-xml.helpme.com:443

请注意,这是未经测试的,您可能还需要转义转义字符:
echo ^^^<TF80DOC^^^>^^^<XPLN/^^^>^^^</TF80DOC^^^>|c:\OpenSSL-Win64\bin\openssl s_client -connect help-xml.helpme.com:443

如果您需要发送多个命令,请将它们放在单独的批处理文件中,每个命令前面加上echo,并将其管道传递给openssl命令,如下所示:

commands.bat

@echo off
echo echo This is one command.
echo echo This is another command.

main.bat

@echo off
commands.bat|C:\OpenSSL-Win64\bin\openssl s-client -connect help-xml.helpme.com:443

给出的错误是<在此时是意外的。 - bgrif
@bgrif - 两天后,我看到了这个答案 ,它似乎基本上就是你要找的,但是使用的是bash。我已经编辑了我的答案以更好地满足您的需求。 - SomethingDark
1
echo ^^^<TF80DOC^^^>^^^<XPLN/^^^>^^^</TF80DOC^^^>|c:\OpenSSL-Win64\bin\openssl s_client -connect help-xml.helpme.com:443 命令会暂停并等待用户按下回车键。这更接近于我尝试使用批处理命令的目的。我仍然需要让它完全运行而不需要用户输入。 - bgrif

1
尝试这个:(请参见下面的编辑。)
@echo off
(
    echo(^^^<TF90DOC^^^>^^^<XPLN/^^^>^^^</TF90DOC^^^>
    echo;
) | C:\OpenSSL-Win64\bin\openssl s_client -connect tf90-xml.bsi.com:443 > test1.txt 2>&1

编辑:

根据您的描述,看起来openssl在输入XML后并不立即准备好接受输入,并且正在黑洞中吞噬传输到stdin的换行符。因此,您需要引入某种延迟,并监听该程序的stdout以获取适当的提示,而不是一次性将所有内容转储到stdin。

这是一个JScript概念验证,我认为它可以很快应用于您的情况,只要我知道openssl用于提示XML的文本,以及Enter键的按键。这是一种与WSHScriptExec StdOut Property文档页面上描述的类似方法,比迄今为止尝试的任何解决方案更灵活。

test.bat

@if (@a==@b) @end   /*  begin multiline JScript comment

:: batch portion

@echo off
setlocal

cscript /nologo /e:JScript "%~f0"

goto :EOF
    
:: end batch portion / begin JScript */
var osh = new ActiveXObject('wscript.shell'),
    fso = new ActiveXObject('scripting.filesystemobject'),
    log = fso.CreateTextFile('output.txt', true),
    read;

var exe = osh.Exec('cmd /c test2.bat');

while (1) {
    if (!exe.StdOut.AtEndOfStream) {
        read += exe.StdOut.Read(1); // read 1 char at a time
        if (/Arg 1:/.test(read)) {
            WSH.Sleep(50);
            exe.StdIn.Write('<TF80DOC><XPLN/></TF80DOC>\n');
            WSH.Sleep(100);

            // This is the output we wish to capture.
            read = exe.StdOut.ReadLine();
            WSH.Echo(read);
            log.WriteLine(read);

            read = '';
        } else if (/Press any key/.test(read)) {
            WSH.Sleep(100);
            exe.StdIn.Write('\n');
            break;
        }
    }
    else WSH.Sleep(100);
}
log.Close();

while (!exe.Status) WSH.Sleep(100);
WSH.Echo('Done.');

test2.bat

@echo off
setlocal enabledelayedexpansion

set /P "input=Arg 1: "

echo(Input: !input!

pause

test.bat和test2.bat像你展示的那样工作得很好,这真的很不错。我尝试了你建议的一切,但当我尝试做所有的openssl操作时,它仍然会暂停。 - bgrif
我会继续尝试不同的方法来使这个工作起来。 - bgrif
@bgrif,我有不同的想法。请看我的编辑。如果您需要帮助将其调整为适合您情况的形式,请告诉我XML字符串提示的文本,无论您是想记录所有内容还是只想记录特定行以及“按Enter键”的文本。 - rojo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接