S-a-t
asked on
Shell Script - read words from file and search in another file and send mail if not found
Hi Experts,
I trying to create a shell script.
I want to read words from one file and search them in another file. If any word not found then send email. If words found then nothing to do.
If multiple words not found then send that information as a single email rather than multiple emails for each word not found.
File1 contains process names and file2 contains current running processes.
Thanks in Advance!
Sat
I trying to create a shell script.
I want to read words from one file and search them in another file. If any word not found then send email. If words found then nothing to do.
If multiple words not found then send that information as a single email rather than multiple emails for each word not found.
File1 contains process names and file2 contains current running processes.
Thanks in Advance!
Sat
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
@tel2 you are right! I am doing that and will post in few mins.
Thanks for your advise!
Thanks for your advise!
Hi Murugesan,
I haven't carefully checked your script, but here are a few initial questions which stand out for me:
Q1. What is the point of the trailing space inside the quotes?:
EGREP="/bin/grep -E "
EGREP="/bin/egrep "
Q2. What is the point of using './' in this context?:
if [[ ! -f ./Ps_names.txt ]]
I know that './' means the current directory, but '-f' is not going to search other directories for the file anyway, so what's the point? Try it if you don't believe me.
Q3. What is the point of having the extra brackets in statements like this?:
if [[ 0 -eq $VALIDATEFILESRET ]] && [[ "RECEIVER_EMAIL" != "$RECEIVER_EMAIL" ]]
You could remove 4 brackets and achieve the same result like this:
if [[ 0 -eq $VALIDATEFILESRET -a "RECEIVER_EMAIL" != "$RECEIVER_EMAIL" ]]
(Also note the '-a' instead of '&&', though '&&' may still work in some cases.)
Q4. And in the above example (and various others), why don't you remove the quotes from the variable (i.e. "$RECEIVER_EMAIL")? In bash these should not be needed inside [[ ]]. Try it if you don't believe me, but I see you don't have any around $VALIDATEFILESRET, so at least be consistent.
Q5. I think we might have discussed this before, but why are you writing your tests like this:
if [[ "" = "$PS_EXCEPTIONS" ]] # Value on left, variable on right
instead of this much more standard coding practice:
if [[ "$PS_EXCEPTIONS" = "" ]] # Variable on left, value on right
(If your answer is still because of your recollection of some bug in ksh from many years ago, which you are unable to provide any evidence of, then I suggest you don't assume this bug exists in bash, or any other shell/language, unless you can provide evidence that it does.)
Please number your answers to Q1 - Q5 clearly.
Thanks.
tel2
I haven't carefully checked your script, but here are a few initial questions which stand out for me:
Q1. What is the point of the trailing space inside the quotes?:
EGREP="/bin/grep -E "
EGREP="/bin/egrep "
Q2. What is the point of using './' in this context?:
if [[ ! -f ./Ps_names.txt ]]
I know that './' means the current directory, but '-f' is not going to search other directories for the file anyway, so what's the point? Try it if you don't believe me.
Q3. What is the point of having the extra brackets in statements like this?:
if [[ 0 -eq $VALIDATEFILESRET ]] && [[ "RECEIVER_EMAIL" != "$RECEIVER_EMAIL" ]]
You could remove 4 brackets and achieve the same result like this:
if [[ 0 -eq $VALIDATEFILESRET -a "RECEIVER_EMAIL" != "$RECEIVER_EMAIL" ]]
(Also note the '-a' instead of '&&', though '&&' may still work in some cases.)
Q4. And in the above example (and various others), why don't you remove the quotes from the variable (i.e. "$RECEIVER_EMAIL")? In bash these should not be needed inside [[ ]]. Try it if you don't believe me, but I see you don't have any around $VALIDATEFILESRET, so at least be consistent.
Q5. I think we might have discussed this before, but why are you writing your tests like this:
if [[ "" = "$PS_EXCEPTIONS" ]] # Value on left, variable on right
instead of this much more standard coding practice:
if [[ "$PS_EXCEPTIONS" = "" ]] # Variable on left, value on right
(If your answer is still because of your recollection of some bug in ksh from many years ago, which you are unable to provide any evidence of, then I suggest you don't assume this bug exists in bash, or any other shell/language, unless you can provide evidence that it does.)
Please number your answers to Q1 - Q5 clearly.
Thanks.
tel2
ASKER
Hi Murugesan,
Sorry for the delayed response.
Thanks for sharing the script, I am tweaking the script according to my need and would update you soon here.
Thanks for your time!
Sorry for the delayed response.
Thanks for sharing the script, I am tweaking the script according to my need and would update you soon here.
Thanks for your time!
ASKER
@tel2 Sorry for the delayed response.
Process names in file (ps_names):
GROUP1
GROUP2
GROUP3
GROUP4
GROUP5
GROUP6
GROUP7
Currently running process names in file (ps_names_running):
GROUP1
GROUP2
GROUP3
GROUP4
GROUP5
In this case there are two process not running (GROUP6 and GROUP7). I have kept process names in file (ps_names) and currently running process names in another file (ps_names_running).
I want to search for ps_names file keywords in ps_names_running file
and if ps_names keywords are missing from ps_names_running file then send an email with missing keywords.
If there are multiple keywords missing then send them all together in one email.
Thanks for your time!
Sat
Process names in file (ps_names):
GROUP1
GROUP2
GROUP3
GROUP4
GROUP5
GROUP6
GROUP7
Currently running process names in file (ps_names_running):
GROUP1
GROUP2
GROUP3
GROUP4
GROUP5
In this case there are two process not running (GROUP6 and GROUP7). I have kept process names in file (ps_names) and currently running process names in another file (ps_names_running).
I want to search for ps_names file keywords in ps_names_running file
and if ps_names keywords are missing from ps_names_running file then send an email with missing keywords.
If there are multiple keywords missing then send them all together in one email.
Thanks for your time!
Sat
Since busy on work here, will update my comment coming Saturday/Sunday.
Regards,
Murugesan
Regards,
Murugesan
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hi scullnobrains,
Could you please explain what the "!" does in this context?:
... ! echo "failed to write the cron file, bye"
Could you please explain what the "!" does in this context?:
... ! echo "failed to write the cron file, bye"
"!" negates the following command ( echo always returns "0" ) so the script returns "1" ( error ) rather than "0" ( no error ) if the tee command fails.
this is of little concern to you if you use the piece of code in a terminal but useful if you stick it in a script for automation
this is of little concern to you if you use the piece of code in a terminal but useful if you stick it in a script for automation
@S-a-t
/bin/cat ./29077002.sh
/bin/cat ./29077002.sh
#!/bin/ksh
# Better use full path
# Handle logging and exceptions
# Handle file exceptions
# Handle all ways to execute the script.
#----------------------------------.---------------------------------.
# Follow current update like svn | or git |
#----------------------------------.---------------------------------|
# DATE FORMAT: /bin/date "+%d_%b_%Y_%H_%M_%S %Z"|modified/created by |
# |Updated details. |
#----------------------------------.---------------------------------|
# Previous updates: | |
#----------------------------------.---------------------------------.
#Handle all such kind of error.
# /bin/egrep location being handled
if [[ ! -f /bin/grep && ! -f /bin/egrep ]]
then
echo "Unable to find location of grep"
# /usr/bin/basename being handled
elif [[ ! -f /bin/basename && ! -f /usr/bin/basename ]]
then
echo "Unable to find location of basename"
# /usr/bin/whoami being handled
elif [[ ! -f /bin/whoami && ! -f /usr/bin/whoami ]]
then
echo "Unable to find location of whoami"
# /usr/bin/tee being handled
elif [[ ! -f /bin/tee && ! -f /usr/bin/tee ]]
then
echo "Unable to find location of tee"
elif [[ ! -f /bin/ls && ! -f /usr/bin/ls ]]
then
echo "Unable to find location of ls"
else
if [[ -f /bin/grep ]]
then
EGREP="/bin/grep -E "
else # /bin/egrep location was handled
EGREP="/bin/egrep"
fi
if [[ -f /usr/bin/basename ]]
then
BASENAME="/usr/bin/basename"
else # /usr/bin/basename location was handled
BASENAME="/usr/bin/basename"
fi
if [[ -f /bin/whoami ]]
then
WHOAMI="/bin/whoami"
else # /usr/bin/whoami location was handled
WHOAMI="/usr/bin/whoami"
fi
if [[ -f /bin/tee ]]
then
TEE="/bin/tee"
else # /usr/bin/tee location was handled
TEE="/usr/bin/tee"
fi
if [[ -f /bin/ls ]]
then
LS="/bin/ls"
else # /usr/bin/ls location was handled
LS="/usr/bin/ls"
fi
CURSCRIPTNAME="$0"
echo "$CURSCRIPTNAME" | $EGREP -E "^\-bash|^bash|^ksh|^mksh" >/dev/null 2>&1
# Above commmand not tested at all platforms.
SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET=$?
if [[ 0 -eq $SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET ]]
then
echo "Cannot execute this script in current shell."
elif [[ "" != "$BASENAME" ]]
then
BASENAME=''`$BASENAME $CURSCRIPTNAME`''
LOGNAME=''`$WHOAMI`''
MAILTO="$LOGNAME@localhost"
if [[ -f /etc/cron.d/check_ps ]]
then
if [[ -w /etc/cron.d/check_ps ]]
then
#Based on comment from skullnobrains
$TEE /etc/cron.d/check_ps << EOF >/dev/null || ! echo "failed to write the cron file, bye"
*/10 * * * * root $EGREP -Fv /tmp/ps_names -f /tmp/ps_names_running >2&1
EOF
else
echo "Write permission denied /etc/cron.d/check_ps for current user: $LOGNAME"
echo "$LS -l /etc/cron.d/check_ps"
echo $CURSCRIPTNAME
$LS -l /etc/cron.d/check_ps
echo "ERROR" | $EGREP "error"
fi
else
echo "No such file /etc/cron.d/check_ps"
echo "ERROR" | $EGREP "error"
fi
fi
fi
That's pretty elaborate looking, Murugesan, but I have a couple of questions about it:
Q1. Why did you write a 97 line script to do a one-off task of creating a cron job?
Q2. My grep & egrep are in /usr/bin on both CentOS and OpenBSD. Your script fails for me because it looks for these in /bin only.
Q1. Why did you write a 97 line script to do a one-off task of creating a cron job?
Q2. My grep & egrep are in /usr/bin on both CentOS and OpenBSD. Your script fails for me because it looks for these in /bin only.
@S-a-t and tel2
>> Thank you for using Q2.
Like the same script needs to be modified to handle all related exceptions.
Q1. Handle forthcoming exceptions
@ all OS(AIX/*BSD/Cygwin*/Darwin */HP-UX/Li nux*/MINGW */SunOS/UN IX ...) and root/Administrator settings.
>> Thank you for using Q2.
Like the same script needs to be modified to handle all related exceptions.
#!/bin/ksh
# Better use full path
# Handle logging and exceptions
# Handle file exceptions
# Handle all ways to execute the script.
#----------------------------------.---------------------------------.
# Follow current update like svn | or git |
#----------------------------------.---------------------------------|
# DATE FORMAT: /bin/date "+%d_%b_%Y_%H_%M_%S %Z"|modified/created by |
# |Updated details. |
#----------------------------------.---------------------------------|
# Previous updates: | |
#----------------------------------.---------------------------------.
#Handle all such kind of error.
# /bin/egrep location being handled
# Like this, all binary location exceptions and $PATH kind of environment variables needs to be handled.
# Based on comment from tel2
if [[ ! -f /bin/grep && ! -f /bin/egrep && ! -f /usr/bin/grep && ! -f /usr/bin/egrep ]]
then
echo "Unable to find location of grep"
# /usr/bin/basename being handled
elif [[ ! -f /bin/basename && ! -f /usr/bin/basename ]]
then
echo "Unable to find location of basename"
# /usr/bin/whoami being handled
elif [[ ! -f /bin/whoami && ! -f /usr/bin/whoami ]]
then
echo "Unable to find location of whoami"
# /usr/bin/tee being handled
elif [[ ! -f /bin/tee && ! -f /usr/bin/tee ]]
then
echo "Unable to find location of tee"
elif [[ ! -f /bin/ls && ! -f /usr/bin/ls ]]
then
echo "Unable to find location of ls"
else
if [[ -f /bin/egrep ]]
then
EGREP="/bin/egrep "
elif [[ -f /bin/grep ]]
then
EGREP="/bin/grep -E "
elif [[ -f /usr/bin/egrep ]]
then
EGREP="/usr/bin/egrep"
else # /usr/bin/grep location was handled
EGREP="/usr/bin/grep -E "
fi
# Handle similar exceptions for all executable locations.
if [[ -f /usr/bin/basename ]]
then
BASENAME="/usr/bin/basename"
else # /usr/bin/basename location was handled
BASENAME="/usr/bin/basename"
fi
if [[ -f /bin/whoami ]]
then
WHOAMI="/bin/whoami"
else # /usr/bin/whoami location was handled
WHOAMI="/usr/bin/whoami"
fi
if [[ -f /bin/tee ]]
then
TEE="/bin/tee"
else # /usr/bin/tee location was handled
TEE="/usr/bin/tee"
fi
if [[ -f /bin/ls ]]
then
LS="/bin/ls"
else # /usr/bin/ls location was handled
LS="/usr/bin/ls"
fi
CURSCRIPTNAME="$0"
echo "$CURSCRIPTNAME" | $EGREP -E "^\-bash|^bash|^ksh|^mksh" >/dev/null 2>&1
# Above commmand not tested at all platforms.
SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET=$?
if [[ 0 -eq $SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET ]]
then
echo "Cannot execute this script in current shell."
elif [[ "" != "$BASENAME" ]]
then
BASENAME=''`$BASENAME $CURSCRIPTNAME`''
LOGNAME=''`$WHOAMI`''
MAILTO="$LOGNAME@localhost"
if [[ -f /etc/cron.d/check_ps ]]
then
if [[ -w /etc/cron.d/check_ps ]]
then
#Based on comment from skullnobrains
$TEE /etc/cron.d/check_ps << EOF >/dev/null || ! echo "failed to write the cron file, bye"
*/10 * * * * root $EGREP -Fv /tmp/ps_names -f /tmp/ps_names_running >2&1
EOF
else
echo "Write permission denied /etc/cron.d/check_ps for current user: $LOGNAME"
echo "$LS -l /etc/cron.d/check_ps"
echo $CURSCRIPTNAME
$LS -l /etc/cron.d/check_ps
echo "ERROR" | $EGREP "error"
fi
else
echo "No such file /etc/cron.d/check_ps"
echo "ERROR" | $EGREP "error"
fi
fi
fi
Q1. Handle forthcoming exceptions
@ all OS(AIX/*BSD/Cygwin*/Darwin
Thanks for your responses, Murugesan.
Q3. Why do you have to handle forthcoming exceptions for a one-off task which can be run from the command line?
Q4. Why do you have a space before the closing quote in lines like this?:
EGREP="/bin/grep -E "
Q5. If this gets executed:
EGREP="/bin/grep -E "
then later this gets executed:
echo "$CURSCRIPTNAME" | $EGREP -E "^\-bash|^bash|^ksh|^mksh" >/dev/null 2>&1
Isn't that like doing this?:
echo "$CURSCRIPTNAME" | /bin/grep -E -E "^\-bash|^bash|^ksh|^mksh" >/dev/null 2>&1
It may work, but is has an extra "-E" and an extra space.
Q3. Why do you have to handle forthcoming exceptions for a one-off task which can be run from the command line?
Q4. Why do you have a space before the closing quote in lines like this?:
EGREP="/bin/grep -E "
Q5. If this gets executed:
EGREP="/bin/grep -E "
then later this gets executed:
echo "$CURSCRIPTNAME" | $EGREP -E "^\-bash|^bash|^ksh|^mksh"
Isn't that like doing this?:
echo "$CURSCRIPTNAME" | /bin/grep -E -E "^\-bash|^bash|^ksh|^mksh"
It may work, but is has an extra "-E" and an extra space.
echo | /usr/bin/wc
Q3.
forth coming exception => The exception which may occur in future if a new joiner join current work.
Q4.
I cannot remember the error which happened in previous company. It required space ( using regular expression [/bin/sed] and edi/idoc files)
Q5:
Thank you for pointing that.
Updated the same.
Q3.
forth coming exception => The exception which may occur in future if a new joiner join current work.
Q4.
I cannot remember the error which happened in previous company. It required space ( using regular expression [/bin/sed] and edi/idoc files)
Q5:
Thank you for pointing that.
Updated the same.
#!/bin/ksh
# Better use full path
# Handle logging and exceptions
# Handle file exceptions
# Handle all ways to execute the script.
#----------------------------------.---------------------------------.
# Follow current update like svn | or git |
#----------------------------------.---------------------------------|
# DATE FORMAT: /bin/date "+%d_%b_%Y_%H_%M_%S %Z"|modified/created by |
# |Updated details. |
#----------------------------------.---------------------------------|
# Previous updates: | |
#----------------------------------.---------------------------------.
#Handle all such kind of error.
# /bin/egrep location being handled
# Like this, all binary location exceptions and $PATH kind of environment variables needs to be handled.
# Based on comment from tel2
if [[ ! -f /bin/grep && ! -f /bin/egrep && ! -f /usr/bin/grep && ! -f /usr/bin/egrep ]]
then
echo "Unable to find location of grep"
# /usr/bin/basename being handled
elif [[ ! -f /bin/basename && ! -f /usr/bin/basename ]]
then
echo "Unable to find location of basename"
# /usr/bin/whoami being handled
elif [[ ! -f /bin/whoami && ! -f /usr/bin/whoami ]]
then
echo "Unable to find location of whoami"
# /usr/bin/tee being handled
elif [[ ! -f /bin/tee && ! -f /usr/bin/tee ]]
then
echo "Unable to find location of tee"
elif [[ ! -f /bin/ls && ! -f /usr/bin/ls ]]
then
echo "Unable to find location of ls"
else
if [[ -f /bin/egrep ]]
then
EGREP="/bin/egrep "
elif [[ -f /bin/grep ]]
then
EGREP="/bin/grep -E "
elif [[ -f /usr/bin/egrep ]]
then
EGREP="/usr/bin/egrep"
else # /usr/bin/grep location was handled
EGREP="/usr/bin/grep -E "
fi
# Handle similar exceptions for all executable locations.
if [[ -f /usr/bin/basename ]]
then
BASENAME="/usr/bin/basename"
else # /usr/bin/basename location was handled
BASENAME="/usr/bin/basename"
fi
if [[ -f /bin/whoami ]]
then
WHOAMI="/bin/whoami"
else # /usr/bin/whoami location was handled
WHOAMI="/usr/bin/whoami"
fi
if [[ -f /bin/tee ]]
then
TEE="/bin/tee"
else # /usr/bin/tee location was handled
TEE="/usr/bin/tee"
fi
if [[ -f /bin/ls ]]
then
LS="/bin/ls"
else # /usr/bin/ls location was handled
LS="/usr/bin/ls"
fi
CURSCRIPTNAME="$0"
echo "$CURSCRIPTNAME" | $EGREP "^\-bash|^bash|^ksh|^mksh" >/dev/null 2>&1
# Above commmand not tested at all platforms.
SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET=$?
if [[ 0 -eq $SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET ]]
then
echo "Cannot execute this script in current shell."
elif [[ "" != "$BASENAME" ]]
then
BASENAME=''`$BASENAME $CURSCRIPTNAME`''
LOGNAME=''`$WHOAMI`''
MAILTO="$LOGNAME@localhost"
if [[ -f /etc/cron.d/check_ps ]]
then
if [[ -w /etc/cron.d/check_ps ]]
then
#Based on comment from skullnobrains
$TEE /etc/cron.d/check_ps << EOF >/dev/null || ! echo "failed to write the cron file, bye"
*/10 * * * * root $EGREP -Fv /tmp/ps_names -f /tmp/ps_names_running >2&1
EOF
else
echo "Write permission denied /etc/cron.d/check_ps for current user: $LOGNAME"
echo "$LS -l /etc/cron.d/check_ps"
echo $CURSCRIPTNAME
$LS -l /etc/cron.d/check_ps
echo "ERROR" | $EGREP "error"
fi
else
echo "No such file /etc/cron.d/check_ps"
echo "ERROR" | $EGREP "error"
fi
fi
fi
Thanks for your response, Murugesan.
Your answer to Q3 isn't really satisfying, but I'm going to give up on that one, because I doubt we're going to get anywhere with it.
> "Q4. I cannot remember the error which happened in previous company. It required space ( on using regular expression [/bin/sed] and edi/idoc files)"
Q6. Where is your proof of this? Please either provide proof of that error (e.g. with a link to some evidence), or stop stating it. Failing that, how do we know you're remembering correctly or there wasn't some other cause of the error? This is how programming rumours could start, and people could continue to use & write strange code for no valid reason for years.
Q7. Why do you have the extra space on some lines, like:
EGREP="/bin/egrep "
but not on others, like?:
EGREP="/usr/bin/egrep"
Q8. Why don't you write this:
elif [[ "" != "$BASENAME" ]]
in this more common & easy to read way:
elif [[ "$BASENAME" != "" ]]
or even this way:
elif [[ ! -z "$BASENAME" ]]
(If you're going to claim that putting the value on the left and the variable on the right, was required in some very old version of ksh, as I think you have claimed in a post last year, then tell me...
Q9. Where is your proof of this?
Please prove it (e.g. with a link to some evidence), or stop claiming it. (Failing that, how do we know you're remembering correctly or there wasn't some other cause of the error? This is how programming rumours could start, and people could continue to use & write strange code for no valid reason for years.)
Q10. Why do you have these extra 4 single quotes in lines like this:
LOGNAME=''`$WHOAMI`''
when you could simply have this?:
LOGNAME=`$WHOAMI`
You've done this more than once in this script.
Your answer to Q3 isn't really satisfying, but I'm going to give up on that one, because I doubt we're going to get anywhere with it.
> "Q4. I cannot remember the error which happened in previous company. It required space ( on using regular expression [/bin/sed] and edi/idoc files)"
Q6. Where is your proof of this? Please either provide proof of that error (e.g. with a link to some evidence), or stop stating it. Failing that, how do we know you're remembering correctly or there wasn't some other cause of the error? This is how programming rumours could start, and people could continue to use & write strange code for no valid reason for years.
Q7. Why do you have the extra space on some lines, like:
EGREP="/bin/egrep "
but not on others, like?:
EGREP="/usr/bin/egrep"
Q8. Why don't you write this:
elif [[ "" != "$BASENAME" ]]
in this more common & easy to read way:
elif [[ "$BASENAME" != "" ]]
or even this way:
elif [[ ! -z "$BASENAME" ]]
(If you're going to claim that putting the value on the left and the variable on the right, was required in some very old version of ksh, as I think you have claimed in a post last year, then tell me...
Q9. Where is your proof of this?
Please prove it (e.g. with a link to some evidence), or stop claiming it. (Failing that, how do we know you're remembering correctly or there wasn't some other cause of the error? This is how programming rumours could start, and people could continue to use & write strange code for no valid reason for years.)
Q10. Why do you have these extra 4 single quotes in lines like this:
LOGNAME=''`$WHOAMI`''
when you could simply have this?:
LOGNAME=`$WHOAMI`
You've done this more than once in this script.
@tel2,@mn : although i mostly agree the 100 lines of code only make it more complex, and adds plain wrong error handling ( "Write permission denied" is a basement-less assumption ) ... among other possible bugs , this is of no help to the author and had better be discussed privately.
>> Q6
Applied those changes.
>> Q7
If faced in future, will post the same exception.
>> Q8
I was from C++ C (https://rt.openssl.org/Ticket/Display.html?id=906&user=guest&pass=guest)
Reverted those changes.
Done those changes for me to remember C C++ due to variable assignment exception using if.
Above comment was posted in other thread.
>> Q9
No proof, at my system (because of security policies till 2013 at previous job).
Reverted all those changes.
If I face in future, will post the same exception (Most probably I won't get, since never seen that exception outside that job)
>> Q10
Reverted those changes.
Example:
Applied those changes.
>> Q7
If faced in future, will post the same exception.
>> Q8
I was from C++ C (https://rt.openssl.org/Ticket/Display.html?id=906&user=guest&pass=guest)
Reverted those changes.
Done those changes for me to remember C C++ due to variable assignment exception using if.
Above comment was posted in other thread.
>> Q9
No proof, at my system (because of security policies till 2013 at previous job).
Reverted all those changes.
If I face in future, will post the same exception (Most probably I won't get, since never seen that exception outside that job)
>> Q10
Reverted those changes.
Example:
$ /usr/bin/sudo /bin/su -c echo `/usr/bin/whoami`
$ /usr/bin/sudo /bin/su -c "echo `/usr/bin/whoami`"
murugesandins
$ /usr/bin/sudo /bin/su -c 'echo `/usr/bin/whoami`'
root
Like this, used few commands (No related email/document) Hence reverted those changes.#!/bin/ksh
# Better use full path
# Handle logging and exceptions
# Handle file exceptions
# Handle all ways to execute the script.
#----------------------------------.---------------------------------.
# Follow current update like svn | or git |
#----------------------------------.---------------------------------|
# DATE FORMAT: /bin/date "+%d_%b_%Y_%H_%M_%S %Z"|modified/created by |
# |Updated details. |
#----------------------------------.---------------------------------|
# Previous updates: | |
#----------------------------------.---------------------------------.
#Handle all such kind of error.
# /bin/egrep location being handled
# Like this, all binary location exceptions and $PATH kind of environment variables needs to be handled.
# Based on comment from tel2
if [[ ! -f /bin/grep && ! -f /bin/egrep && ! -f /usr/bin/grep && ! -f /usr/bin/egrep ]]
then
echo "Unable to find location of grep"
# /usr/bin/basename being handled
elif [[ ! -f /bin/basename && ! -f /usr/bin/basename ]]
then
echo "Unable to find location of basename"
# /usr/bin/whoami being handled
elif [[ ! -f /bin/whoami && ! -f /usr/bin/whoami ]]
then
echo "Unable to find location of whoami"
# /usr/bin/tee being handled
elif [[ ! -f /bin/tee && ! -f /usr/bin/tee ]]
then
echo "Unable to find location of tee"
elif [[ ! -f /bin/ls && ! -f /usr/bin/ls ]]
then
echo "Unable to find location of ls"
else
if [[ -f /bin/egrep ]]
then
EGREP="/bin/egrep"
elif [[ -f /bin/grep ]]
then
EGREP="/bin/grep -E"
elif [[ -f /usr/bin/egrep ]]
then
EGREP="/usr/bin/egrep"
else # /usr/bin/grep location was handled
EGREP="/usr/bin/grep -E"
fi
# Handle similar exceptions for all executable locations.
if [[ -f /usr/bin/basename ]]
then
BASENAME="/usr/bin/basename"
else # /usr/bin/basename location was handled
BASENAME="/usr/bin/basename"
fi
if [[ -f /bin/whoami ]]
then
WHOAMI="/bin/whoami"
else # /usr/bin/whoami location was handled
WHOAMI="/usr/bin/whoami"
fi
if [[ -f /bin/tee ]]
then
TEE="/bin/tee"
else # /usr/bin/tee location was handled
TEE="/usr/bin/tee"
fi
if [[ -f /bin/ls ]]
then
LS="/bin/ls"
else # /usr/bin/ls location was handled
LS="/usr/bin/ls"
fi
CURSCRIPTNAME="$0"
echo "$CURSCRIPTNAME" | $EGREP "^\-bash|^bash|^ksh|^mksh" >/dev/null 2>&1
# Above commmand not tested at all platforms.
SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET=$?
if [[ 0 -eq $SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET ]]
then
echo "Cannot execute this script in current shell."
elif [[ ! -z "$BASENAME" ]]
then
BASENAME=`$BASENAME $CURSCRIPTNAME`
LOGNAME=`$WHOAMI`
#Change LOGNAME and localhost based on requirement
MAILTO="$LOGNAME@localhost"
if [[ -f /etc/cron.d/check_ps ]]
then
if [[ -w /etc/cron.d/check_ps ]]
then
#Based on comment from skullnobrains
$TEE /etc/cron.d/check_ps << EOF >/dev/null || ! echo "failed to write the cron file, bye"
*/10 * * * * root $EGREP -Fv /tmp/ps_names -f /tmp/ps_names_running >2&1
EOF
else
echo "Write permission denied /etc/cron.d/check_ps for current user: $LOGNAME"
echo "$LS -l /etc/cron.d/check_ps"
echo $CURSCRIPTNAME
$LS -l /etc/cron.d/check_ps
echo "ERROR" | $EGREP "error"
fi
else
echo "No such file /etc/cron.d/check_ps"
echo "ERROR" | $EGREP "error"
fi
fi
fi
Hi Murugesan,
Now looking at your first line ("#!/usr/ksh"), what happens if the machine doesn't have ksh, like the Cloud Linux box I'm using doesn't? If you're going to try to cater for every eventuality, it could get very messy. Have you heard of KISS? Keep It Simple, Saint.
Hi skullnobrains,
> "this is of no help to the author and had better be discussed privately"
I hear ya, but one reason it can be useful to have such debates in the question thread is, if any issues are not agreed on and the code is not changed as a result, then at least the questioner can see the issues raised, so (s)he can decide which way to go in his/her case.
> "!" negates the following command ( echo always returns "0" ) so the script returns "1" ( error ) rather than "0" ( no error ) if the tee command fails.
This is a new one for me, and I can't get it to work yet, but could you please provide a simpler example (e.g. a one-liner) which I can test from the command line, because my attempts to do so are failing. And/or a link to some documentation about it, would be good.
Now looking at your first line ("#!/usr/ksh"), what happens if the machine doesn't have ksh, like the Cloud Linux box I'm using doesn't? If you're going to try to cater for every eventuality, it could get very messy. Have you heard of KISS? Keep It Simple, Saint.
Hi skullnobrains,
> "this is of no help to the author and had better be discussed privately"
I hear ya, but one reason it can be useful to have such debates in the question thread is, if any issues are not agreed on and the code is not changed as a result, then at least the questioner can see the issues raised, so (s)he can decide which way to go in his/her case.
> "!" negates the following command ( echo always returns "0" ) so the script returns "1" ( error ) rather than "0" ( no error ) if the tee command fails.
This is a new one for me, and I can't get it to work yet, but could you please provide a simpler example (e.g. a one-liner) which I can test from the command line, because my attempts to do so are failing. And/or a link to some documentation about it, would be good.
Thank you tel2, for given comments.
Simple => script also need to include all exceptions @ all platforms (including $?). 23 commented lines for enhancement/error handling/future/further comments :)
Total lines currently: 106
Tested original and updated code using:
1. /bin/ksh (and cygwin /bin/mksh.exe linked to /bin/ksh)
2. /bin/bash (and cygwin)
Difference between updated and previous code:
Simple => script also need to include all exceptions @ all platforms (including $?). 23 commented lines for enhancement/error handling/future/further comments :)
Total lines currently: 106
Tested original and updated code using:
1. /bin/ksh (and cygwin /bin/mksh.exe linked to /bin/ksh)
2. /bin/bash (and cygwin)
Difference between updated and previous code:
$ /bin/diff Original.sh 29077002.sh
94a95,116
> TEE_RET=$?
> if [[ 0 -eq $TEE_RET ]]
> then
> if [[ -f /etc/cron.d/check_ps ]]
> then
> if [[ -s /etc/cron.d/check_ps ]]
> then
> echo "Created the file /etc/cron.d/check_ps"
> echo "$LS -l /etc/cron.d/check_ps"
> $LS -l /etc/cron.d/check_ps
> else
> echo "/etc/cron.d/check_ps file is empty FAILED"
> echo "ERROR" | $EGREP "error"
> fi
> else
> echo "Creating /etc/cron.d/check_ps FAILED"
> echo "ERROR" | $EGREP "error"
> fi
> else
> echo "tee [ $TEE ] using EOF FAILED"
> echo "ERROR" | $EGREP "error"
> fi
Updated code:#!/bin/ksh
# Better use full path
# Handle logging and exceptions
# Handle file exceptions
# Handle all ways to execute the script.
#----------------------------------.---------------------------------.
# Follow current update like svn | or git |
#----------------------------------.---------------------------------|
# DATE FORMAT: /bin/date "+%d_%b_%Y_%H_%M_%S %Z"|modified/created by |
# |Updated details. |
#----------------------------------.---------------------------------|
# Previous updates: | |
#----------------------------------.---------------------------------.
#Handle all such kind of error.
# /bin/egrep location being handled
# Like this, all binary location exceptions and $PATH kind of environment variables needs to be handled.
# Based on comment from tel2
if [[ ! -f /bin/grep && ! -f /bin/egrep && ! -f /usr/bin/grep && ! -f /usr/bin/egrep ]]
then
echo "Unable to find location of grep"
# /usr/bin/basename being handled
elif [[ ! -f /bin/basename && ! -f /usr/bin/basename ]]
then
echo "Unable to find location of basename"
# /usr/bin/whoami being handled
elif [[ ! -f /bin/whoami && ! -f /usr/bin/whoami ]]
then
echo "Unable to find location of whoami"
# /usr/bin/tee being handled
elif [[ ! -f /bin/tee && ! -f /usr/bin/tee ]]
then
echo "Unable to find location of tee"
elif [[ ! -f /bin/ls && ! -f /usr/bin/ls ]]
then
echo "Unable to find location of ls"
else
if [[ -f /bin/egrep ]]
then
EGREP="/bin/egrep"
elif [[ -f /bin/grep ]]
then
EGREP="/bin/grep -E"
elif [[ -f /usr/bin/egrep ]]
then
EGREP="/usr/bin/egrep"
else # /usr/bin/grep location was handled
EGREP="/usr/bin/grep -E"
fi
# Handle similar exceptions for all executable locations.
if [[ -f /usr/bin/basename ]]
then
BASENAME="/usr/bin/basename"
else # /usr/bin/basename location was handled
BASENAME="/usr/bin/basename"
fi
if [[ -f /bin/whoami ]]
then
WHOAMI="/bin/whoami"
else # /usr/bin/whoami location was handled
WHOAMI="/usr/bin/whoami"
fi
if [[ -f /bin/tee ]]
then
TEE="/bin/tee"
else # /usr/bin/tee location was handled
TEE="/usr/bin/tee"
fi
if [[ -f /bin/ls ]]
then
LS="/bin/ls"
else # /usr/bin/ls location was handled
LS="/usr/bin/ls"
fi
CURSCRIPTNAME="$0"
echo "$CURSCRIPTNAME" | $EGREP "^\-bash|^bash|^ksh|^mksh" >/dev/null 2>&1
# Above commmand not tested at all platforms.
SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET=$?
if [[ 0 -eq $SCRIPT_EXECUTED_IN_CURRENT_SHELL_RET ]]
then
echo "Cannot execute this script in current shell."
elif [[ ! -z "$BASENAME" ]]
then
BASENAME=`$BASENAME $CURSCRIPTNAME`
LOGNAME=`$WHOAMI`
#Change LOGNAME and localhost based on requirement
MAILTO="$LOGNAME@localhost"
if [[ -f /etc/cron.d/check_ps ]]
then
if [[ -w /etc/cron.d/check_ps ]]
then
#Based on comment from skullnobrains
$TEE /etc/cron.d/check_ps << EOF >/dev/null || ! echo "failed to write the cron file, bye"
*/10 * * * * root $EGREP -Fv /tmp/ps_names -f /tmp/ps_names_running >2&1
EOF
else
echo "Write permission denied /etc/cron.d/check_ps for current user: $LOGNAME"
echo "$LS -l /etc/cron.d/check_ps"
echo $CURSCRIPTNAME
$LS -l /etc/cron.d/check_ps
echo "ERROR" | $EGREP "error"
fi
else
echo "No such file /etc/cron.d/check_ps"
echo "ERROR" | $EGREP "error"
fi
fi
fi
After reducing number of lines, will post updated code.
1. Removed all comments (needs related documentation)
2. Tested the same using /bin/bash /bin/bash.exe /bin/mksh.exe /bin/ksh including/excluding /usr/bin/sudo
2. Tested the same using /bin/bash /bin/bash.exe /bin/mksh.exe /bin/ksh including/excluding /usr/bin/sudo
#!/bin/ksh
if [[ -f /usr/bin/egrep && /usr/bin/tee && -f /bin/ls && -f /usr/bin/whoami && /bin/cat ]]
then
CURSCRIPTNAME="$0"
echo "$CURSCRIPTNAME" | /usr/bin/egrep "^\-bash|^bash|^ksh|^mksh" >/dev/null 2>&1
if [[ 0 -eq $? ]]
then
echo "Cannot execute this script in current shell."
else
LOGNAME=`/usr/bin/whoami`
MAILTO="$LOGNAME@localhost"
if [[ -f /etc/cron.d/check_ps ]]
then
if [[ -w /etc/cron.d/check_ps ]]
then
/usr/bin/tee /etc/cron.d/check_ps << EOF >/dev/null || ! echo "failed to write the cron file, bye"
*/10 * * * * root /usr/bin/egrep -Fv /tmp/ps_names -f /tmp/ps_names_running >2&1
EOF
if [[ 0 -eq $? ]]
then
if [[ -f /etc/cron.d/check_ps ]]
then
if [[ -s /etc/cron.d/check_ps ]]
then
echo -e "Updated the file /etc/cron.d/check_ps\n$ /bin/cat /etc/cron.d/check_ps"
/bin/cat /etc/cron.d/check_ps
else
echo "/etc/cron.d/check_ps file is empty FAILED"
echo ERROR | /usr/bin/egrep error
fi
else
echo "Creating /etc/cron.d/check_ps FAILED"
echo ERROR | /usr/bin/egrep error
fi
else
echo "tee [ /usr/bin/tee ] using EOF FAILED"
echo ERROR | /usr/bin/egrep error
fi
else
echo -e "For current user: $LOGNAME cannot write [Permission denied]:\n$ /bin/ls -l /etc/cron.d/check_ps"
/bin/ls -l /etc/cron.d/check_ps
echo ERROR | /usr/bin/egrep error
fi
else
echo -e "No such file /etc/cron.d/check_ps\n$ /bin/ls -ld /etc/cron.d/check_ps"
/bin/ls -ld /etc/cron.d/check_ps
fi
fi
else
echo "Update this script having correct location for:"
/bin/ls -l /usr/bin/egrep /usr/bin/tee /bin/ls /usr/bin/whoami /bin/cat >/dev/null
fi
@tel2
see your favorite shell man page
again please discuss your own issues in your own threads : you are hijacking this one without even bothering to provide your own solution.
@mm
my short script will work on pretty much any platform and many shells providing the PATH is set properly. try it. your script most likely will not. adding a lot of complexity does not help making your script portable or less error prone.
additionally many of the tests and error handling are meaningless or plain wrong :
@both
posting 10 versions of the same solution without author intervention does not help him in any way and creates a mountain to read for a very simple question. i see no value added past @murugesan's very first script and my own.
This is a new one for me, and I can't get it to work yet, but could you please provide a simpler example
$ ! echo test
test
$ echo $?
1
see your favorite shell man page
again please discuss your own issues in your own threads : you are hijacking this one without even bothering to provide your own solution.
@mm
my short script will work on pretty much any platform and many shells providing the PATH is set properly. try it. your script most likely will not. adding a lot of complexity does not help making your script portable or less error prone.
additionally many of the tests and error handling are meaningless or plain wrong :
- the EOF stuff will NEVER trigger on any shell that does not support heredocs or this heredoc syntax because the shell will either crash at the following line or stick the script body into the file and crash when reaching the last line of the script. ... but it will trigger on many DIFFERENT errors such as the disk being full and output a misleading error message
- full paths make it less portable and not more secure : just control your PATH environment when you need that kind of security
- checking the shell version will prevent it from working in for example dash and bsd's sh while it would work should you let it
- ... and so on
@both
posting 10 versions of the same solution without author intervention does not help him in any way and creates a mountain to read for a very simple question. i see no value added past @murugesan's very first script and my own.
Better to use full path.
$ unset -f ls
ls ()
{
echo use full path for ls to use
echo ls $@
return 12
}
$ ls murugesandins
$ echo $?
12
$
$ unset -f ls
ls ()
{
echo use full path for ls to use
echo ls $@
return 12
}
$ ls murugesandins
$ echo $?
12
$
looks to me like putting on a full body armor before shooting yourself in the foot voluntarily.
if you want to prevent such things, you'd also need to prevent folks from replacing the ls command entirely with a different one.
... in that case, rather rely on builtins entirely
busybox might be worth considering for a builtin-only setup with a decent set of commands available
if you want to make sure to use the system command rather than an alias or builtin, you can unset aliases first or possibly use an idiom such as "`which ls`" rather than just "ls". that way, you only need to bother with the path variable in one place.
also note that you can use -i with pretty much all shells and --norc with many shells which alleviates problems due to admins toying with .profile and the likes ( if that is actually your concern which would be my guess given your last comment )
best regards
if you want to prevent such things, you'd also need to prevent folks from replacing the ls command entirely with a different one.
... in that case, rather rely on builtins entirely
busybox might be worth considering for a builtin-only setup with a decent set of commands available
if you want to make sure to use the system command rather than an alias or builtin, you can unset aliases first or possibly use an idiom such as "`which ls`" rather than just "ls". that way, you only need to bother with the path variable in one place.
also note that you can use -i with pretty much all shells and --norc with many shells which alleviates problems due to admins toying with .profile and the likes ( if that is actually your concern which would be my guess given your last comment )
best regards
Writing following comment to exclude following kind of exceptions (any time)
Example using `which ls`
Example using `which ls`
$ echo $PATH | /bin/awk -F: '{ print $1}'
/home/murugesandins
$ /usr/bin/gcc -g -Wall which.c -o ./which
$ #Use related compiler and related language at related OS
$ which ls
use full path using which
which ls
$ echo $?
12
i do not see your point. demonstrating that you can mess up the shell in such a way ls won't work properly is not a good reason to bother recoding the shell existing features with additional bugs.
if you're going that way, try and alias echo to exit. that will break very efficiently your code as well. and pretty much any other.
a proper code is not a code that makes the right assumptions regarding it's environment. it is a code that will either do what it is instructed or break cleanly with a decent error message.
adding complexity just in case someone messes up the profile or startup script seems overkill. just make sure you don't load them if you have no control over them. and don't add misleading error messages to commands that otherwise produce a meaningful one.
it is also a good idea to not use commands you don't need : for example, ls is not needed to perform this task and clearly one of the less portable commands around.
--
btw, the way you check which shell is running is also very error prone and relies on stuff that can be messed up even involuntarily such as actually making the script executable so you probably won't have the extension in the name nor $0 working the way you assume, not speaking about executing a .bash script with zsh and the likes
you should actually handle the error after the "tee || ! echo ..." where it occurs : your script should exit in case this fails rather than print the tee error message, then the one i wrote ( which is overkill ), than a 3rd additional one ( with a groundless assumption regarding why it failed ) or rechecking when the tee already reported it wrote the file successfully. if tee says so, then the file is actually written. this is why i bother using tee rather than shell redirections.
rather write it as "! tee ... && echo ... && exit 1" for example ( yes assuming echo exists and returns 0 )
--
anyway, we're not any help to the author...
see you around
regards
if you're going that way, try and alias echo to exit. that will break very efficiently your code as well. and pretty much any other.
a proper code is not a code that makes the right assumptions regarding it's environment. it is a code that will either do what it is instructed or break cleanly with a decent error message.
adding complexity just in case someone messes up the profile or startup script seems overkill. just make sure you don't load them if you have no control over them. and don't add misleading error messages to commands that otherwise produce a meaningful one.
it is also a good idea to not use commands you don't need : for example, ls is not needed to perform this task and clearly one of the less portable commands around.
--
btw, the way you check which shell is running is also very error prone and relies on stuff that can be messed up even involuntarily such as actually making the script executable so you probably won't have the extension in the name nor $0 working the way you assume, not speaking about executing a .bash script with zsh and the likes
you should actually handle the error after the "tee || ! echo ..." where it occurs : your script should exit in case this fails rather than print the tee error message, then the one i wrote ( which is overkill ), than a 3rd additional one ( with a groundless assumption regarding why it failed ) or rechecking when the tee already reported it wrote the file successfully. if tee says so, then the file is actually written. this is why i bother using tee rather than shell redirections.
rather write it as "! tee ... && echo ... && exit 1" for example ( yes assuming echo exists and returns 0 )
--
anyway, we're not any help to the author...
see you around
regards
$#Closing my comment
Hi scullnobrains,
> "again please discuss your own issues in your own threads : you are hijacking this one without even bothering to provide your own solution."
I've got 7 questions for you about your comment, above:
Q1. Why is it OK for you to critique Murugesan's code in this public thread, but not OK for me to?
Q2. Why are they "our own issues" when I do it, but not when you do it?
Q3. If I critiqued his code privately (which you don't seem to be doing), then Murugesan would probably just post the amended version in this public thread, and unless he documented the changes well, people would not be able to see why things were changed. How would that be better?
Q4. I'm not bothering to provide my own solution because I don't have anything to add to yours. My input is to try to improve Murugesan's solution, (which will hopefully carry over to his future solutions). Any problem with that?
Q5. Is it against the rules for experts to critique other experts' solutions without providing their own solutions? If so, where is that rule?
Q6. Given the above, in what way have I hijacked this thread?
Q7. If my posts were "hijacking", then why weren't yours?
Thanks for the tip on "! echo...".
> "again please discuss your own issues in your own threads : you are hijacking this one without even bothering to provide your own solution."
I've got 7 questions for you about your comment, above:
Q1. Why is it OK for you to critique Murugesan's code in this public thread, but not OK for me to?
Q2. Why are they "our own issues" when I do it, but not when you do it?
Q3. If I critiqued his code privately (which you don't seem to be doing), then Murugesan would probably just post the amended version in this public thread, and unless he documented the changes well, people would not be able to see why things were changed. How would that be better?
Q4. I'm not bothering to provide my own solution because I don't have anything to add to yours. My input is to try to improve Murugesan's solution, (which will hopefully carry over to his future solutions). Any problem with that?
Q5. Is it against the rules for experts to critique other experts' solutions without providing their own solutions? If so, where is that rule?
Q6. Given the above, in what way have I hijacked this thread?
Q7. If my posts were "hijacking", then why weren't yours?
Thanks for the tip on "! echo...".
Q1 : i was wrong to do so. but note that i'm barely responding to him. i did not critique his code in the first place. actually i both endorsed his comment because it is apparently a working solution and provided an additional one. digressions came later and out-of-place. my bad.
Q2 : because i'm not asking my own rtfm questions. feel free to ask those privately. additionally i've been waiting for the thread to be dead to the author before discussing anything unrelated at length. but yet i was wrong again.
Q3 : you could as well provide a working variant based on his code, give credits, and explain why you made the changes if you don't think it's obvious... and discuss coding pratice or stuff that could be written in a different way but won't prevent the code from working ( such as extraneous spaces ) in a different thread.
Q4 : no, and see above
Q5 : no, it's just rude. but then i'm no one to talk since i've been quite rude myself which is extra-dumb knowing that there may be some actual reason why @mn does some of his things that i don't get possibly because neither of us are native english speakers.
Q6 : ok. let's say i'm the hijacker... and i'm out ... 2>&-
Q7 : i'm pretty sure this one is redundant with the above
Q2 : because i'm not asking my own rtfm questions. feel free to ask those privately. additionally i've been waiting for the thread to be dead to the author before discussing anything unrelated at length. but yet i was wrong again.
Q3 : you could as well provide a working variant based on his code, give credits, and explain why you made the changes if you don't think it's obvious... and discuss coding pratice or stuff that could be written in a different way but won't prevent the code from working ( such as extraneous spaces ) in a different thread.
Q4 : no, and see above
Q5 : no, it's just rude. but then i'm no one to talk since i've been quite rude myself which is extra-dumb knowing that there may be some actual reason why @mn does some of his things that i don't get possibly because neither of us are native english speakers.
Q6 : ok. let's say i'm the hijacker... and i'm out ... 2>&-
Q7 : i'm pretty sure this one is redundant with the above
Thanks for that, scullnobrains. I have responded privately.
ASKER
Thanks everyone, I have completed the script with the help of your comments.
I took Murugesan's script and modified it to my need. I will post it.
All your time is valuable to me, it helps me.
Sorry for the late response. I will try to post my comments immediately next time onwards.
I took Murugesan's script and modified it to my need. I will post it.
All your time is valuable to me, it helps me.
Sorry for the late response. I will try to post my comments immediately next time onwards.
ASKER
Hi Murugesan,
Sorry that I didn't post results for so long, I was traveling and then got busy in some work but tell you that with your help I have completed the script and using it.
My apologies for so late response.
I would like to thank you for your time and help.
I will post modified script, it is not having error handling but it does the job.
Sat
Sorry that I didn't post results for so long, I was traveling and then got busy in some work but tell you that with your help I have completed the script and using it.
My apologies for so late response.
I would like to thank you for your time and help.
I will post modified script, it is not having error handling but it does the job.
Sat
@S-a-t
No problem :)
>> I would like to thank you for your time and help.
close this query by accepting/assisting provided solution(s).
echo welcome | /usr/bin/wc
No problem :)
>> I would like to thank you for your time and help.
close this query by accepting/assisting provided solution(s).
echo welcome | /usr/bin/wc
I doubt I'll be working on this myself, but as with most requests for code, I would suggest you provide sample input files and expected output (i.e. the email content) which cover the different scenarios, so experts will hopefully:
a) Understand exactly what you mean. Right now it's not completely clear to me.
b) Know when their solution meets your requirements, without having to go back and forth asking you, etc.
Doing this will probably save the experts time (which they are donating so you should do your best to make it easy for them), and your time in telling when they've got it wrong, etc. And sometimes this could mean you end up getting a solution in hours instead of days, because it gives experts a good chance of getting it right first time.
Thanks.
tel2