LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-28-2016, 07:40 AM   #1
rbees
Member
 
Registered: Mar 2004
Location: northern michigan usa
Distribution: Debian Squeeze, Whezzy, Jessie
Posts: 921

Rep: Reputation: 46
Generate a script from a script?


Ladies & Gents

I have a bash script that makes a fifty day count after Passover and using text-to-speech makes an announcement over the PA system to remind us of just which day of the count it is. It's a Jewish thing, so......

The issue I have is that I want this announcement to be at or near sunrise in the morning but that conflicts with the morning reading which happens at 6:30 every morning and is an "alarm clock" of sorts. Some mornings the reading takes 15 minuets, other mornings a half hour or more, depending on what day of the month it is. So I need to pause that reading for the "count announcement" and then continue it.

The other half of the issue is that because the "solar" cycle and the "lunar" cycle shift around each other sunrise in any given year may be at a time that will not conflict with the morning reading. For instance this year the solar cycle is ahead of the lunar cycle by thirty days or so, subtracting a couple minuets a day means that the announcement conflicts early in the count and will cease to be a conflict with in a couple weeks because sunrise will be before the morning reading time.

Because the count changes per which day it is I don't see it a practical to have a pre-made file to make the announcement. And killing the morning reading like the radio is not an option. There are too many things that change. So I want to generate that file as part of the scheduling process. Assuming that the variables are properly filled is this code likely to work if I incorporate it into the function that generates the announcement?

Or perhaps there is a better way?

I would normally test before posting but I am hoping to avoid all the work of building a test script for something that will not work.

Code:
echo "#!/bin/bash"
    echo "if pgrep espeak; then" >> $TMPDIR/$3 
        echo "pkill -SIGSTOP espeak" >> $TMPDIR/$3
        echo "sleep 10" >> $TMPDIR/$3
        echo "amixer set Master 70%" >> $TMPDIR/$3
        echo "mpg123 $HOME/bin/shabbat/music/ZvukPobedyShofar.mp3" >> $TMPDIR/$3
        echo "sleep 3" >> $TMPDIR/$3
        echo "$STORDIR/omershofar" >> $TMPDIR/$3
        echo "$COMMAND \"Today is $2 days, which is $WEEK weeks and $EXTRA days of the Ohmare." >> $TMPDIR/$3
        echo "$BLESS" >> $TMPDIR/$3
        echo "amixer set Master 30%" >> $TMPDIR/$3
        echo "sleep 20" >> $TMPDIR/$3
        echo "pkill -SIGCONT espeak" >> $TMPDIR/$3
        
    echo "else" >> $TMPDIR/$3       
        echo "killall -9 mpg123" >> $TMPDIR/$3
        echo "sleep 10" >> $TMPDIR/$3
        echo "amixer set Master 70%" >> $TMPDIR/$3
        echo "mpg123 $HOME/bin/shabbat/music/ZvukPobedyShofar.mp3" >> $TMPDIR/$3
        echo "$STORDIR/omershofar" >> $TMPDIR/$3
        echo "$COMMAND \"Today is $2 days, which is $WEEK weeks and $EXTRA days of the Ohmare." >> $TMPDIR/$3
        echo "$BLESS" >> $TMPDIR/$3
        echo "amixer set Master 30%" >> $TMPDIR/$3
        echo "sleep 20" >> $TMPDIR/$3
        echo  "mpg123 http://216.118.106.247:7000" >> $TMPDIR/$3
        
        echo "fi" >> $TMPDIR/$3

    chmod +x $TMPDIR/$3
Thanks
 
Old 04-28-2016, 07:54 AM   #2
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by rbees View Post
Or perhaps there is a better way?

I would normally test before posting but I am hoping to avoid all the work of building a test script for something that will not work.
There are always better ways. Mine is that you do your normal thing and test before posting, since you clearly have programming ability. And you don't need to write a test script, you can run and test your script live, or edit it to alter the conditions and test them individually.

If the name of your script is espeak, then you'll be self killing it.

Everything's $3, $3, $3 and I saw at least one $2.

But where's $1 being used, ever? Not that, that's a problem, just weird, IMHO.
 
