>
>
>
>
When dealing with interactive processes in Linux, you might encounter situations where you need to programmatically send input to an already running process. The conventional approach of writing to /proc/PID/fd/0
often doesn't work as expected because it simply displays the text in the terminal rather than feeding it to the process's stdin.
>
>
>
>
Named pipes (FIFOs) create a persistent communication channel that can be attached to a process's stdin. Unlike anonymous pipes, they exist in the filesystem and can be accessed by multiple processes.
>
>
>
>
Here's how to properly redirect input to a running process:
>
>
# Create the named pipe
>
>mkfifo /tmp/input_pipe
>
># Attach the pipe to your process (before starting it)
>
>your_program < /tmp/input_pipe
>
>
>
>
For an already running process, you'll need to use gdb:
>
>
# Create pipe if not exists
>
>mkfifo /tmp/input_pipe
>
># Attach to running process
>
>gdb -p PID
>
>(gdb) call close(0)
>
>(gdb) call open("/tmp/input_pipe", 0)
>
>(gdb) quit
>
>
>
>
>
>
Consider this Python script that reads from stdin:
>
>
# reader.py
>
>while True:
>
> data = input("Enter command: ")
>
> print(f"Received: {data}")
>
>
>
>
To control it:
>
>
# Terminal 1:
>
>mkfifo /tmp/command_pipe
>
>python3 reader.py < /tmp/command_pipe
>
># Terminal 2:
>
>echo "start" > /tmp/command_pipe
>
>echo "stop" > /tmp/command_pipe
>
>
>
>
>
>
-
>
- Permission errors: Ensure the pipe has proper permissions (chmod 666 /tmp/input_pipe)
- Hanging writes: The reading process must be active when you write to the pipe
- EOF handling: Some processes close stdin after first EOF - use tail -f for continuous input
>
>
>
>
>
>
>
>
>
>
>
For more complex scenarios consider:
>
>
-
>
- Using
expect
for interactive programs - Creating a PTY with
socat
orscript
- Implementing a socket interface in your application
>
>
>
>
>
>
>
>
>
When you need to programmatically send input to an already running process, direct stdin redirection becomes tricky. The common approach of echo "input" > /proc/PID/fd/0
often just prints the text to the terminal rather than feeding it as actual input.
Named pipes (FIFOs) provide a robust solution for interprocess communication. Here's the proper workflow:
# Create the named pipe
mkfifo /tmp/cmd_pipe
# Redirect process stdin from the pipe
your_program < /tmp/cmd_pipe
# In another terminal, feed commands
echo "your_input" > /tmp/cmd_pipe
Consider this interactive Python program (interactive.py):
while True:
user_input = input("Enter command: ")
print(f"Executed: {user_input}")
if user_input == "quit":
break
Control it via named pipe:
mkfifo py_pipe
python3 interactive.py < py_pipe &
echo "test_command" > py_pipe
echo "quit" > py_pipe
For continuous communication, keep the pipe open:
# Terminal 1
mkfifo persistent_pipe
tail -f persistent_pipe | your_program
# Terminal 2
echo "command1" > persistent_pipe
echo "command2" > persistent_pipe
- Ensure proper permissions on the pipe (
chmod 660 pipe_name
) - Check process stdin with
ls -l /proc/PID/fd/0
- For network applications, consider
socat
as an alternative