pavelmed
asked on
How to verify dates in UNIX shell script
I have a shell script that accepts two dates of a date range from the command line and sends the dated into the sqlplus script.
How can I verify that the dates are correct before sending to sqiplus?
I would like to check if:
a) date is entered in a correct format (MM/DD/YYYY) and exit if not;
b) beginning date is less than ending date - exit if not;
c) date is not skipped (no blanks from the user).
Is that possible?
Please assist.
How can I verify that the dates are correct before sending to sqiplus?
I would like to check if:
a) date is entered in a correct format (MM/DD/YYYY) and exit if not;
b) beginning date is less than ending date - exit if not;
c) date is not skipped (no blanks from the user).
Is that possible?
Please assist.
you can use the date command like this
the script will additionally understand the wide variety of formats the date function understands including MM/DD/YYYY but also things like DD-MM-YYYY, YYYY-MM-DD or even "next week"
if you need to limit the input format to MM/DD/YYYY, it should be rather trivial to add an additional simple regular expression to validate the basics "[0-9]\{2\}/[0-9]\{2\}/[0- 9]\{4\}" and let date complain if the user types invalid dates like 02/29/2003
# read user input
read -p "type in min date" min
read -p "type in min date" max
# convert these to timestamps
min_=$(date --date="$min" +%s) || ! echo "invalid min date '$min'" || exit 1
max_=$(date --date="$max" +%s) || ! echo "invalid max date '$max'" || exit 1
test $min_ -gt $max_ || ! echo min date should be less than max >&2 || exit 1
# add whatever other checks you need here such as a reasonable range
# reconvert the dates to the format you need
min=$(date --date="@$min" +%m/%d/%Y)
max=$(date --date="@$max" +%m/%d/%Y)
the script will additionally understand the wide variety of formats the date function understands including MM/DD/YYYY but also things like DD-MM-YYYY, YYYY-MM-DD or even "next week"
if you need to limit the input format to MM/DD/YYYY, it should be rather trivial to add an additional simple regular expression to validate the basics "[0-9]\{2\}/[0-9]\{2\}/[0-
ASKER
Sorry for the delay in my response.
I appreciate both solutions shown above but they don't work for me.
The first one errors out and I don't have enough knowledge to debug.
The second one with "date" also errors out because the --date option is not available for me.
So I am trying not to use a compromised solution:
I am going to check for an empty string is shell string, and verify date in the sqlplus.
How can I return an error description from the sqlplus back to shell script so that I could display it from there?
I am going to execute a statement like this in the sqlplus:
select to_date('$BEGDATE', 'MM/DD/YYYY') from dual;
where $BEGDATE is a value of date received from the user's input in shell script.
In my opinion it should error if the date is entered in a wrong format.
Also, how can I compare dates in sqlplus and return an error to the shell script if BEGDATE is less than ENDDATE?
Thank you.
I appreciate both solutions shown above but they don't work for me.
The first one errors out and I don't have enough knowledge to debug.
The second one with "date" also errors out because the --date option is not available for me.
So I am trying not to use a compromised solution:
I am going to check for an empty string is shell string, and verify date in the sqlplus.
How can I return an error description from the sqlplus back to shell script so that I could display it from there?
I am going to execute a statement like this in the sqlplus:
select to_date('$BEGDATE', 'MM/DD/YYYY') from dual;
where $BEGDATE is a value of date received from the user's input in shell script.
In my opinion it should error if the date is entered in a wrong format.
Also, how can I compare dates in sqlplus and return an error to the shell script if BEGDATE is less than ENDDATE?
Thank you.
Try something like this:
if [ $# -ne 2 ]
then
echo "!Error: missing parameters, 1-{begin date} 2-{end_date}."
exit 1
fi
BEGDATE=$1
ENDDATE=$2
ORAENV_ASK=NO
. /usr/local/bin/oraenv orcl >/dev/null
result=`
sqlplus -s / <<EOSQL
set echo off term off feed off
set serverout on size 1000000;
DECLARE
dt_beg DATE;
dt_end DATE;
BEGIN
BEGIN
SELECT TO_DATE ( '$BEGDATE', 'MM/DD/YYYY') INTO dt_beg FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line ('!Error: $BEGDATE ' || SQLERRM);
END;
BEGIN
SELECT TO_DATE ( '$ENDDATE', 'MM/DD/YYYY') INTO dt_end FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line ('!Error: $ENDDATE ' || SQLERRM);
END;
BEGIN
IF dt_beg > dt_end
THEN
dbms_output.put_line ('!Error: $BEGDATE is greater than $ENDDATE.');
END IF;
END;
END;
/
exit
EOSQL`
[ ! -z $result ] && echo "$result"
:p
ASKER
MikeOM_DBA,
Thank you for your suggestion.
I copied your code into mine with slight changes, for example, I changed EOSQL to EOF which worked in my code.
That line below I commented out because my script stopped responding when I entered it:
. /usr/local/bin/oraenv orcl >/dev/null
Anyway, the script returns the following:
./audsh2.sh[50]: 01/01/2001: not found
where audsh2.sh is a name of the script file, and 01/01/2001 is a date entered as a beginning date.
Please advise.
Thank you for your suggestion.
I copied your code into mine with slight changes, for example, I changed EOSQL to EOF which worked in my code.
That line below I commented out because my script stopped responding when I entered it:
. /usr/local/bin/oraenv orcl >/dev/null
Anyway, the script returns the following:
./audsh2.sh[50]: 01/01/2001: not found
where audsh2.sh is a name of the script file, and 01/01/2001 is a date entered as a beginning date.
Please advise.
ASKER
I also have a different sqlplus string (and a connection string of course):
sqlplus -s /nolog > /dev/null 2>&1 << EOF
connect username/mypassword@mydata base
sqlplus -s /nolog > /dev/null 2>&1 << EOF
connect username/mypassword@mydata
can you post the complete command you type, the result and some data about your environment (at least the OS, shell, and sqlplus versions) ? either for the sqlpus of the shell way ?
ASKER
SQL*Plus: Release 11.2.0.1.0
OS - UNIX
The default shell script on the server is KSH, so I use this line at the beginning:
#!/bin/ksh
I tried to change it to #!/bin/sh but then it displays a different error:
./audsh2.sh: 03/03/2000: not found
./audsh2.sh: test: argument expected
OS - UNIX
The default shell script on the server is KSH, so I use this line at the beginning:
#!/bin/ksh
I tried to change it to #!/bin/sh but then it displays a different error:
./audsh2.sh: 03/03/2000: not found
./audsh2.sh: test: argument expected
SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
OS - UNIX ???
sco ? bsd ? solaris ? the environment are very different
the error you have in sh will disapear if you quote BEGDATE="$1" and other parameters at the beginning of the script
sco ? bsd ? solaris ? the environment are very different
the error you have in sh will disapear if you quote BEGDATE="$1" and other parameters at the beginning of the script
ASKER
OS - SunOS dover 5.10 Generic_142900-13 sun4u sparc SUNW,Netra-T12
I get data into BEGDATE from the user's input in response to a prompt, like this:
echo "Enter beginning date of a date range in MM/DD/YYYY format:"
read BEGDATE
#echo "$BEGDATE"
if [ -z "$BEGDATE" ]; then
echo "Empty beginning date. Please try again"
exit
fi
echo "Enter ending date of a date range in MM/DD/YYYY format:"
read ENDDATE
if [ -z "$ENDDATE" ]; then
echo "Empty ending date. Please try again"
exit
fi
There are just two parameters, BEGDATE and ENDDATE
I get data into BEGDATE from the user's input in response to a prompt, like this:
echo "Enter beginning date of a date range in MM/DD/YYYY format:"
read BEGDATE
#echo "$BEGDATE"
if [ -z "$BEGDATE" ]; then
echo "Empty beginning date. Please try again"
exit
fi
echo "Enter ending date of a date range in MM/DD/YYYY format:"
read ENDDATE
if [ -z "$ENDDATE" ]; then
echo "Empty ending date. Please try again"
exit
fi
There are just two parameters, BEGDATE and ENDDATE
ckdate should be available on your machine
it will prompt the user for date, take care of validation, and send explicit error messages
the format you want is the default one
http://docs.oracle.com/cd/E19253-01/816-5165/6mbb0m9c0/index.html
if you want to validate without propmpting, you can use valdate instead
it will prompt the user for date, take care of validation, and send explicit error messages
the format you want is the default one
http://docs.oracle.com/cd/E19253-01/816-5165/6mbb0m9c0/index.html
if you want to validate without propmpting, you can use valdate instead
ASKER
ckdate is available but it does not accept some valid dates.
But most importantly, I need to save the value of a user's input to a variable, and I can't figure out how to send the ckdate input to a variable.
But most importantly, I need to save the value of a user's input to a variable, and I can't figure out how to send the ckdate input to a variable.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
I am sorry I forgot to complete this question.
I resolved this by combining your and some other suggestions, and I would like to split the points.
Thank you for your help.
I resolved this by combining your and some other suggestions, and I would like to split the points.
Thank you for your help.
Otherwise, use awk like this:
Open in new window
;)