LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 10-20-2012, 03:37 AM   #1
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Fill effect in a shell script


Good morning everyone..
It's a wierd question, but I am curious about it.
Let's say I have a script
Code:
for i in $file
do
echo "Command is working..."
<command>
done
You can see, I have used 3 dots in echo. So in a shell script is it possible to fill such an effect that until the command works, the 3 dots keep blinking? So it make an effect that some processing is going on. Although we used to see such effects in GUIs, but not in terminals. But can we do this?
Any opinion is most welcome!!

Last edited by shivaa; 10-20-2012 at 03:39 AM.
 
Old 10-20-2012, 03:51 AM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
As long as <command> doesn't produce any output, you can do some basic "animation" with carriage return "\r". This is a special character that moves the cursor the beginning of the line, so you can then overwrite the previous contents:
Code:
blink=0
while true ; do
    if ((blink)) ; then
        echo -n $'\rworking...'
    else
        echo -n $'\rworking   '
    fi
    sleep 0.5
    ((blink = !blink))
done
A more common thing is a sort of "hourglass" type animation:

Code:
#!/bin/bash
frames=('|' '/' '-' '\')
frame=0

while true ; do
    echo -n $'\r'"working... ${frames[frame]}"
    sleep 0.2
    ((frame = (frame + 1) % ${#frames[@]}))
done
 
2 members found this post helpful.
Old 10-20-2012, 10:58 AM   #3
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800

Original Poster
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Thanks, but how can I impliment this code in my script? My test script is:
Code:
for i in $file
do
echo "Command is working...."
cmd=$(more $i | grep -w "20/Oct/2012" | wc -l)
echo $cmd
done
Suppose erroelogs i.e. $i is very large log file and command is taking 4 or 5 minutes to accomplish it, then in this period it want to insert that animation with my echo statement "Command is working....". I tried to add your code but failed...
Could you show me the way by modifying my script? Thanks a lot again!

Last edited by shivaa; 10-20-2012 at 11:03 AM.
 
Old 10-20-2012, 11:17 AM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
You can put the blinking loop in the background:
Code:
#!/bin/bash

blinker() {
    blink=0
    while true ; do
        if ((blink)) ; then
            echo -n $'\rworking...'
        else
            echo -n $'\rworking   '
        fi
        sleep 0.5
        ((blink = !blink))
    done
}

for i in $file
do
    blinker &
    blinker_pid=$!
    # piping from more was redundant, and grep's -c counts matching
    # lines so wc is not needed. The -F tells grep the pattern is just
    # a plain string, which may be more efficient to search for than a
    # regex.
    cmd=$(grep -F -c -w "20/Oct/2012" "$i") 
    kill $blinker_pid
    echo $cmd
done
 
2 members found this post helpful.
Old 10-20-2012, 04:28 PM   #5
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
i heard them referred to as spinners. this is my favorite spinner design:
Code:
frames=('\__' '_|_' '__/' '_|_')
 
1 members found this post helpful.
Old 10-20-2012, 11:52 PM   #6
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800

Original Poster
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Quote:
Originally Posted by schneidz View Post
i heard them referred to as spinners. this is my favorite spinner design:
Code:
frames=('\__' '_|_' '__/' '_|_')
Hmmm.. it's not so impressive! but what @ntubski has suggested is a really good interpretation of running process i.e frames=('|' '/' '-' '\').
Is there any way that same thing can be done with same type of symbols? I mean somthing like this:
.(wait some mili seconds).(wait).(wait)... Then again first .(wait) and so on...
 
Old 10-21-2012, 07:00 AM   #7
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
Quote:
Originally Posted by meninvenus View Post
Hmmm.. it's not so impressive! but what @ntubski has suggested is a really good interpretation of running process i.e frames=('|' '/' '-' '\').
Is there any way that same thing can be done with same type of symbols? I mean somthing like this:
.(wait some mili seconds).(wait).(wait)... Then again first .(wait) and so on...
yeah:
Code:
 frames=('.   ' '..  ' '... ' '....')
 
1 members found this post helpful.
Old 10-21-2012, 09:48 AM   #8
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800

Original Poster
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Quote:
Originally Posted by schneidz View Post
yeah:
Code:
 frames=('.   ' '..  ' '... ' '....')
Exactly :-). This is what I was looking for!!
In addition to your frames variable, I just added one more empty values as:
Code:
frames=('    ' '.   ' '..  ' '... ' '....')
And that is what I was looking for. You'd find it more beautiful... like a twinkle twinkle little stars :-)

Thanks a lot Mr. ntubski and many thanks to Mr. schneidz also.
 
Old 10-21-2012, 11:00 AM   #9
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800

Original Poster
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Termination of a function in shell script

Following is my final script:
Code:
#!/bin/bash
## Blinker function
blinker ()
{
frames=('.   ' '..  ' '... ' '....')
frame=0

while true ; do
    echo -n $'\r'"Calculating count ${frames[frame]}"
     sleep 0.2
    ((frame = (frame + 1) % ${#frames[@]}))
done
}

## Script
blinker &
blinker_pid=$!
cmd=`grep -F -c -w "20/10/2012" /tmp/largefile.txt`  ## largefile.txt is a large text file, so command is taking 2 or 3 minutes to finish it. 
echo "Total counts is: $cmd"
kill $blinker_pid
It's working ok and result a correct value but,
Problem 1# In output of the script, it gives me an error,
Quote:
"scriptname...1234 terminated blinker"
Which I want to avoid. So how to stop the function normally, instead of killing it's PID at the end.
Problem 2# If I want to stop the script in between processing using CTRL+C, it's not working and function is keep going on. One way is to kill script's PID, which I don't want. So what's a safe way to stop the script if I want to?

Last edited by colucix; 10-23-2012 at 03:02 AM. Reason: Removed redirection to another thread (threads have been merged here)
 
Old 10-21-2012, 01:26 PM   #10
Rupadhya
Member
 
Registered: Sep 2012
Location: Hoffman Estates, IL
Distribution: Fedora 20
Posts: 167

Rep: Reputation: Disabled
I haven't been able to recreate your #1 issue yet, but you might do this to suppress the message with the following modification.
Code:
kill $blinker_pid 2>/dev/null
I will look at Issue #2 now.
- Raj
 
Old 10-21-2012, 01:33 PM   #11
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800

Original Poster
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Quote:
Originally Posted by Rupadhya View Post
I haven't been able to recreate your #1 issue yet, but you might do this to suppress the message with the following modification.
Code:
kill $blinker_pid 2>/dev/null
I will look at Issue #2 now.
- Raj
Thanks Mr. Raj, I have tried this redirection to /dev/null, but it didn't work.
Meanwhile, I put a exit 0 just as:
Code:
....
....
echo "Total counts is: $cmd"
kill $blinker_pid
exit 0
And it worked fine.
But now my question is, how to terminate a script in between processing, I mean beofore it gets finished?
 
Old 10-21-2012, 01:48 PM   #12
Rupadhya
Member
 
Registered: Sep 2012
Location: Hoffman Estates, IL
Distribution: Fedora 20
Posts: 167

Rep: Reputation: Disabled
Try this.. What the trap command does is it traps the SIGINT signal and passes control to the control_c function.
Code:
#!/bin/bash
## Blinker function
blinker ()
{
frames=('.   ' '..  ' '... ' '....')
frame=0

while true ; do
    echo -n $'\r'"Calculating count ${frames[frame]}"
     sleep 0.2
    ((frame = (frame + 1) % ${#frames[@]}))
done
}
 
control_c()
# run if user hits control-c
{
  kill $blinker_pid 2>/dev/null
  echo -en "\n*** Why did you hit ctrl-c?  I was grepping a large file! ***\n"
  exit 1
}
 
# trap keyboard interrupt (control-c)
trap control_c SIGINT

## Script
blinker &
blinker_pid=$!
cmd=`grep -F -c -w "20/10/2012" /tmp/largefile.txt`  ## largefile.txt is a large
 text file, so command is taking 2 or 3 minutes to finish it. 
echo "Total counts is: $cmd"
kill $blinker_pid 2>/dev/null
I don't know why the redirect to the /dev/null didn't work for you. The redirect to the /dev/null is meant to send the output to a black hole and never be seen again.

- Raj
 
3 members found this post helpful.
Old 10-21-2012, 02:13 PM   #13
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,779

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
The "terminated" message doesn't come directly from the kill command but from the shell when it sees a child process that exited due to a signal. You need to insert this line at the top of the blinker() function:
Code:
trap "exit 0" TERM
Now the function will exit with a zero return code, and you will not get any message.
 
3 members found this post helpful.
Old 10-21-2012, 02:20 PM   #14
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800

Original Poster
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Unhappy

Thank agian Raj. The trap cmd worked fine. I was also awere about this, but I was not sure how to use it this way. You showed me a good way!
 
1 members found this post helpful.
Old 10-21-2012, 02:24 PM   #15
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800

Original Poster
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Quote:
Originally Posted by rknichols View Post
The "terminated" message doesn't come directly from the kill command but from the shell when it sees a child process that exited due to a signal. You need to insert this line at the top of the blinker() function:
Code:
trap "exit 0" TERM
Now the function will exit with a zero return code, and you will not get any message.
I used it, but making no use. My script is working OK without this line. Could you elaborate it little more, please? What difference it can make in above mentioned script (by Raj)?
 
1 members found this post helpful.
  


Reply

Tags
effects, function, script, shell scripting



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] queries about [:digit:] and cp --verbose effect: GNU shell MMaddoxx Linux - Newbie 4 11-09-2011 02:57 PM
Does setting of BASH as the default shell has any effect? msgforsunil Linux - Newbie 7 10-22-2006 10:41 PM
help with shell script - fill an array with values from a file delmoras Linux - General 1 07-17-2006 11:19 AM
Script to Fill In a Website Chryzmo Programming 1 12-15-2005 04:39 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 02:43 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration