Part 1

Say I have a command my_command that outputs multiple lines.

I would like to capture the first line of my_command's output as soon as it's ready in a script, while keeping my_command running.

I thought something like this would work:

# Get a code that `my_command` prints in its first line
parsed_first_line=`my_command | grep -oEe '[0-9]+'` 
echo 'Here is the first line ' $parsed_first_line

but it doesn't. The echo statement is only reached only once my_command has fully finished, which is not what I want.

Part 2

Getting into more details: Imagine my_command is actually a command that connects my shell to a remote shell. Would this change in any way our solution to Part 1?

In case the details matter, my_command is actually a one-line command:

bsub /bin/zsh.

This is a Platform LSF command that submits a job from a login machine (an interactive zsh shell in our case) to a remote grid. Once the submited job gets an open slot on the grid, LSF dispatches it, giving me an interactive shell on the remote machine.

The first thing bsub does is output the job ID of my job on the remote queue (this is what I hope to parse in my script), and then once a slot is open, it dispatches my job.

I'm wondering if a trivial solution to Part 1 would work for Part 2


You use read to get one line of input at a time. You can do something like this:

my_command | { 
  read line
  line=$(grep -oEe '[0-9]+');
  if [ $line ]; then
    echo 'Here is the first line ' $line
  #possibly read more from my_command, transfer control to another program via `exec`, etc...

Why don't you just pipe to head -1?

# Get a code that `my_command` prints in its first line
# parsed_first_line=`my_command | grep -oEe '[0-9]+'`
parsed_first_line=$( my_command | head -1 | grep -oEe '[0-9]+' )
echo 'Here is the first line ' $parsed_first_line

This also lets my_command finish, but it only brings back the first line, which it can then match against your grep.


This is for bash, zsh may be a bit different:


# We'll need a temporary file.

# Start the process in the background
my_command > $TMPFILE &

# Get its pid so we can clean up that temp file later.

# Wait for the first line of output
first_line=`head -n1 $TMPFILE | grep -oEe '[0-9]+'`
while [ -z "$first_line" ]; do 
    # Don't technically need this, but it'll prevent the system from grinding.
    sleep 1
    first_line=`head -n1 $TMPFILE | grep -oEe '[0-9]+'`

echo Result: "$first_line"

# Clean up that temp file.
wait $PID

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.