【问题标题】:Simulate ENTER key in bash here-document在 bash here-document 中模拟 ENTER 键
【发布时间】:2016-12-08 05:29:09
【问题描述】:

有没有办法在 bash 脚本中模拟 ENTER 键,通过 here-document (EOF) 将值输入到代码中。在 bash 中很容易实现,请参阅 question 6264596

伪代码:

 #!/bin/bash
 code_executable << EOF
 value1
 value2 
 EOF

value2 后面需要回车,即从 shell 执行时输入。

谢谢大家。

模拟在终端上运行的可执行文件:

  $./code_executable
  >Do you want to continue? yes or no
  User: y
  >Enter number:
  User: 314 

如果用户在输入 314 后没有按键盘上的 ENTER,则可执行文件挂起/暂停并等待。

编辑:查看标准输入缓冲中的异常,这些异常阻止 EOF 将参数传递给可执行文件,如下面的@that other guy answer所示。

【问题讨论】:

  • 您是否只想在value2 之后但EOF 之前有一个空行?
  • @chepner:我不确定。我在 value2 和 EOF 之间添加了一个文字空白行,但仍未解决,可执行文件无法获取 value2
  • 也许可执行文件中存在错误?使用问题中所示的脚本,可执行文件应该看到一行"value1\n",然后是一行"value2\n",然后是一个文件结束条件。在value2EOF 之间添加一个空行应该给可执行文件一个额外的行"\n"。当您自己运行可执行文件并从键盘输入时会发生什么?
  • @Keith Thompson:可执行文件中没有错误。 value1 是在不等待回车的情况下获取的,而 value2 不是。从终端运行时会发生这种情况:询问value1,然后在“键入”时,后者立即按照指令估算value2,直到键入ENTER。
  • 可能code_exacutableFTP.EXE 或类似的?从 /dev/tty 读取的程序不能以这种方式重定向。

标签: bash enter heredoc


【解决方案1】:

Enter 通常由换行符表示,而不是回车符。程序经常被回车符弄糊涂,所以终端会自动将它们翻译成换行符。

您可以在十六进制转储中看到这一点:

holen@vidarh2 11:14 ~ $ hexdump -C
(press enter several times, end with ctrl+d)
00000000  0a 0a 0a 0a                                       |....|
           ^----------- line feeds

如果你查看你的脚本,你会发现它已经在 value2 和你的尾随空格之后添加了一个:

$ cat yourscript 
#!/bin/bash
hexdump -C << EOF
value1
value2 
EOF

$ ./yourscript 
00000000  76 61 6c 75 65 31 0a 76  61 6c 75 65 32 20 0a     |value1.value2 .|
                                        line feed ----^

这是一个工作示例:

$ ./ex1
Continue?
yes
Number?
123
You wrote: 123

$ ./ex1 << EOF
> yes
> 123
> EOF
Continue?
Number?
You wrote: 123

以下是由于程序中的缓冲错误而导致失败的示例,即使程序在交互运行时看起来完全一样,但接收到错误的输入:

$ ./ex2
Continue?
yes
Number?
123
You wrote: 123

$ ./ex2 << EOF
yes
123
EOF

Continue?
Number?
You wrote: yes

这是另一种缓冲错误的第三个示例,其中程序以交互方式工作,但似乎没有从此处的文档接收输入:

$ ./ex3
Continue?
yes
Number?
123
You wrote: 123

$ ./ex3 << EOF
yes
123
EOF
Continue?
Number?
You wrote: 

他们分别读取带有fscanf(stdin, ..)fdopen(0, "r"); fscanf(file, ...read(0, buffer, 1024) 的行。只有第一个是正确的。

【讨论】:

  • @其他人:请看我上面的评论。感谢您的解释。但是,它并不建议解决方案。
  • 是的,只是没有暗示您的后续跟进“为什么我的秘密程序不能解释正确添加的回车键?”
  • @ :我不认为我理解你的评论。我通过终端的模拟执行澄清了这个问题。
  • @slkuser 听起来仍然像您的程序中的错误。我添加了一个示例,其中三个程序在交互运行时工作相同,其中只有一个与 here 文档一起工作。非交互式程序有不同的缓冲和计时行为,有缺陷的程序可能会依赖这些行为。
  • @其他人:非常感谢详细的调试。有问题的可执行文件不使用您指向的 stdin 函数。而是自定义定义的函数来执行读取行。事实上,它的行为就像非工作情况一样。
【解决方案2】:

* 请参阅that other guy's helpful answer 了解有用的背景信息和有关实际问题的提示。
* 这个答案假设一个行为良好的程序从标准输入读取提示输入 - 事实证明,不使用这样的程序正是 OP 的问题:当通过标准输入提供输入时,他们的程序的行为 不同与交互式打字相反。

让我们使用以下脚本模拟您的可执行文件:

#!/usr/bin/env bash

printf ">Do you want to continue? (y)es or (n)o: "
read -r -n 1  confirm  # NOTE: A *single* keypress terminates input here.
printf "\nUser: $confirm\n"

printf ">Enter number: "
read -r  number
printf "User: $number\n"

要通过标准输入将您问题中的示例输入提供给此脚本,使用here-document

./code_executable <<EOF
y314
EOF

请注意 y314 之间没有换行符,这是因为第一个提示不需要需要按 ENTER 键来提交输入- 只有一个字符。

使用 here-document,整个输入总是以换行符 (\n) 结束,这就像按下了 Enter 键(如 @ 中所述987654323@),因此将输入提交到第二个提示符。

其他提示输入可以简单地添加到结束 EOF 分隔符之前,每个额外的输入都需要 Enter 提交到自己的行。

./code_executable <<EOF
y314
next input
...
EOF

【讨论】:

  • @ mklement0:非常感谢您的建议。我测试了您的解决方案,但不幸的是无济于事。我需要将几个参数传递给可执行文件,因此使用EOF...但我愿意接受其他建议。
  • @slkuser:我已经删除了 here-string 替代项 (&lt;&lt;&lt;) 以避免混淆。您可以简单地向 here-document 添加额外的输入(这就是我假设您所说的 args) - 请参阅我的更新。
  • @mklement0: 实际上使用y314 而不是314 并没有解决问题。在此参数之后(但之前)没有其他用户输入需要按 Enter。
  • 此时唯一合理的解释是您的 C++ 程序不会(始终)从 stdin 读取数据,并且可能会从 终端 读取提示输入i> 直接(正如已经建议的那样)。在不知道您的程序真正做什么的情况下,我们无法帮助您。我模拟您的程序的示例脚本在从标准输入读取方面表现良好,并且如您所知,它可以工作。
猜你喜欢
  • 2011-04-13
  • 1970-01-01
  • 2016-02-25
  • 2012-10-26
  • 2015-05-11
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多