ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
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.
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?
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.
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.
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
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.
[...]
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.
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.
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.
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
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.