How to Write to stdin of a Running Process Using Named Pipes in Linux


2 views

>
>
>
>

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:

>
>

    >
    >

  1. Using expect for interactive programs
  2. >
    >

  3. Creating a PTY with socat or script
  4. >
    >

  5. Implementing a socket interface in your application
  6. >
    >

>
>


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