Old 04-28-2016, 08:39 AM   #3
rbees
Member
 
Registered: Mar 2004
Location: northern michigan usa
Distribution: Debian Squeeze, Whezzy, Jessie
Posts: 921

Original Poster
Rep: Reputation: 46
Thanks rtmistler

The code is part of a larger function which is in turn called by a different function and has $1, $2, and $3 passed to it when it is called.

Also running this test code as part of the whole script is not practical as the larger script is 1100 lines and generates maybe 30 at jobs which then have to be deleted. Yes I can do that but it is a pain in the ***. It is more practical to make a much smaller script to test with. Yes the commands can be run from the command line, and have been.

"espeak" is actually the name of the text-to-speach software not my script.

My question, since I have never tried to generate a "script from within a script", is will something like this work?

Is it going to have the correct permissions to be run by "at" when the time comes?

Will the larger script that generates it be able to delete it when it is run the following week and does its "clean up" from the last run?

Or is there a better way to create a bash script from within a bash script?
 
Old 04-28-2016, 08:44 AM   #4
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Anything you can do on the command line, you can do within a script. It is in fact easier because in the script you don't have to type it manually.

Echoing stuff to a file, as you're doing, is valid in the command line, as in the script.

Since you know the destination as $3, then you can also perform command line actions such as: chown, chmod, mv, cp, rm, and so forth. All that stuff is valid in the script. In fact, it's probably a great idea to check for the existence, versus not of $3 and then act accordingly, such as your first echo uses the create directive ">" versus the create/append ">>". And consider generating that script in a safe, or "draft", location and then move it, and give it proper permissions and ownership once you're done with creating it. Note that if you fail somewhere in the middle of the creating part, then you have done nothing destructive because it would be in a benign, unused location.
 
1 members found this post helpful.
Old 04-28-2016, 08:54 AM   #5
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
I don't quite understand why writing a new script is useful, but I'd suggest using a here document instead a whole bunch of echo calls, it will read better.
 
Old 04-28-2016, 11:37 AM   #6
rbees
Member
 
Registered: Mar 2004
Location: northern michigan usa
Distribution: Debian Squeeze, Whezzy, Jessie
Posts: 921

Original Poster
Rep: Reputation: 46
Thanks rtmistler, that is what I needed to know before building and testing. Sometimes google does not reveal the answer to the simplest of questions

I do like the notion of generating the script in an unused location and making it +x there before putting it with the other files that get called by at.

So I guess it is time to make a test script.

ntubski,
If there is a different way to pause/continue the "espeak" process at the correct time with out having to generate an executable text file I don't know about it. I suppose I could create a permanent script to pause it then just call it in the text file, but a text file has to be generated for each day with the correct counting in it for that day and it needs to be processed at a specific time which changes according to when sunrise is day by day. If that time conflicts with the morning reading then the morning reading needs to be paused and restarted. If it does not then the radio stream is active and it needs to be killed then restarted. And this is all in relation to the Hebrew calender not the civil calender we use in our day to day life.

It seams to me that executing a pause/resume or kill/start command on a non-existent process is not the best use of cpu even though probably harmless, hence a script that test for the process and act on it if true.

Is using a "here-document" more efficient cpu usage than "echo"?
Something more like this, if google is still being my friend today.
Code:
    cat << EOF > $TMPDIR/$3
#!/bin/bash
if pgrep espeak; then  
     pkill -SIGSTOP espeak 
     sleep 10 
     amixer set Master 70% 
     mpg123 $HOME/bin/shabbat/music/ZvukPobedyShofar.mp3 
     sleep 3 
     $STORDIR/omershofar 
     $COMMAND \Today is $2 days of the Ohmare. 
     $BLESS 
     amixer set Master 30% 
     sleep 20 
     pkill -SIGCONT espeak 
else        
     killall -9 mpg123 
     sleep 10 
     amixer set Master 70% 
     mpg123 $HOME/bin/shabbat/music/ZvukPobedyShofar.mp3 
     $STORDIR/omershofar 
     $COMMAND \Today is $2 days of the Ohmare. 
     $BLESS 
     amixer set Master 30% 
     sleep 20 
     mpg123 http://216.118.106.247:7000 
