Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place. |
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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
|
 |
08-06-2010, 03:27 PM
|
#1
|
LQ Newbie
Registered: Dec 2009
Posts: 7
Rep:
|
Bash scripting: value too great for base (error token is "08")
I have a bash script that I use to process some data, and compares each days file with the previous days file and store it in files based on the current date. The script needs to know yesterdays date and todays date stored in this format: YYYYMMDD. It runs every single day, and the script has worked flawlessly until I noticed this error today. It is getting an error for the month of August ("08"). I don't have logs to show if the error occured the first 5 days of August, but I would assume so.
The code is below, with the line causing the error in red.
OFFSET=${1:-1}
set DAYS Sat Sun Mon Tue Wed Thu Fri Sat
set MONTHS Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
YESTERDAYPRE=`date +%d | sed 's/^0*//'`
YESTERDAY=`expr $YESTERDAYPRE - 1`
#YESTERDAY=$((`date +%d` -1))
MONTH=`date +%m`
YEAR=`date +%Y`
NDAY=`date +%u`
WEEKDAY=${DAYS[`date +%u`]}
if [ $YESTERDAY -eq "0" ]
then
MONTH=$((MONTH-1))
if [ $MONTH -eq "0" ]
then
MONTH=12
YEAR=$((YEAR-1))
fi
set `cal $MONTH $YEAR`
shift $(($# - 1))
YESTERDAY=$1
fi
TMONTH=${MONTHS[MONTH]}
# echo $WEEKDAY $YESTERDAY $MONTH $TMONTH $YEAR
if [ $MONTH -eq "1" ] ; then MONTH=01 ; fi
if [ $MONTH -eq "2" ] ; then MONTH=02 ; fi
if [ $MONTH -eq "3" ] ; then MONTH=03 ; fi
if [ $MONTH -eq "4" ] ; then MONTH=04 ; fi
if [ $MONTH -eq "5" ] ; then MONTH=05 ; fi
if [ $MONTH -eq "6" ] ; then MONTH=06 ; fi
if [ $MONTH -eq "7" ] ; then MONTH=07 ; fi
if [ $MONTH -eq "8" ] ; then MONTH=08 ; fi
if [ $MONTH -eq "9" ] ; then MONTH=09 ; fi
if [ $YESTERDAY -eq "1" ] ; then YESTERDAY=01 ; fi
if [ $YESTERDAY -eq "2" ] ; then YESTERDAY=02 ; fi
if [ $YESTERDAY -eq "3" ] ; then YESTERDAY=03 ; fi
if [ $YESTERDAY -eq "4" ] ; then YESTERDAY=04 ; fi
if [ $YESTERDAY -eq "5" ] ; then YESTERDAY=05 ; fi
if [ $YESTERDAY -eq "6" ] ; then YESTERDAY=06 ; fi
if [ $YESTERDAY -eq "7" ] ; then YESTERDAY=07 ; fi
if [ $YESTERDAY -eq "8" ] ; then YESTERDAY=08 ; fi
if [ $YESTERDAY -eq "9" ] ; then YESTERDAY=09 ; fi
yesterday=$YEAR$MONTH$YESTERDAY
today=`date +%Y%m%d`
The if statements were added to keep everything in two digit format.
I don't have a ton of bash experience so I'm sure there are 100 much more efficient ways of doing this, LOL
Thanks!
|
|
|
08-06-2010, 04:12 PM
|
#2
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852
|
Please use [code][/code] tags around your scripts, to preserve formatting and to improve readability.
I haven't worked through everything yet, but it appears that somehow your MONTHS value is coming out as "08", and the leading zero in that is unusable as the index number in the TMONTH array variable.
As for your list of if statements, you can use something like this instead:
Code:
if [[ $MONTH =~ ^[1-9]$ ]] ; then
MONTH=${MONTH/#/0}
fi
if [[ $YESTERDAY =~ ^[1-9]$ ]] ; then
YESTERDAY=${YESTERDAY/#/0}
fi
It uses bash's more flexible extended test command, allowing the easy use of regex values, and parameter substitution to add the leading zero.
Oh, and $(..) is recommended over `..`
Last edited by David the H.; 08-06-2010 at 04:14 PM.
|
|
|
08-06-2010, 04:43 PM
|
#3
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852
|
I think I can say a bit more about it now. "date +%m" outputs the month in zero-padded form.
But bash treats integers starting with 0 as octal values, so you're ok from 01-07, but 08 and 09 are illegal in all of your arithmetic functions.
A quick glance at the date man page shows that, instead of using sed or other tricks, you can simply use a hyphen in the format string to force it not to zero-pad. e.g. "date +%-m".
Oh, and here's an even cleaner way to re-pad the numbers afterwards, using bash's builtin printf function:
Code:
MONTH=$(printf %02d $MONTH)
YESTERDAY=$(printf %02d $YESTERDAY)
Edit: And one last thing. I was puzzled about your two "set" lines at the beginning of the script, but now I see that they're supposed to be array values. But that's not how to populate an array. You need something like this instead:
Code:
DAYS=( Sat Sun Mon Tue Wed Thu Fri Sat )
MONTHS=( Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec )
After I made all the above changes, your script seems to give me the kind of output I'd expect it to.
Last edited by David the H.; 08-06-2010 at 04:53 PM.
Reason: as stated
|
|
|
08-06-2010, 05:50 PM
|
#4
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852
|
One last post. In retrospect, most of what you're attempting can be done with just the date command. GNU date can be set to output some other date instead of the current one. More here and here.
The following is just an example of how to fetch various strings for "yesterday". I've used an array, so as to only call date one time. The fewer external calls you have to make, the more efficient the code.
Code:
#!/bin/bash
YESTARRAY=( $(date -d "yesterday" "+%d %u %a %m %b %Y") )
YESTERDAY=${YESTARRAY[0]}
WEEKDAYNUM=${YESTARRAY[1]}
WEEKDAYSTR=${YESTARRAY[2]}
MONTHNUM=${YESTARRAY[3]}
MONTHSTR=${YESTARRAY[4]}
YEAR=${YESTARRAY[5]}
echo "Yesterday's date (day of month): $YESTERDAY"
echo "Day of the week in numeric form: $WEEKDAYNUM"
echo "Day of the week in abbreviated string form: $WEEKDAYSTR"
echo "Month in numeric form: $MONTHNUM"
echo "Month in abbreviated string form: $MONTHSTR"
echo "Year: $YEAR"
exit 0
And the output:
Code:
$ ./datescript.sh
Yesterday's date (day of month): 06
Day of the week in numeric form: 5
Day of the week in abbreviated string form: Fri
Month in numeric form: 08
Month in abbreviated string form: Aug
Year: 2010
|
|
1 members found this post helpful.
|
05-08-2012, 12:36 PM
|
#5
|
LQ Newbie
Registered: Apr 2012
Posts: 11
Rep: 
|
Thanks for this! I was using this whole friggin thing to get to yesterdays date
Code:
declare eod=(0 31 28 31 30 31 30 31 31 30 31 30 31)
yest=`date +%d`
yest=$((yest-1))
mon=`date +%m`
if [ $yest -lt 1 ]
then
mon=$((mon-1))
yest=${eod[$mon]}
fi
if [ $mon -lt 10 ] && [ ${#mon} -eq 1 ];
then
mon=0$mon
fi
if [ $yest -lt 10 ] && [ ${#yest} -eq 1 ];
then
yest=0$yest
fi
...and now it's one line of code. I know this post is two years old, but maybe you'll get a thanks in your email.
|
|
|
09-24-2013, 11:18 AM
|
#6
|
LQ Newbie
Registered: Sep 2009
Posts: 8
Rep:
|
Enforce base 10 in your script
This post is not timely, but still relevant.
The problem you have is the 0 pad made shell, bash, ksh or csh all the same, thinks your value is in Octal (thus "value too great for base" for 09). Check out this post to enforce shell the use of base 10
http://stackoverflow.com/questions/5...-token-is-0925
In your case, just replace the two date commands by the following:
yest=10#`date +'%d'`
...
mon=10#$`date +'%m'`
All the rest does not need to be changed.
|
|
|
All times are GMT -5. The time now is 08:58 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|