Have you ever had a script or program running in the background, with no TTY/console, asking for input to continue running? How do you tell it ‘y’ so it will keep going? By faking input using TIOCSTI
! I had this issue when running a long chain of tasks in an ansible playbook, and a command in one of those tasks wanted to know if I was “sure”. I identified the PID
that was waiting for input, and wrote this little python script:
import fcntl
import sys
import termios
with open('/proc/<PID GOES HERE>/fd/0', 'w') as fd:
for char in "y\n":
fcntl.ioctl(fd, termios.TIOCSTI, char)
When you run this, it will send the letter ‘y
‘, followed by newline to the PID
, and the process continues to run. What is TIOCSTI
? From the man page of ioctl_tty
:
IOCTL_TTY(2) Linux Programmer's Manual IOCTL_TTY(2)
NAME
ioctl_tty - ioctls for terminals and serial lines
SYNOPSIS
#include <termios.h>
int ioctl(int fd, int cmd, ...);
DESCRIPTION
The ioctl(2) call for terminals and serial ports accepts many possible
command arguments. Most require a third argument, of varying type,
here called argp or arg.
Use of ioctl makes for nonportable programs. Use the POSIX interface
described in termios(3) whenever possible.
[...]
Faking input
TIOCSTI const char *argp
Insert the given byte in the input queue.
[...]
Linux 2020-06-09 IOCTL_TTY(2)
When I googled around for a way to solve this, this Stackexchange Q&A was pretty much spot on: https://unix.stackexchange.com/questions/48103/construct-a-command-by-putting-a-string-into-a-tty and this answer in particular for the Python script: https://unix.stackexchange.com/a/345572/315097