fi
EOF
    chmod +x $TMPDIR/$3
 
Old 04-28-2016, 11:50 AM   #7
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
Quote:
Originally Posted by rbees View Post
If there is a different way to pause/continue the "espeak" process at the correct time with out having to generate an executable text file I don't know about it.
At the place where you would execute the script, why can't you just execute the same code directly, without writing it to a separate file first?

Quote:
It seams to me that executing a pause/resume or kill/start command on a non-existent process is not the best use of cpu even though probably harmless, hence a script that test for the process and act on it if true.
The test probably costs as much as sending the signal.

Quote:
Is using a "here-document" more efficient cpu usage than "echo"?
Possibly, but more importantly it's a lot more readable.
Quote:
Something more like this, if google is still being my friend today.
[...]
Yup.
 
1 members found this post helpful.
Old 04-28-2016, 12:52 PM   #8
rbees
Member
 
Registered: Mar 2004
Location: northern michigan usa
Distribution: Debian Squeeze, Whezzy, Jessie
Posts: 921

Original Poster
Rep: Reputation: 46
Quote:
At the place where you would execute the script, why can't you just execute the same code directly, without writing it to a separate file first?
When did "at" gain the ability to execute code that was not in an executable file? That was one of the problems I had when I first started this project.

A sample of what currently gets generated and processed by "at" at sunrise, called scripts in red. "espeak" its self is executable as well as amixer.

Code:
/home/user/bin/shabbat/stopradio
/home/user/bin/shabbat/data/omershofar
espeak -s 105 -ven-us+m5 "Today is 6 days of the Ohmare.
We don't say the Ohmare blessing during the daylight hours"
amixer set Master 30%
/home/user/bin/shabbat/radio
Generating this same file as a script gets rid of those calls to external scripts. If I were to create two more to handle espeak then there would be 5 calls instead of processing it all "in house".

The main script (some 1100 lines) runs once a week and generates for each day a
morning reading, an evening reading, for Friday a candle lighting announcement, for Shabbat (saturday) the readings and Havdalah (separation). Then you have to add in the readings, announcements, candle and havdalah for the Festivals. This particular announcement that I am working on is the 50 day counting between Passover and Feast of Weeks which adds 14 at jobs per week. If every possible job is generated there are about 30, although most weeks there are only 17 if I am adding right.

Hope that helps
 
Old 04-28-2016, 12:56 PM   #9
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939
1,100 lines? Of [i]Bash?!{/i]

Well, the first thing that I would suggest is that you probably should be using a "real" programming language to write this rather-complex system.

Second, I'm not warming-up to the idea of "self-generated scripts" as being the best-all-around way to handle this requirement.
 
Old 04-28-2016, 01:16 PM   #10
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
Quote:
Originally Posted by rbees View Post
When did "at" gain the ability to execute code that was not in an executable file? That was one of the problems I had when I first started this project.
Oh, I missed that you were running things from "at". But I still don't quite understand

Quote:
Because the count changes per which day it is I don't see it a practical to have a pre-made file to make the announcement.
Any file that can generate all possible files to make announcements should be just as complicated as a single pre-made file that can make all possible announcements directly.
 
Old 04-28-2016, 01:19 PM   #11
rbees
Member
 
Registered: Mar 2004
Location: northern michigan usa
Distribution: Debian Squeeze, Whezzy, Jessie
Posts: 921

Original Poster
Rep: Reputation: 46
Quote:
1,100 lines? Of [i]Bash?!{/i]
I hear that! When I started this some years ago I never expected it to get so big. Three fourths of those line are the processing engine that converts some antiquated htm files into text files that espeak can process, and it has take parts/all of as many as five htm files to generate one text file.

I am sure there is streamlining that it could use, but that is beyond me.

I do have plans on porting it to perl but time always seams to get in the way. And I have to actually learn perl. I have read a beginning perl book but that time thing......

