Eddy
Eddy

Reputation: 6871

Simulate keyboard presses in mac terminal

I'm running some simulations which require manual keyboard input to change the parameters (annoyingly).

Is there a way to simulate keyboard presses, so that I can run the simulations with a bash script?

Upvotes: 3

Views: 12020

Answers (5)

GoForth
GoForth

Reputation: 656

I like using robotgo to control all aspects of your machine: https://github.com/go-vgo/robotgo

Upvotes: 0

cancerbero
cancerbero

Reputation: 7045

I'm the author of cli-driver which is is a Node.js library to automate the command line, the analogy to web-driver but in the command line. It supports mac, linux and windows and so far I was able to easily "automate" any use case I needed, from complex prompts, to multiple command tasks, ssh sessions, command completion with tab or history with control+r, or even using vi, nano, emacs.

It let you actually create a new terminal and simulate user input (keyboard only) . In general you need to simulate a human user keystrokes like characters but in particular sequences like "enter", "shift-tab", "control-q", "control-shift-right", etc. But more generally any ansi sequence can written to control the cursor, keyboard and display capabilities - although in general you don't need that.

Internally it uses node-pty which is "forkpty(3) bindings for node.js. This allows you to fork processes with pseudoterminal file descriptors. It returns a terminal object which allows reads and writes."

The comunicacion is one way only though - you enter text and wait for an output, example (plenty on the home page):

const client = await new Driver().start()
let output = await client.enterAndWait('ls -a', '..')
expect(output).not.toContain('tmpFile')
await client.enterAndWait('echo hello > tmpFile1.txt', d=>existsSync('tmpFile1.txt'))
await client.destroy()

Upvotes: 0

Eddy
Eddy

Reputation: 6871

Turns out I could do from bash all along:

./program << ENDINPUT
$input1
$input2
$input3
ENDINPUT

Upvotes: 1

Flambino
Flambino

Reputation: 18793

While I won't recommend it, you can do something like this (it just lists your home directory's contents)

tell application "Terminal"
    activate
    do script "cd ~" -- the command to run
    delay 5 -- maybe throw in a delay to let the process start up
    tell application "System Events" to keystroke "ls -la" & return -- the keystrokes to simulate
end tell

However this is the digital equivalent of training a cat to walk on your keyboard. The code has no clue what's going on in the terminal. It just "types" something and presses return, completely obliviously.

So if you have any other way of passing the input to the process, use that instead. I just posted this, since you did ask for an AppleScript solution. I just doubt that AppleScript's the right solution.

Upvotes: 6

Emil
Emil

Reputation: 427

Maybe you could use expect?

Also echo | <cmd>.

Upvotes: 1

Related Questions