bash 将关键代码发送到 OS X 上的命令行程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2616015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:56:47  来源:igfitidea点击:

Send key code to command line program on OS X

bashmacosscriptingkeypresskeycode

提问by Sandy Vanderbleek

I want to make a script that starts a program and then sends it key input. In psuedo-script:

我想制作一个脚本来启动一个程序,然后向它发送键输入。在伪脚本中:

#!/bin/bash
./program << (PRESS CONTROL-Z)

The program is running so if there were additional commands in the script they will not be reached unless say control-z terminates the program.

程序正在运行,因此如果脚本中有其他命令,则除非说 control-z 终止程序,否则将无法访问它们。

Is this possible? From what I've found I thought it might require key codes but I could be wrong.

这可能吗?根据我的发现,我认为它可能需要密钥代码,但我可能是错的。

采纳答案by Jonathan Leffler

You might be looking for expect(from http://expect.nist.gov/). This deals with the complexities of pseudo-ttys that make it appear to the program that the input from the script (in this scenario, the expectprogram) is coming from a terminal.

您可能正在寻找expect(来自http://expect.nist.gov/)。这处理了伪 tty 的复杂性,使程序看起来脚本(在这种情况下,expect程序)的输入来自终端。

Alternatively, you might be able to use echoor catand pipe the output of that into the program - it depends on the program.

或者,您可以使用echoorcat并将其输出通过管道传输到程序中 - 这取决于程序。

回答by PiersyP

This I think is probably a better solution than "expect" since it can be executed in native bash script, I'll be interested to see what you think.

我认为这可能是比“期望”更好的解决方案,因为它可以在本机 bash 脚本中执行,我很想知道您的想法。

Use

`printf "character code here"` 

note the backticks

注意反引号

So for instance I have written a script that controls a remote gnu screen session, the following line opens window 2 and issues the ctrl-c key combo

例如,我编写了一个控制远程 gnu 屏幕会话的脚本,以下行打开窗口 2 并发出 ctrl-c 组合键

ssh -t user@$host screen -p 2 -X stuff `printf "
printf "%#x\n" "'X"
0x58
3"`
  • The -t option simulates terminal input on the remote machine
  • -p allows us to specify the name or number of the window we are connecting to within the screen session.
  • \003 is the bash format of character code 0x03
  • -t 选项模拟远程机器上的终端输入
  • -p 允许我们指定我们在屏幕会话中连接的窗口的名称或编号。
  • \003 是字符代码 0x03 的 bash 格式

See herefor a complete reference of codes.

有关代码的完整参考,请参见此处

To find the code of some key input you can use

要查找某些键输入的代码,您可以使用

#!/bin/bash
./program&
  • Were X is the key you want to find the code of
  • To find codes of non literals you can use ctrl-v (makes bash append the next key to the command line rather than intepret it) and then type the key combo, so if I wanted to find the key code for ctrl-c I would delete the X press ctrl-v and then press ctrl-c.
  • 如果 X 是您要查找代码的关键
  • 要查找非文字代码,您可以使用 ctrl-v(使 bash 将下一个键附加到命令行而不是解释它)然后键入组合键,因此如果我想找到 ctrl-c 的键代码,我会删除 X 按 ctrl-v 然后按 ctrl-c。

One last thing the ascii code reference mentioned above lists 0x13 as the carriage return, but in the screen manual they list 0x15 as the enter key code, does anyone know why? Ive tested in a local screen and when I press enter 0x13 is produced, but when sending commands via ssh to a remote screen 0x13 doesn't work but 0x15 does.

上面提到的ascii代码参考最后一件事将0x13列为回车,但在屏幕手册中他们将0x15列为输入键码,有谁知道为什么?我已经在本地屏幕上进行了测试,当我按下 Enter 时,会生成 0x13,但是当通过 ssh 向远程屏幕发送命令时,0x13 不起作用,但 0x15 起作用。

Hope that helps

希望有帮助

Piers

码头

回答by Jason Coco

If you just want the program to start in the background, just do

如果您只想让程序在后台启动,请执行以下操作

./program &    # The & sends the command to the background
echo commands here are executed while program is in the background
…
wait           # Wait for the completion of background commands
echo commands here are executed after background program has completed

回答by Arkku

If your intent is to background the program, use:

如果您的目的是使程序后台运行,请使用:

kill -STOP pid

Edit:If your intent is to stop the program (as ctrl-Z often does in *nix shells), you can send it the STOP signal:

编辑:如果您的意图是停止程序(就像 ctrl-Z 在 *nix shell 中经常做的那样),您可以向它发送 STOP 信号:

kill -CONT pid

To resume the execution, send it the CONT signal:

要恢复执行,请向其发送 CONT 信号:

./prog &
echo prog started in the background
pid_of_prog=$!
kill -STOP $pid_of_prog
echo prog stopped
kill -CONT $pid_of_prog
echo prog continues
wait
echo prog finished

In each of these examples pidis the process id of the program. If you launch it in a script, it's easy to get with the variable $!, e.g.

在这些示例pid中的每一个中,都有程序的进程 ID。如果您在脚本中启动它,则很容易获得变量$!,例如

echo -e "2" | ./prog

Edit 2:If your program is one that exits when it receives a ctrl-Z character, then remember that the control characters have the numerical value of the position letter in the alphabet (i.e. Ctrl-A is 1, Ctrl-B is 2, etc.). To send this character to a program you can:

编辑 2:如果您的程序是在收到 ctrl-Z 字符时退出的程序,那么请记住控制字符具有字母表中位置字母的数值(即 Ctrl-A 为 1,Ctrl-B 为 2,等等。)。要将此字符发送到程序,您可以:

##代码##

(032is 26, i.e. ^Z, in octal. Of course you can produce the same character by any means, perhaps adding it to the end of other input like ( cat inputfile ; echo -e "\032" ) | ./prog.

(032是八进制的 26,即 ^Z。当然,您可以通过任何方式生成相同的字符,也许将其添加到其他输入的末尾,例如( cat inputfile ; echo -e "\032" ) | ./prog.

But this may not necessarily work; the program must be designed to recognise this character from the input (which it probably won't); usually the shell catches it. Then again, most programs reading input from stdinjust exit when the input ends, so redirecting any finite input (even </dev/null) should cause it to terminate.

但这可能不一定有效;程序必须设计为从输入中识别这个字符(它可能不会);通常外壳会抓住它。再说一次,大多数读取输入的程序stdin在输入结束时才退出,因此重定向任何有限输入(甚至</dev/null)应该会导致它终止。

And, finally, if the intent was to stop the execution of the program when some other event (detected elsewhere in the script) has occurred, you can just killit…

最后,如果目的是在其他事件(在脚本的其他地方检测到)发生时停止程序的执行,你可以kill……