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'm using svn export as part of a packager script for my application, and it looks like this command, like many others, doesn't have any kind of progress bar.

I have two choices at the moment:

  • using it without options, and watch it printing thousands of lines
  • using --quiet, and not seing anything until it completes.

Is there a way to at least show the number of lines output by the command, in real time? Such as:

Exporting SVN directory ... 1234 files

And see this number 1234 increment in real time? I can imagine piping the output to a command that would do just this, but which one?

share|improve this question
add comment

3 Answers 3

yourcommand | { I=0; while read; do printf "$((++I))\r"; done; echo ""; }

Or put the bracketed section in a shell script. Note that this only works if your shell actually supports the preincrement operator, like bash or ksh93 or zsh. Otherwise you'll have to increment $I and then print it (as in I=$((I+1));printf...). Also, if printf isn't a builtin with your shell (it's a builtin with current bash), you could use echo -ne or print -n instead for better performance. You just want to suppress the newline and have the \r interpreted as an escape character.

share|improve this answer
    
Oh, I'll never make myself learn bashscripting with all its ugly = and ` = ` differences and quirks. :) Why wouldn't they replace it with python-like-syntaxed language... –  Bob Oct 6 '13 at 18:12
    
Hey, I know, what! You can add carriage return symbol to each new line you print, and it won't flood the screen, it will just overwrite the previous line. –  Bob Oct 6 '13 at 18:22
    
That's why the printf ends with a \r. And what happens if you do echo -ne "$I\r" or print -n "$I\r". :) I used printf, however, because it defaults to not printing a newline at the end, so the \r just moves back to the beginning. Not all echo implementations support the -e or -n argument, unfortunately. –  dannysauer Oct 6 '13 at 19:02
1  
This also works with the pdksh version that OpenBSD uses for /bin/sh. –  kurtm Oct 6 '13 at 19:06
    
For the rest of this, putting a series of commands inside {} groups them together like an inline function. $(())`` does math expansion. And the rest is just a standard shell while loop. I guess it's worth noting that read` takes one line from STDIN, storing it in $REPLY if no other var is specified. Since the whole thing is in {}, read's stdin is connected to the output of the pipeline. So the contents of the loop happen once per line. Then there's a plain echo at the end to print a newline when it's done reading (when SDIN closes). –  dannysauer Oct 6 '13 at 19:08
show 8 more comments

This is a rough idea but you could use the pv command to count the number of lines as they're going by and display that to the screen. pv among it's many switches has a -l switch which counts each line as it goes through.

Example

Here I'm using a while loop to simulate some files from your SVN output.

$ for i in $(seq 100); do echo "file$i"; sleep 2; done | pv -l -c >/dev/null
   3 0:00:05 [0.99/s ] [      <=>             

It will keep overwritting the output line like this:

  18 0:00:36 [   0/s ] [                                     <=>                                                                  ]

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]
share|improve this answer
    
I was unaware of pv. Hooray for learning stuff! –  dannysauer Oct 6 '13 at 19:16
    
@dannysauer - pv is worth spending some time learning, it allows anything that goes through a pipe to be gauged and displayed. –  slm Oct 6 '13 at 19:55
    
I installed it after I read the comment and have been playing with it. Eighteen years using Linux, and there's still always new stuff to discover. :) –  dannysauer Oct 6 '13 at 20:07
add comment

You can run your command in background as a job and redirect its stdout (and stderr optionally) to a logfile: command > logfile & where & designates job (if stderr too, say &> instead of >).

Then you can use wordcount utility to count the number of lines in your logfile with wc -l.

To show the change of state in one dynamically changing line, you could use something like while true; do echo -en '\r'; wc -l logfile; sleep 1; done, but I can't force bash to draw \r carriage return to kill the contents of the previous line.

See this question, it's nearly a duplicate: http://stackoverflow.com/questions/2388090/how-to-delete-and-replace-last-line-in-the-terminal-using-bash

share|improve this answer
1  
But he wants a real-time display that keeps incrementing, which is not what wc does. –  kurtm Oct 6 '13 at 18:12
    
@kurtm eh, what he wants much more is not to get his screen flooded with results of printf/print/echo as suggested by danny. :) Of course, he could use less, but I suppose, he can afford to say wc -l logfile everytime he gets impatient. I think, playing with ncurses or clearing the screen is an overkill here. –  Bob Oct 6 '13 at 18:18
    
Well, yes. He doesn't want it flooded, but he wants to know progress, otherwise he could just use the --quiet. –  kurtm Oct 6 '13 at 18:32
    
@kurtm see update: can you help to debug my echo -e 'r' command? It should erase the previously printed contents of line, so that it dynamically changes, but I can't force it to do that :( –  Bob Oct 6 '13 at 18:35
    
You want to also add the n option to echo which suppresses the trailing newline. –  kurtm Oct 6 '13 at 18:39
show 2 more comments

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.