Quote:
Second, I'm not warming-up to the idea of "self-generated scripts" as being the best-all-around way to handle this requirement.
I am very willing to look at a different method. I am just not aware of one with out porting it, or calling external scripts which seams rather clunky to me.
 
Old 04-28-2016, 01:21 PM   #12
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
If the count is so important and does not rely on being at a specific time ("I want this announcement to be at or near sunrise"), why not just have it said prior to the reading at 0630?

As I have seen many different pieces of this script as it has grown, I also considered asking, perhaps you should look at having 2 scripts, one to calculate all the timing requirements (using hdate I believe)
and the second being the one called by 'at' which then performs the necessary tasks (count info, readings, so on).

The idea above would also alleviate the need for many additional files as the espeak could be called directly to say the required information ... just a thought


@sundialsvcs - I am never telling you how many lines are in 2 of the scripts I developed a couple of years ago ... all in bash :P
 
1 members found this post helpful.
Old 04-29-2016, 07:48 AM   #13
rbees
Member
 
Registered: Mar 2004
Location: northern michigan usa
Distribution: Debian Squeeze, Whezzy, Jessie
Posts: 921

Original Poster
Rep: Reputation: 46
Ladies & Gents

As always, Thanks for the guidance you provide.

So following the advice in this thread I opted to abandon the self generating scripts in favor of calling other smaller pre-made scripts. I got partial success.

As can be seen in this generated output file that calls said scripts the correct data is placed in the file.

Code:
/home/user/bin/shabbat/stopradio
/home/user/bin/shabbat/data/pauseEspeak
/home/user/bin/shabbat/data/omershofar
espeak -s 100 -ven-us+m2 "Today is 6 days of the Ohmare."
We don't say the Ohmare blessing durring the daylight hours"
amixer set Master 30%
/home/user/bin/shabbat/data/resumeEspeak
But the last line does not get executed. The file resumeEspeak does exist and is executable. It is owned by the user and readable by others and group (733 I think) as are the other scripts in that directory.

Code:
#!/bin/bash
if pgrep espeak; then
    pkill -SIGCONT espeak 
else
    radio (this line may need a full path to function correctly)
fi
If I execute this script by hand then it does what it is suppose to as there is a paused espeak process left running for it to act on.

In the older version of the main script I was using "echo" to write to the output file, but this version uses here-document. When I was having this same kind of a problem before I had to "" some of the variables to get it to work correctly, but that does not seam to relate here.

The code that generated the output file

Code:
if Element_In "$2" "${omer[@]}" ; then
    Get_Reader
    cat << EOF > $TMPDIR/$3
    $BINDIR/stopradio
    $STORDIR/pauseEspeak
    $STORDIR/omershofar
    $COMMAND "Today is $2 days of the Ohmare."
    $BLESS
    amixer set Master 30%
    $STORDIR/resumeEspeak
EOF
Ahh, such a simple fix, note the " at the end of the espeak line in the output file. That causes espeak to stop and the next line is not executable by its self.
 
Old 04-29-2016, 09:19 AM   #14
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
You could try single quotes around the text. The $2 will still be present and expanded due to the heredocument not being quoted to preserve items.
 
Old 04-29-2016, 09:23 AM   #15
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by rbees View Post
But the last line does not get executed. The file resumeEspeak does exist and is executable. It is owned by the user and readable by others and group (733 I think) as are the other scripts in that directory.
733 is owner rwx, group/world wx. Should be 755 to be r-x for group and world.

That would be the problem, however double check because I'm thinking that having a umask which would create 733 permissions is rather awkward. Typical umask is 022 to make 755 permissions.
 
  


Reply



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] Script to generate 200 files bkone Programming 11 07-23-2015 09:58 AM
Script to generate EXCEL sheet by shell script dani1234 Linux - Newbie 15 09-14-2014 07:36 PM
[SOLVED] Generate md5 password in a script Rogue45 Linux - Newbie 2 07-31-2012 03:33 PM
[SOLVED] Need script to generate vouchers suse_nerd Programming 3 06-25-2010 10:13 AM
Using firestarter to generate an iptables script jc materi Linux - Security 2 03-28-2005 10:15 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:07 AM.

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