I have few bash shell scripts which depends on one Ksh shell script. When i run bash shell scripts, it shows error as bad interpretor : ksh no such bad file or directory.
When i tried to install ksh shell, it is not downloading too.
If I remove !/bin/ksh command in starting line of the script, then errors get displayed in few commands.
Can anyone give me good solution for this please ?
#!/bin/ksh
#
# shift_date: Shift specified date (YYYYMMDD) by number of days
# e.g. shift_date 20000411 -42
# = 20000229
#
# Parameters:
# $1 shift_date Date (YYYYMMDD)
# $2 shift_days Days to add (integer, can be negative)
#
# Define current script name, stripping any leading "*/" or "-" (in case run in
# current shell for some reason and $0 = "-sh")
program=${0##*(*/|-)}
# Allow references to unset variables:
set +u
alias integer="typeset -i"
# Define 'usage' text for error messages:
usage="Usage: ${program} [date YYYYMMDD] [days to add]
\n\tparameter 1 = date in YYYYMMDD format
\n\tparameter 2 = days to add (negative to subtract), integer
\ne.g:\n\t$program $(date +'%Y%m%d') -42"
# Array of month lengths for use by conversion functions
# (Feb 28 is default value only - gets reset to 29 when necessary)
set -A monthlengths dummy 31 28 31 30 31 30 31 31 30 31 30 31
# Set DEBUG=TRUE to enable diagnostic output.
typeset -ux DEBUG=${DEBUG:-FALSE}
function debug
{
# Optional diagnostic message, only displayed if environment variable DEBUG=TRUE
message="$*"
[[ ${DEBUG} = TRUE ]] && print -u2 "${message#-}"
}
debug "${program}: Debugging messages enabled. Set environment variable DEBUG=FALSE to disable."
function bomb
{
# Display error message and exit with non-zero exit status.
# Pick up exit status from environment (reset to 2 if zero):
exitstatus=$?
(( exitstatus == 0 )) && exitstatus=2
# Display message only if one was passed as parameter:
if (( $# > 0 )); then
print "${program}: $*" >&2
fi
debug Exiting with exit status ${exitstatus}
exit ${exitstatus}
}
# Ensure two parameters were supplied:
(( $# == 2 )) || bomb ${usage}
# Ensure parameter 1 is a number and is 8 digits long:
shift_date=$1 && [[ ${#1} = 8 ]] && print ${shift_date} | grep >/dev/null "[0-9]\{8\}" || bomb "Invalid date '$1'\n${usage}"
[[ ${shift_date} != $1 ]] && bomb "Invalid date '$1'\n${usage}"
# Ensure parameter 2 is a number (note shell rounds decimals down):
# Some shells give fatal error of integer assignment fails, others silently set value to 0,
# so to validate $2 we assign to an integer variable and then do a text comparison (stripping
# any leading "+" off start of $2).
integer shift_days=$2 || bomb "Invalid number of days $2\n${usage}"
[[ ${shift_days} != ${2#+} ]] && bomb "Invalid number '$2'\n${usage}"
# Rather than hardcode arbitrary julian base year e.g. 1970, set each time
# using specified year and number of shift_days:
typeset -L4 base_year=${shift_date} # Extract as leftmost 4 characters of $shiftdate
if (( shift_days != 1 )); then
plural="s"
fi
if (( shift_days >= 0 ))
then
# Positive shift: don't need base date in the past; set to year specified:
# (redefine existing character variable as integer)
sign="+"
integer max_years=1
integer base_year
debug "Using ${base_year} as base year for julian date conversion."
debug Adding ${shift_days} day${plural} to ${shift_date}
else
# Negative shift: set julian base date as far in the past as it needs to be:
sign=""
# integer max_years=$(( (shift_days/-365) +1 ))
# Latest version of ksh93 in CentOS 5 gives zero divide error when multiplying by a negative number,
# so reverse both signs to give same result:
integer max_years=$(( ( (shift_days * -1) / 365) +1 ))
integer base_year=$(( base_year - max_years )) # Redefine as integer
debug "Negative shift ${shift_days} days = ${max_years} year(s) or less (${shift_days}/-365 +1):"
debug "Using ${base_year} as base year for julian date conversion."
debug Subtracting $(( shift_days * -1 )) day${plural} from ${shift_date}
fi
# Make read-only (some shells don't allow typeset -r var=value):
typeset -r max_years
typeset -r base_year
# Sanity check values derived above:
if (( base_year < 1 )) # There was no year zero
then
bomb "Cannot calculate BC dates."
fi
function leapyear
{
# Test for a leap year.
# Parameters:
# $1 testyear YYYY
# Returns actual boolean (not text) via return exit status.
# Leap Year occurs every four years, except for years ending in 00, in which case
# only if the year is divisible by 400.
# ...however, this system was only standardised in 1752 (1582 in Catholic countries), so the 400 rule
# does not apply to years before then.
# The actual length of a year is 365 days, five hours, 48 minutes, 46 seconds.
integer testyear=$1 TRUE=0 FALSE=1
# Initially assume FALSE, only reset to TRUE if passes tests:
integer leapyearanswer=${FALSE}
if (( testyear % 4 == 0 ))
then
if (( testyear % 100 == 0 ))
then
if (( testyear < 1752 ))
then
leapyearanswer=${TRUE}
elif (( testyear % 400 == 0 ))
then
leapyearanswer=${TRUE}
fi
else
leapyearanswer=${TRUE}
fi
fi
return ${leapyearanswer}
}
function yearlength
{
# Return number of days in specified year:
# Parameters:
# $1 testyear YYYY
integer result=365
integer testyear=$1 && (( testyear > 0 )) && (( testyear < 10000 )) \
|| bomb "$0: Invalid year '$1': year must be between 1 and 9999."
if leapyear ${testyear}
then
(( result = 366 ))
elif (( testyear == 1582 )) || (( testyear == 1752 ))
then
(( result = 355 ))
fi
print ${result}
}
function split_yyyy_mm_dd
{
# Accept YYYYMMDD
# Return YYYY MM DD, validated as integers in vaguely appropriate ranges.
date_yyyymmdd=$1
# Confirm length of date parameter is 8:
[[ ${#date_yyyymmdd} = 8 ]] || bomb "$0: Invalid date '$1': must be 8 digits"
# Break date string into YYYY MM DD elements:
typeset -L4 yyyy=${date_yyyymmdd}
typeset -R2 dd=${date_yyyymmdd}
typeset -R4 mm=${date_yyyymmdd}
typeset -L2 mm=${mm}
debug $0: ${date_yyyymmdd} = ${yyyy} ${mm} ${dd}
integer yyyy || bomb "$0: year '${year}' is not numeric."
# Confirm yyyy is a number between 1 and 9999:
if (( yyyy < 1 )) || (( yyyy > 9999 ))
then
bomb "$0: Invalid year '${yyyy}': must be between 1 and 9999"
fi
print ${yyyy} ${mm} ${dd}
}
function to_j
{
# Parameters:
# $1: date_yyyymmdd: date in format YYYYMMDD
# Return date converted to julian format (days since 01/01/${base_year})
[[ $1 = [0-9][0-9][0-9][0-9] ]] || bomb $1 is not 4 digits
[[ $2 = [0-1][0-9] ]] || bomb $2 is not 2 digits
[[ $3 = [0-3][0-9] ]] || bomb $3 is not 2 digits [0-3][0-9]
integer yyyy=$1 || bomb "$0: Year $1 is not numeric"
integer mm=$2 || bomb "$0: Month $2 is not numeric"
integer dd=$3 || bomb "$0: Day $1 is not numeric"
debug yyyy = $1 mm = $2 dd = $3
# Confirm yyyy is a number between 1 and 9999:
if (( yyyy < 1 )) || (( yyyy > 9999 ))
then
bomb "$0: Invalid year '${yyyy}': must be between 1 and 9999"
fi
# If yyyy is a leap year, set Feb length to 29:
if leapyear ${yyyy}
then
monthlengths[2]=29
else
monthlengths[2]=28
fi
# Confirm mm is a number between 1 and 12:
integer mm && (( 1 <= mm )) && (( mm <= 12 )) \
|| bomb "$0: Invalid month '${mm}'"
# Confirm dd is a number between 1 and length of month 'mm':
integer dd && (( 1 <= dd )) && (( dd <= ${monthlengths[mm]} )) \
|| bomb "$0: Invalid day '${dd}' for month ${mm}/${yyyy}"
integer yearlength y=${base_year} j=0 m=1
yearlength=$(yearlength ${y}) || bomb # Cascade on failure
debug "$0: Convert ${yyyy} ${mm} ${dd} to julian date, base = 01/01/${base_year}:"
# Add whole years to total 'j', stopping at year before yyyy:
# (y is counter starting at ${base_year}; yyyy is the year specified in date parameter)
while (( y < yyyy ))
do
yearlength=$(yearlength ${y}) || bomb # Cascade on failure
debug "\tYear ${y}: incrementing j by ${yearlength}"
(( j += yearlength ))
(( y += 1 ))
done
debug "\tFinished years at ${y}: j = ${j}."
# Set length of February (reset yearlength as loop may have overshot in last iteration):
yearlength=$(yearlength ${y}) || bomb # Cascade on failure
if (( yearlength == 366 ))
then
(( monthlengths[2] = 29 ))
else
(( monthlengths[2] = 28 ))
fi
# Add whole months to total 'j', stopping at month before mm:
# (m is counter starting at 1; mm is the month specified in date parameter)
while (( m < mm ))
do
debug "\tMonth ${m}: incrementing j by ${monthlengths[m]}"
(( j += ${monthlengths[m]} ))
(( m += 1 ))
done
debug "\tFinished months at ${m}: j = ${j}."
# Add days to total 'j':
debug "\tAdding ${dd} days"
(( j += dd ))
debug "$0 $* = ${j}"
if (( j < 1 ))
then
bomb "$0: Date conversion ${yyyy} ${mm} ${dd} to julian with" \
"base year ${base_year} gave invalid result '${j}'."
else
print ${j}
fi
}
function j_to_yyyymmdd
{
# Parameters:
# $1: date_j: date in julian format (days since 01/01/${base_year})
# Return date converted to format YYYYMMDD
integer date_j=$1 || bomb "$0: Invalid julian date '$1'"
(( date_j > 0 )) || bomb "$0: julian date must be greater than 0 (01/01/${base_year})"
integer yyyy=${base_year} mm=1 dd=0 yearlength monthlength
debug "$0: Convert ${date_j} to YYYYMMDD using base date 01/01/${base_year}:"
# Add whole years to total 'j', stopping when running total goes < 0:
while (( date_j > 0 ))
do
if (( yyyy < 1 ))
then
bomb "Cannot calculate BC dates."
elif (( yyyy > 9999 ))
then
bomb "Invalid year ${yyyy}: cannot be greater than 9999."
fi
(( yearlength = $(yearlength ${yyyy}) )) || bomb # Cascade on failure
if (( date_j <= yearlength ))
then
# Less than a whole year to add:
# use yearlength to set length of Feb for use in Month stage, and break:
debug "\t${date_j} <= ${yearlength}: Finished years: yyyy = ${yyyy}."
break
else
(( yyyy += 1 ))
(( date_j -= yearlength ))
debug "\tYear $(( yyyy -1 )):" \
"Reduced date_j by ${yearlength} to ${date_j}"
fi
done
# Re-use final yearlength from loop to set length of February:
if (( yearlength == 366 ))
then
(( monthlengths[2] = 29 ))
else
(( monthlengths[2] = 28 ))
fi
# Add whole months to total 'j', stopping at month before mm:
while (( mm <= 12 )) && (( date_j > 0 ))
do
(( monthlength = ${monthlengths[mm]} ))
if (( date_j <= monthlength ))
then
debug "\tMonth ${mm}:" \
"${date_j} <= ${monthlength}: Finished months: mm = ${mm}."
break
else
(( mm += 1 ))
(( date_j -= monthlength ))
debug "\tMonth $(( mm -1 )) length ${monthlength}:" \
"Reduced date_j by ${monthlength} to ${date_j}"
fi
done
# Assign remaining days to DD:
dd=${date_j}
debug dd = $dd
# Finished integer arithmetic: change to zero-padded strings:
typeset -Z4 yyyy
typeset -Z2 mm dd # left-padded with zeroes, 2 digits
debug "$0 $* = ${yyyy} ${mm} ${dd}"
# Sanity-check result before returning:
if (( yyyy < 1 ))
then
bomb "$0: Date conversion ${date_j} to YYYYMMDD base year ${base_year}" \
"gave invalid result '${yyyy}'."
else
print ${yyyy}${mm}${dd}
fi
}
# Convert to julian date and confirm valid result:
# integer jdate=$(to_j ${shift_date}) || bomb
set -A date_elements $(split_yyyy_mm_dd ${shift_date}) || bomb "Failed to split ${shift_date}) into its components"
# Inelegant optimization:
# Short-circuit the whole procedure in simplest case where dd + shift_days > 0 < month_length
# e.g. if adding 2 days to 2004 03 02, answer will be 2004 03 04 (month unchanged)
integer test_result_dd
typeset -Z2 mm monthlength
mm=${date_elements[1]}
monthlength=${monthlengths[${mm}]}
(( test_result_dd = date_elements[2] + shift_days ))
debug Day ${date_elements[2]} + ${shift_days} = ${test_result_dd}
debug Date elements are: ${date_elements[*]}
debug Month lengths are: ${monthlengths[*]}
debug Length of month ${mm} is ${monthlengths[${mm}]} which should be the same as ${monthlength}
debug Testing whether ${test_result_dd} is less than month length ${monthlength} \
and required day ${test_result_dd} is in future
if (( test_result_dd < monthlength )) && (( test_result_dd > 0 )); then
debug "${test_result_dd} is less than ${monthlength} and ${test_result_dd} is greater than zero"
debug "Short circuit: day ${date_elements[2]} + ${shift_days} = ${test_result_dd}" \
"is in range 1-${monthlength} for month ${mm}"
debug Quick result: ${date_elements[0]} ${mm} ${test_result_dd}
# Declared test_result_dd as an integer above for efficiency,
# but make it 2-char zero-padded here immediately prior to display:
typeset -Z2 test_result_dd
print ${date_elements[0]}${mm}${test_result_dd}
exit 0
else
debug Short circuit not possible: applying full procedure.
fi
debug Defining jdate from by calling function to_j "${date_elements[*]}"
# Solaris reports success indiscriminately if var defined and set on same line e.g. integer jdate=$(func)
integer jdate
jdate=$(to_j ${date_elements[*]}) || bomb
if [[ $? = 0 ]]; then
debug Call successful
else
debug Call failed
fi
# Apply shift_days (+ or -) to jdate, and confirm valid result:
(( jdate += shift_days )) || bomb "Date arithmetic failed (${jdate} - ${shift_days})"
debug "$((jdate - shift_days)) ${sign}${shift_days} = ${jdate}"
# Convert back:
new_date_yyyymmdd=$(j_to_yyyymmdd ${jdate}) || bomb
# Confirm we have a result before returning:
if [[ -z ${new_date_yyyymmdd} ]]
then
print "$0: Failed: $(date)" >&2
exit 1
else
print ${new_date_yyyymmdd}
fi
and error showing is
test_email.sh: /home/dbadmin/Scripts/recon/shift_date.sh: /bin/ksh: bad interpreter: No such file or directory
---------- Post updated at 01:39 AM ---------- Previous update was at 01:38 AM ----------
If I remove !/bin/ksh, then it will show error SET command is not proper....
i tried Akshay see below error when i tried to install..
[root@v001 ~]# yum install ksh
Loaded plugins: product-id, security, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use su bscription-manager to register.
file:///mnt/Server/repodata/repomd.xml: [Errno 14] Could not open/read file:///m nt/Server/repodata/repomd.xml
Trying other mirror.
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package ksh.x86_64 0:20100621-19.el6 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
ksh x86_64 20100621-19.el6 rhel 686 k
Transaction Summary
================================================================================
Install 1 Package(s)
Total download size: 686 k
Installed size: 1.5 M
Is this ok [y/N]: y
Downloading Packages:
Error Downloading Packages:
ksh-20100621-19.el6.x86_64: failure: ../Packages/ksh-20100621-19.el6.x86_64.rpm from rhel: [Errno 256] No more mirrors to try.
---------- Post updated at 02:08 AM ---------- Previous update was at 02:06 AM ----------
I am new to this Unix shell scripting so i don't understand many things
ksh is part of the standard Redhat distribution, so no need to download anything, just install it from the distribution itself, I don't understand how your manager could object to this. Your yum repositories are not properly set up and yum needs to be told where it can find those files (and your systems appear to not be registered either)...