I needed a simple inter-process communication between a Kotlin application and a Bash script.
After some research, I stumbled over Named Pipes.
It’s a very simple concept, and exactly what I needed:
On MacOS or Linux, you can use the command mkfifo
to create a Named Pipe that behaves like a file.
You can use one process to write into it, and another to read from it.
My simple Bash script is responsible for creating the Named Pipe, reading from it, and eventually deleting it:
#!/bin/bash
# create a named pipe
mkfifo /tmp/my-named-pipe
# read from the named pipe in a loop
while read line
do
echo "Received: $line"
# do something with the received line
if [[ "$line" == "TEST" ]]; then
# do something
fi
done < /tmp/my-named-pipe
# clean up
rm /tmp/my-named-pipe
My Kotlin application used the Named Pipe to transfer data to the Bash script:
import java.io.File
import java.io.PrintWriter
fun main() {
val pipe = File("/tmp/my-named-pipe")
// ensure the named pipe exists
if (!pipe.exists()) {
error("Error: Named Pipe does not exist")
return
}
PrintWriter(pipe).use { pipeWriter ->
while (true) {
pipeWriter.println("TEST") // write some data
pipeWriter.flush()
Thread.sleep(1000)
}
}
}
In this simple example, the Bash script must be started first to create the Named Pipe. Then the Kotlin Application can be started to write to it.
And that’s already it. This simple concept enables a simple and efficient inter-process communication.