Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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

share|improve this question
add comment

3 Answers

up vote 3 down vote accepted

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 ' $parsed_first_line
  fi
  #possibly read more from my_command, transfer control to another program via `exec`, etc...
 }
share|improve this answer
add comment

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.

share|improve this answer
add comment

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

#!/bin/bash

# We'll need a temporary file.
TMPFILE=`mktemp`

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

# Get its pid so we can clean up that temp file later.
PID=$!

# 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]+'`
done

echo Result: "$first_line"

# Clean up that temp file.
wait $PID
rm $TMPFILE
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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