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.
A friend wrote a script for me and it seams to work on his server but it does not on mine.
The script is suppose to process a data file and pull a single line out and make a separate file out of it. Each line in the file begins with a number followed by a double pipe as in " 2||Some text." It is suppose to pull the lines one at a time up to the limit set in a different place in the script. And there are a few variables inside the data file that need to be filled correctly. That is about the extent of what this does. It is part of a larger project.
So far I have not been able to get it to do anything but "not generate any files" or "generate the files but all with the same content." Grrr.
At one point it did work briefly when I changed the grep to egrep. I think something may have gotten deleted when I was copying parts of it out to enable other functionalities that I wanted. So I may have broked it myself.
Code:
#! /bin/bash
STORDIR="${HOME}/BDay/Dev"
BINDIR="${HOME}/BDay"
TMPDIR="${HOME}/BDay/Dev"
BIN="/bin"
# Temporary Variables
Name="John"
AGE="54"
Delay="1440"
Domain="altell"
PNumber="123456789"
COUNT="54"
#Number of times to send blessing, based on age
Count="56"
#set -x
# Delay=$((60*$(($(($TotalDayMinutes))/$(($AGE))))))
#Processing loop
#
#Processing loop to generate blessings
#
I=0
COUNT=0
while [ ${I} -lt ${Count} ]; do
#for now, assumes all blessings are generic. No M/F, Age, or relational component branches
I=$(($I+1))
#
#Get Blessing from Blessings file
#
BlText=`egrep -e "^${I}|" ${STORDIR}/Blessings.txt`
if [ "${BlText}" == "" ]; then
BlText="999||You have lived so long that you have already received every blessing humanly possible. It is time to share that blessing and your wisdom with the world."
COUNT=${I}
I=999
fi
#
#Convert variables in the blessings to values
#
Blessing=`echo ${BlText//@AGE@/$AGE}`
Blessing=`echo ${Blessing//@NAME@/$Name}`
Blessing=`echo ${Blessing//@SEX@/$Sex}`
# Column 1 is the plessing ID, Column 2 is for any flags for decision making, Column 3 is the acutal blessing.
Blessing=`echo ${Blessing} | awk -F"|" '{printf("%s",$3)}'`
#
#Store blessing to be sent in temporary file
#
echo "${Blessing}" > $TMPDIR/$Name.blessing.$I.txt
done
if [ "${COUNT}" == "0" ]; then
COUNT=${AGE}
fi
echo "${BIN}/bash ${BINDIR}/send_blessing.sh ${Name} ${AGE} ${Delay} ${Domain} ${PNumber} ${COUNT} &" >> ${TMPDIR}/myjobs.sh
chmod +x ${BINDIR}/send_blessing.sh
exit
I have not had any success trying to debug this. Some lines make sense to be but others don't. Inserting a "set -x" results in processing the data file however many times count is set. Looking through the scroll black does not yeild anything that I can say "yup, that's an issue".
Because of the debug fail I have no idea what to even search for to see if I can fix it myself.
Count and COUNT actually are two separate variables that serve separate purposes in other parts of the larger project. One and I forget which remains constant and the other is incremented so the loop is processed the correct number of times.
Well I see a few issues but not sure which points to your problem:
1. Space between shebang and interpreter ... probably won't error but not the accepted norm
2. Whilst case sensitivity is used for bash variables, you can already see how naming 2 or more variables the same can cause issues when viewed by other parties
3. Prior to the while loop you have the following which will cancel each other (and not sure why one is a string and the other a number):
Code:
COUNT="54"
COUNT=0
4. Use (()) for arithmetic operations AND tests
Code:
while [ ${I} -lt ${Count} ]; do
while (( I < Count )); do
5. You can use standard increment options inside (())
Code:
I=$(($I+1))
(( I++ ))
6. Using $() is much clearer and more extensible than ``
7. The -e is superfluous in its current use (but i see no issue with leaving it in), however the change to egrep (which is deprecated and should be grep -E) has cause side effects:
Code:
grep -e "^${I}|" ${STORDIR}/Blessings.txt) - - This looks for a digit at the start of the line and followed by a pipe
egrep -e "^${I}|" ${STORDIR}/Blessings.txt) - - This looks for a digit at the start of the line OR ... as there is nothing after the pipe, my grep -E interpreted this to mean anything and hence spewed back the entire file
8. [[]] over [] (see here for some info) and use built in tests when looking at variable values
Code:
if [ "${BlText}" == "" ]; then
if [[ -z "${BlText}" ]]; then
9. As you have identified the column information, the below can be simplified to exclude the call to awk:
10. Obviously we have a cut down listing of the full script, but the chmod at the end makes little sense unless this file is being deleted elsewhere and also populated somewhere else as it is not done in this part.
3. COUNT="54" is a temporary just for testing as that variable is set in a different part of the larger project and serves other purposes. I have no idea why in this section it is then zeroed out. Also looking through I see that it need not be set prior to this section being run. So I removed it from the temporary variable list.
4. That is a lot easier for me to understand what it does.
5. Trying
6. I was somewhat aware of that. But the original author did not use it, so for consistencies sake I will not change it unless that proves to be the fix, at which time I will probably break it again in the process of making the script uniform.
7. Trying grep -E
8. Same as 6
9. Took me a while to figure out what that was doing. It had me all confused before your insight.
10. This one is all me. If you look through the whole project you will see that the first script that is run generates a csv data file which is then read by the second script (which this peace is part of), and generates a third script ( one of the ones generated here). That third script is then run at a specific time and calls a 4th script to process out the batch job to completion.
The original second script did not make the file executable so it had to be done by hand, kind of a pain, so I added that line. I have been working on adding the functionality of automating the batch job but there are issue with hdate converting a Hebrew dates during leap years back into Gregorian dates. I think it is actually a bug in hdate because it is not processing the leap-months, which are numbered 13 and 14, correctly when trying to convert backwards as the man page says it should. I have posted to the mailing list but not heard back.
So now for the test. One more note first. I am using a pristine Debian Wheezy vm now.
#!/bin/bash
STORDIR="${HOME}/BDay"
BINDIR="${HOME}/BDay"
TMPDIR="${HOME}/BDay"
BIN="/bin"
# Temporary Variables
Name="John"
AGE="54"
Delay="1440"
Domain="altell"
PNumber="123456789"
#Number of times to send blessing, based on age
Count="3"
#set -x
# Delay=$((60*$(($(($TotalDayMinutes))/$(($AGE))))))
#Processing loop
#
#Processing loop to generate blessings
#
I=0
COUNT=0
while (( I < Count )); do
#for now, assumes all blessings are generic. No M/F, Age, or relational component branches
(( I++ ))
#
#Get Blessing from Blessings file
#
BlText=`grep -E "^${I}|" ${STORDIR}/Blessings.txt`
if [ "${BlText}" == "" ]; then
BlText="999||You have lived so long that you have already received every blessing humanly possible. It is time to share that blessing and your wisdom with the world."
COUNT=${I}
I=999
fi
echo " # 1 ${BlText}"
#
#Convert variables in the blessings to values
#
Blessing=`echo ${BlText//@AGE@/$AGE}`
Blessing=`echo ${Blessing//@NAME@/$Name}`
Blessing=`echo ${Blessing//@SEX@/$Sex}`
# Column 1 is the blessing ID, Column 2 is for any flags for decision making, Column 3 is the acutal blessing.
# Blessing=`echo ${Blessing} | awk -F"|" '{printf("%s",$3)}'`
Blessing="${Blessing##*|}"
#
#Store blessing to be sent in temporary file
#
echo "${Blessing}" > $TMPDIR/$Name.blessing.$I.txt
done
if [ "${COUNT}" == "0" ]; then
COUNT=${AGE}
fi
echo "${BIN}/bash ${BINDIR}/send_blessing.sh ${Name} ${AGE} ${Delay} ${Domain} ${PNumber} ${COUNT} &" >> ${TMPDIR}/myjobs.sh
chmod +x ${BINDIR}/send_blessing.sh
exit
I have tried about every combination of -e -E egrep gerp that I can think of. It either dumps the whole data file into BlText or the "999 error text" I even tried adding an extra | with no joy.
Could it be the | (pipe)? Maybe there should be a different separator like a ,(comma) in the data file to search for. There must be another way to pull the proper data out of the file and dump it into BlText for further processing.
I have tried about every combination of -e -E egrep gerp
-e just says the next argument is a pattern, so it only really matters if you pass more than 1 pattern or your pattern starts with a "-". grep -E is the same as egrep.
AS ntubski has said and myself in point 7 of my previous post, grep is all you really need here to have the desired affect as the pipe will be treated as just another character.
My suggestion, like when doing any bash scripting, would be test that command in isolation on the command line. Remembering that the script is just a way to put a whole lot of
commands in the same place, so if it work on the command line there should be no real reason not to work in a script (generally)
That made it process correctly. I really don't know why I could not get grep/egrep to work.
My only concern with the above is when the data file is broken up into smaller more relevant to specifics that it will still work. But I will cross that bridge when I get to it.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.