从bash脚本自动化文本输入而无需使用EOF


10

我正在运行Ubuntu Linux。假设有一个名为的程序myprogram。该程序提示用户输入;特别是,用户必须在出现提示时键入一个整数,然后按Enter。我想使用bash脚本自动执行此过程。特别是,我想执行myprogram100次(使用i1到的计数器100)。在每次执行时myprogram,我想i在出现提示时输入的当前值。

(顺便说一句,使用myprogramoptions / switches -options,它们都是常量,因此在bash脚本中指定。)

此bash脚本的不完整骨架可能是:

#!/bin/bash
for i in {1..100}
do
   myprogram -options
done

现在,我想修改上面的代码,以便i在程序提示时输入的当前值。做这个的最好方式是什么?

我正在使用的软件的网站建议<<EOF在行尾使用myprogram -options。我认为这告诉bash查看输入的“文件结尾”。但是,如果我不想要的东西放置在输入的结束文件?如果要在<<或之后立即放置<怎么办?

原因是事情会变得更加复杂。例如,我可能会引入一个j以某种非线性,非顺序方式改变的整数计数器。然后,我想在每次迭代中提供jto 的当前值myprogram,但是to 的值j可能在to的调用myprogram -options与文件的结尾之间变化EOF

你有什么建议吗?


Answers:


14

对于几乎所有程序,通过标准输入提供程序,两者echo $i | myprogram -optionsmyprogram -options <<<$i都应该起作用$i

<foo将使用名为foostdin 的文件的内容。

<<foo将使用该文本和仅由组成的一行之间的文本foo作为标准输入。正如Gilles所说,这是一个here文件(heredoc)。EOF实际上并不意味着文件的末尾,它只是一个常见的Heredoc轮廓线(在此示例中,我们改用“ foo”)。

<<<foo将使用字符串“ foo”作为标准输入。您还可以指定一个变量$foo,如上所示,shell将使用其内容作为stdin。这称为herestring,因为它使用短字符串而不是整个块(如heredoc)。串在bash中有效,但在bash中无效/bin/sh


9

本网站推荐的语法称为此处文档。文件程序的输入在包含的行的下面立即开始<<EOF,并且不会在脚本末尾终止,而是在恰好包含文本的行终止EOF(请注意不要有多余的空格)。顺便说一句,您可以使用不包含任何shell特殊字符的任何结束标记:EOF不是关键字,它只是传统的。

#!/bin/bash
for i in {1..100}
do
   myprogram -options <<EOF
$i
EOF
   for j in {1..42}; do
     myprogram2 <<EOF
$i
$j
EOF
   done
done

换句话说,在这种情况下,EOF表示文件结尾标记,而不是脚本文件的实际结尾。文本“ EOF”是任意文本-您在<<字符后立即使用的任何字符都将指示此文档的结尾。我通常使用EOF,因为它很引人注目,例如,如果我正在以编程方式生成shell脚本(我经常这样做),则它不太可能位于nownow文档中。
cas

粗体的EOF应该为<underscore> <underscore> EOF <underscore> <underscore>
cas

使用这样的此处文档,我经常将结束标记更改为更有意义的内容(并且不太可能“随机”匹配),例如END_OF_WHATEVER_FUNCTION。有时,尝试“节省”空间/大小实际上是在浪费精力,因为这会导致对实际发生的事情产生歧义。
killermist 2012年

您如何sleep在两次从脚本读取的命令之间?
boltup_im_coding 2014年

@ unexpected62我不明白您的要求。您可能应该在此站点上提出一个新问题。确保提供足够的上下文。
吉尔斯(Gillles)“所以-别再作恶了” 2014年

3

上面的Kevin和Gilles都提到过这里的文件,或者简单的管道在很多情况下都可以使用。

对于更复杂的情况,您可能需要研究Expect或类似的东西(例如,Expect :: Simple CPAN模块是非常易于使用的perl实现)。就个人而言,我更喜欢perl模块(期望本身就是tcl),但是有许多常见脚本语言的实现。甚至可以使用while和read在sh或bash中编写该思想的非常原始的实现。

Expect和类似工具的一般思想是等待程序输出中的指定字符串或模式,然后将其输入所需的任何输入。

一个常见的示例用法是通过“期望”(即等待)字符串“ ogin:”,发送登录名,然后期望字符串“ word:”和发送密码来自动化登录。

如果您拥有myprogram的源代码,那么最后一个选择就是将其修改为将您要提供的输入作为命令行选项。这可能需要更多的前期工作,但比弄乱Expect或将数据管道传输到不是专门用于这种方式的程序中要麻烦得多。

...并且不要忘记将补丁提交到myprogram上游:)即使他们不喜欢您编写代码的方式,他们也可能会想要足够的想法自己添加功能。上游开发人员倾向于欣赏那些摆脱困境并做出贡献的人,而不是需求或抱怨。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.