I need to write a shell script, the output of which is fed to the standard input of another application. The shell script needs to read data from a named pipe pipe.fifo
.
A trivial way to do this is using
cat pipe.fifo
However, this introduces a slight overhead due to the use of cat
command which introduces another pipe. I thought of a way to redirect the data from the named pipe to standard output using only exec
and shell redirections and without using any other command.
exec 3<pipe.fifo 3>&1
This should create a new fd 3, representing the opened named pipe pipe.fifo
and the data coming from the pipe should be redirected to standard output. When I run this shell script, it blocks as nothing is writing to the named pipe, as expected. However, as soon as I printf something into the named pipe from another shell, the script does not output anything and stops blocking.
I would like to ask, what could be the possible problem in this command, and if such a redirection is even possible.
EDIT: To clarify more on the specific use case, I would like to do something akin to myapp <temp.fifo
, where myapp
reads directly reads from the named pipe instead of standard input. But unfortunately, I can't call myapp
directly. Instead, the application runs a command itself, the output of which is used in the application. Here's some minimal C code which can be used to represent myapp
.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char command[100];
char buffer[1024];
FILE* pipe;
if (argc != 2) {
printf("Usage: %s command\n", argv[0]);
exit(1);
}
snprintf(command, sizeof(command), "%s", argv[1]);
/* Open the command as a pipe */
pipe = popen(command, "r");
if (pipe == NULL) {
printf("Failed to run command\n");
exit(1);
}
/* Read the output of the command into a buffer */
while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
printf("%s", buffer);
}
pclose(pipe);
return 0;
}
It accepts the command to run as the first command line argument, which in this case is the mentioned shell script. We can run it as ./myapp ./script.sh
assuming both the executable and the script are in the same folder.
I prefer not to modify the actual code of myapp
to solve the problem, due to the code being too complex.