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.

I need to ssh into a server and check for a service to see if it is up and running. What i do is to use ssh and run a command which calls that service and check the output of that command. I want to have a progress bar to show the user that the script is trying to check the status of the service; but I am not able to run the progress bar function while ssh command is not returned from the server! (ssh must wait for the service to fully start before it can check the status) and I miss that part of the progress.

Is there a standard way to deal with such a scenario?

My ssh command is something like this:

State=$(ssh host "app-status")

And it should return something like:

Status OK
share|improve this question

3 Answers 3

up vote 5 down vote accepted

You can run ssh in the background and have it write its output to a FIFO

#! /bin/bash
mkfifo fifo-ssh
(ssh host "app-status"; echo error;) >fifo-ssh &
exec 3<>fifo-ssh
until read -t 1 -u 3 status; do
  echo -n .
done
# if [ "$status" = error ]; then...
share|improve this answer

Alternative to Hauke's that doesn't involve creating a named pipe (and the hassle associated with exclusive access, cleanup... of it), that preserves the exit status, and supports multi-line output:

result=$(
  {
    {
      ssh host app-status >&3 3>&-; echo "$?"
    } | {
      until read -t1 ret; do
        printf . >&2
      done
      exit "$ret"
    }
  } 3>&1
)

should work in zsh, ksh93 and bash ($status is special (an alias for $?) in zsh like in (t)csh).

Above, we've got a subshell ({ ssh ...; echo "$?"; }) whose output goes to the until loop. Nothing is output by that subshell except the $? when ssh returns. ssh output itself goes to $result by way of file descriptor 3 which we've made to point to the pipe that feeds the command substitution.

So, while ssh is running, the read -t1 will timeout, and as soon as ssh returns, read will read the exit status and finish the loop.

More detailed explanation at this question that's a follow up on this one.

share|improve this answer
    
just trying to understand. First 3>&1 fd 3 is opened as a dup of stdout. ssh stdout is set to dup of fd3, then 3 is closed 3>&- stdout from ssh is piped into read loop, which is printed to stderr >&2 Nothing is run in background, so how does this help? –  X Tian Feb 6 at 11:59
    
@XTian, no, see my edit. The fd 3 is only used to carry the original stdout within that command substitution to ssh. The progress loop reads nothing until ssh exits. –  Stéphane Chazelas Feb 6 at 12:12
    
I've opened this up as a new question to avoid clogging this one with comments. –  X Tian Feb 6 at 12:38
    
OP's new question: Please help explain this bash output redirection –  terdon Feb 6 at 12:41

I found out that it is much simpler to run the progress bar in the background instead of the ssh command. Something like this:

function progress {
while :
do
    sleep 1
    echo -e ".\c"
done
}

progress &

PROGRESS_PID=$!

ssh_command_runs_here

status_check_command_here

kill -9 $PROGRESS_PID
share|improve this answer
    
Whether that works depends on the stty tostop setting. –  Hauke Laging Feb 6 at 21:58
    
@HaukeLaging Can you explain more? –  coffeMug Feb 6 at 22:33
    
"Background processes which attempt to read from (write to when stty tostop is in effect) the terminal are sent a SIGTTIN (SIGTTOU) signal by the kernel's terminal driver, which, unless caught, suspends the process." –  Hauke Laging Feb 6 at 22:36
    
Maybe you should find a progress indicator that will die when SIGTERMed or SIGINTed. –  Blacklight Shining Feb 7 at 3:17
    
I have a problem; when i kill the script (Ctrl-C) while progressing, the dots continue to print on the screen! –  coffeMug Feb 7 at 10:16

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.