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 am a copy/paste person and don't really know how to write code. I only know what I want it to do. Most of the code below comes from other working scripts with a few small changes relevant to what I am trying to do. Since the code doesn't work my changes are a "fail".
What this code is suppose to do is take the input day and check to see if it is a Jewish Holiday. So the civil date needs to be converted to a Hebrew date. Hdate will do that and output the Hebrew Holiday, or a blank line.
For example
Code:
:~$ hdate -dhq 5 3 2015
Thursday, 5 March 2015, 14 Adar 5775
Purim
:~$
So I need the 3rd line of the output, or at least I think it is the third line. That's where the data I need is if I redirect the output to a file. I am trying to test if that line has data or is blank. If blank, then loop to check the next day and so on for 7 days.
If there is data in that line then I am trying to compare it to a cvs data file with a listing of the Jewish Holidays to get other data so automated events (not implemented yet) can be scheduled for that day based on that data.
The Code:
Code:
#!/bin/bash
STORDIR="${HOME}/bin/shabbat/data"
set -x
DAY=5
MONTH=3
YEAR=2015
i=1
while [ $i -lt 7 ]; do
YOMTOVE=`echo "$(hdate -dhq $DAY $MONTH $YEAR)" | head -n 3 | tail -n +3 `
echo "$YOMTOVE"
if [[ "$YOMTOVE" != "" ]]; then
grep ^"$YOMTOVE" "$STORDIR"/YomTove.cvs
i=$[$i+1]
DAY=$[$DAY+1]
fi
done
When I run this my shell goes into a open ended loop with this type of output.
After a reboot the code checks the correct date (5 March 2015) the second time the code is run it checks an incorrect date (7 March 2015). No idea why. It also does not seem to be stepping through the while loop.
Last edited by rbees; 02-12-2015 at 02:42 PM.
Reason: formating
What is the best way to make it step over a new month? Something like running a check on $DAY and if it is larger than 28 somehow test $MONTH to see when it will change. Guess I will have to think on it some.
I like that, it looks cleaner too. On the plus side I actually understand what it does.
But now by trying to account for leap years I have made it not work again and I don't understand why. I am getting
Code:
:~$ bin/shabbat/test
bin/shabbat/test: line 90: syntax error near unexpected token `}'
bin/shabbat/test: line 90: `}'
My guess is that I am not following the logic through correctly and I have too many, or not enough "fi" in the right place.
The Current code
Code:
#!/bin/bash
STORDIR="${HOME}/bin/shabbat/data"
DAY=28
MONTH=1
YEAR=2016
# Calculate next day accounting for leap years
function Next_Day
{
if [[ "$DAY" -le "27" ]]; then
let i=i+1
let DAY=DAY+1
exit
elif [[ "$DAY" = "28" ]]; then
case ${ $MONTH } in
1)
FULL="31"
;;
2)
FULL="28"
;;
3)
FULL="31"
;;
4)
FULL="30"
;;
5)
FULL="31"
;;
6)
FULL="30"
;;
7)
FULL="31"
;;
8)
FULL="31"
;;
9)
FULL="30"
;;
10)
FULL="31"
;;
11)
FULL="30"
;;
12)
FULL="31"
;;
esac
if [[ $MONTH == "2" ]];then
rem1=$((YEAR%4))
rem2=$((YEAR%100))
rem3=$((YEAR%400))
if [ ${rem3} = "0" ];then
$FULL="29"
exit
fi
if [ ${rem2} = "0" -a ${rem3} != "0" ];then
# echo "$YEAR Is Not A Leap Year"
exit
fi
if [ ${rem1} = "0" -a ${rem2} != "0" ];then
# echo "$YEAR Is A Leap Year"
$FULL="29"
else
# echo "$YEAR Is Not A Leap Year"
exit
fi
fi
if [ ${DAY} = ${FULL} -a ${MONTH} -lt "12" ]; then
let MONTH=MONTH+1
let DAY=1
exit
elif [ ${DAY} = ${FULL} -a ${MONTH} = "12" ];then
let YEAR=YEAR+1
let MONTH=1
let DAY=1
exit
fi
}
#################
# # Main Code # #
#################
for (( i = 1; i < 7; i++)); do
YOMTOVE=$(hdate -dhq $DAY $MONTH $YEAR | awk 'NR==3')
echo "$YOMTOVE"
if [[ -n "$YOMTOVE" ]]; then
grep ^"$YOMTOVE" "$STORDIR"/YomTove.cvs
# actions based on what holiday it is
fi
done
Next_Day
exit
I went through the logic for the 100th time and made some more changes and cleaned the code up a little but I am still getting the same thing.
Code:
#!/bin/bash
STORDIR="${HOME}/bin/shabbat/data"
DAY=28
MONTH=1
YEAR=2016
# Calculate next day accounting for leap years
function Next_Day
{
case ${ $MONTH } in
1)
FULL="31"
;;
2)
FULL="28"
;;
3)
FULL="31"
;;
4)
FULL="30"
;;
5)
FULL="31"
;;
6)
FULL="30"
;;
7)
FULL="31"
;;
8)
FULL="31"
;;
9)
FULL="30"
;;
10)
FULL="31"
;;
11)
FULL="30"
;;
12)
FULL="31"
;;
esac
if [[ "$DAY" -le "27" ]]; then
(( DAY++ ))
exit
elif [[ ${MONTH} == "2" ]]; then
rem1=$((YEAR%4))
rem2=$((YEAR%100))
rem3=$((YEAR%400))
if [ ${rem3} = "0" ]; then
$FULL="29"
exit
fi
if [ ${rem2} = "0" -a ${rem3} != "0" ]; then
# echo "$YEAR Is Not A Leap Year"
exit
fi
if [ ${rem1} = "0" -a ${rem2} != "0" ]; then
# echo "$YEAR Is A Leap Year"
$FULL="29"
else
# echo "$YEAR Is Not A Leap Year"
exit
fi
if [ ${DAY} = ${FULL} -a ${MONTH} -lt "12" ]; then
(( MONTH++ ))
(( DAY++ ))
exit
fi
elif [ ${DAY} = ${FULL} -a ${MONTH} = "12" ]; then
(( YEAR++ ))
let MONTH=1
let DAY=1
exit
fi
exit
fi
}
#################
# # Main Code # #
#################
for (( i = 1; i < 7; i++)); do
YOMTOVE=$(hdate -dhq $DAY $MONTH $YEAR | awk 'NR==3')
echo "$YOMTOVE"
if [[ -n "$YOMTOVE" ]]; then
grep ^"$YOMTOVE" "$STORDIR"/YomTove.cvs
# actions based on what holiday it is
fi
done
Next_Day
exit
Yes your if's are out of balance. Placing just the if's in vim and formatting it tells me that the last fi is not required, ie the one after exit.
However, I would guess that you have put an additional one in earlier, maybe before the last elif???
Also, you use the round brackets for the for loop and incrementing but then not for testing your values. Whenever working with numbers in bash, use your round brackets, eg.
Code:
elif [ ${DAY} = ${FULL} -a ${MONTH} = "12" ]; then
elif (( DAY == FULL && MONTH == 12 )); then
You can also use standard arithmetic symbols, such as <,>, <= and so on
#!/bin/bash
STORDIR="${HOME}/bin/shabbat/data"
DAY=28
MONTH=1
YEAR=2016
# Calculate next day accounting for leap years
function Next_Day
{
case $MONTH in [13578] | 1[02] ) FULL=31;;
[469] | 1[01] ) FULL=30;;
2) FULL=28;;
esac
if (( DAY <= 27 )); then
(( DAY++ ))
exit
else (( MONTH = 2 )); then
rem1=$((YEAR%4))
rem2=$((YEAR%100))
rem3=$((YEAR%400))
if (( rem3 == 0 )); then
FULL="29"
exit
fi
if (( rem2 == 0 && rem3 != 0 )); then
FULL="28"
exit
fi
if (( rem1 == 0 && rem2 != 0 )); then
FULL="29"
else
FULL="28"
exit
fi
if (( DAY == FULL && MONTH < 12 )); then
(( MONTH++ ))
(( DAY++ ))
exit
elif (( DAY == FULL && MONTH == 12 )); then
(( YEAR++ ))
let MONTH=1
let DAY=1
exit
fi
exit
fi
}
#################
# # Main Code # #
#################
for (( i = 1; i < 7; i++)); do
YOMTOVE=$(hdate -dhq $DAY $MONTH $YEAR | awk 'NR==3')
echo "$YOMTOVE"
if [[ -n "$YOMTOVE" ]]; then
grep ^"$YOMTOVE" "$STORDIR"/YomTove.cvs
# actions based on what holiday it is
fi
done
Next_Day
exit
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.