Piping from a long-running process into xargs having no effect

160 views Asked by At

In bash, I want to start my program (gollum) and use a part of the stderr (the port number) as an argument for another program. I redirect stderr to stdout and use grep and sed to filter the output. I get the result in stdout:

gollum -p0 2>&1|  sed  -n -e "s/.*port=//p"

It returns '56343' and continue to run as gollum is a server.

However if I want to use this as an argument of another program (i.e. echo but I want to use it later to launch an internet navigator with the port number ) with xargs it does not work.

gollum -p0 2>&1|  sed  -n -e "s/.*port=//p" | xargs -n1  echo  

Nothing happen. Do you know why, or do you have another idea to do the same thing.

Thank you for your help.

1

There are 1 answers

2
Charles Duffy On

This is easy to do if you don't want your server to keep running in the background. If you do, one approach is to use process substitution:

#!/bin/bash
#      ^^^^- not /bin/sh; needed for >(...) syntax

gollum -p0 > >(
  while IFS= read -r line; do
    # start a web browser here, etc.
    [[ $line = *"port="* ]] && echo "${line##*port=}"
    # ...for instance, could also be:
    # open "http://localhost:${line##*port=}/"
  done
) 2>&1 &

...if you want to read only the first line containing port=, then break out of the loop in the handler, and handle the rest of stdin before it exits (this is as easy as using cat >/dev/null).