Linux sendmail nohup Repeatable Email Report Tutorial
โœ‚๐Ÿƒ๐Ÿพโ€โ™€๏ธ๐Ÿƒ๐Ÿผโ€โ™‚๏ธ
๐Ÿ“–

Linux sendmail nohup Repeatable Email Report Tutorial

Linux sendmail nohup Repeatable Email Report Tutorial

We left off yesterdayโ€™s Linux sendmail nohup Report Content Tutorial โ€ฆ

โ€ฆ to start down this new parameterizable โ€œjourneyโ€. โ€œJourneyโ€, because there is more to do regarding โ€œtabularโ€ display in thought and action.

โ€ฆ panning out not to be the hardest step getting towards the โ€œstanding order repeatable and emailable reportโ€ aim to get to with todayโ€™s Korn Shell scripting work.

The fact is, most Linux command line statements produce tabbed output that if teamed with โ€ฆ



`cat date_ps_ef_first.txt | sed '/^/s//<tr><td>/g' | sed 's/ \{1,\}/<\/td><td>/g' | awk '{ t=0; while (getline \$0) { if (t == 0) { print \"<tr style=background-color:#e7e7e7 !important;\" substr(\$0,3); } else { print \$0; } t=1-t; } }' | sed '/$/s//<\/td><\/tr>/g'`

โ€ฆ the ability to convert multiple space characters into a single blank character gives us all we need as a basis to forego headings on โ€œnon-psโ€ commands, but nonetheless create decent tabular inline HTML email reports.

No, what was harder was โ€ฆ

  • carrying through to โ€œnohupโ€ the delimitation and special character considerations of allowing the user to define their own Linux report commands
  • carrying through to โ€œnohupโ€ the idea that any โ€œ?โ€ in a command line argument meant you asked for interactively entered (said Linux) command but not to carry that โ€œ?โ€ on into โ€œnohup landโ€

For you to see what we mean here, you can examine todayโ€™s tutorial picture and/or see thechanged date_ps_efโšซksh Korn Shell script to download and try yourself on your own Linux or unix or macOS system.



Previous relevant Linux sendmail nohup Report Content Tutorial is shown below.

Linux sendmail nohup Report Content Tutorial

Linux sendmail nohup Report Content Tutorial

Itโ€™s all fine and good adding โ€œnohupโ€ scheduling but what if there are not ways to schedule โ€œwhatโ€ (ie. the resultant report content) a lot of users want, adding onto the recent Linux sendmail nohup Refined Scheduling Tutorial?

Well, today, weโ€™re turning our attention to isolating the โ€œwhatโ€ and turning it into a parameterizable concept of our Korn Shell (Linux or unix or macOS) command line script.

This โ€œwhatโ€ report content default value is โ€ฆ



ps -ef | grep '/world.php' | grep -v 'grep'

โ€ฆ but the pipe โ€œ|โ€s were problematic to us within the one Korn Shell variable and so we coded for three parts to a command we โ€œ|โ€ pipe ourselves (any Claytonโ€™s pipes can be โ€ | grep โ€ โ€œ) โ€ฆ



topiccmd="`echo \"ps -ef | grep '/world.php' | grep -v 'grep '\"`"

topiccmd1="`echo \"ps -ef \"`"

topiccmd2="`echo \"grep '/world.php'\"`"

topiccmd3="`echo \"grep -v 'grep '\"`"

โ€ฆ and establish any user defined non-default via argument โ€œ?โ€ ( anywhere within one โ€ฆ eg. 10+1.5:?43 ) involvement teamed with (Korn Shell) script interactive entry, and readying command line flagging of non-default report actions, as per โ€ฆ



cmdsuffix=''

if [ "`echo \"${1}\" | sed '/^topiccmd/s///g'`" != "`echo \"${1}\"`" ]; then

if [ "`echo \"${1}\" | sed '/^topiccmd1=/s///g'`" != "`echo \"${1}\"`" ]; then

topiccmd1="`echo \"${1:10}\" | tr '~' ' '`"

cmdsuffix="${cmdsuffix} topiccmd1=${1:10}"

elif [ "`echo \"${1}\" | sed '/^topiccmd2=/s///g'`" != "`echo \"${1}\"`" ]; then

topiccmd2="`echo \"${1:10}\" | tr '~' ' '`"

cmdsuffix="${cmdsuffix} topiccmd2=${1:10}"

elif [ "`echo \"${1}\" | sed '/^topiccmd3=/s///g'`" != "`echo \"${1}\"`" ]; then

topiccmd3="`echo \"${1:10}\" | tr '~' ' '`"

cmdsuffix="${cmdsuffix} topiccmd3=${1:10}"

fi


elif [ "`echo \"${1}\" | sed '/\?/s///g'`" != "`echo \"${1}\"`" ]; then

topiccmd="ps -ef | grep '/world.php' | grep -v 'grep '"

topiccmd1="ps -ef"

topiccmd2="grep '/world.php'"

topiccmd3="grep -v 'grep '"


echo "Enter your Korn Shell understood command: [ ${topiccmd1} | ${topiccmd2} | ${topiccmd3} ]"

read ptopic


if [ ! -z "`echo \"${ptopic}\" | tr -d \"\\n\"`" ]; then

topiccmd2=" grep ''"

topiccmd3=" grep ''"

ptopic="`echo \"${ptopic}\" | sed \"/|/s//\\|/g\"`"

topiccmd1="`echo \"${ptopic}\" | cut -f 1 -d \"|\"`"

cmdsuffix="${cmdsuffix} topiccmd1=`echo \"${topiccmd1}\" | tr ' ' '~'`"

ptopic="${ptopic} | grep ''"

topiccmd2="`echo ${ptopic} | cut -f 2 -d \"|\"`"

cmdsuffix="${cmdsuffix} topiccmd2=`echo \"${topiccmd2}\" | tr ' ' '~'`"

ptopic="${ptopic} | grep ''"

topiccmd3="`echo ${ptopic} | cut -f 3 -d \"|\"`"

cmdsuffix="${cmdsuffix} topiccmd3=`echo \"${topiccmd3}\" | tr ' ' '~'`"

fi

fi


โ€ฆ so that where we once would have had echo โ€œ`ps -ef | grep โ€˜/world.phpโ€™ | grep -v โ€˜grep โ€˜`โ€ > date_ps_ef_first.txt we now have โ€ฆ



echo "${topiccmd1} | ${topiccmd2} | ${topiccmd3}" > date_ps_ef_first_bit.ksh

ksh ./date_ps_ef_first_bit.ksh > date_ps_ef_first.txt

rm -f ./date_ps_ef_first_bit.ksh

Here is thechanged date_ps_efโšซksh Korn Shell script to start down this new parameterizable โ€œjourneyโ€. โ€œJourneyโ€, because there is more to do regarding โ€œtabularโ€ display in thought and action.


Previous relevant Linux sendmail nohup Refined Scheduling Tutorial is shown below.

Linux sendmail nohup Refined Scheduling Tutorial

Linux sendmail nohup Refined Scheduling Tutorial

Yesterdayโ€™s Linux sendmail nohup Scheduling Tutorial left us with a Linux (or unix) โ€ฆ

  1. nohup
  2. โ€œ&โ€ background processing
  3. recursion (perhaps)

โ€ฆ scheduling Korn Shell script coding snippet for either โ€ฆ

  1. one off scheduled process execution โ€ฆ eg. date_ps_ef.ksh 10:43 โ€ฆ or โ€ฆ
  2. โ€œdailyโ€ continuous (as long as the server is up) process execution โ€ฆ eg. date_ps_ef.ksh 10:-43

โ€ฆ and today we get even closer to crontab with capabilities by adding to โ€œdailyโ€ scheduling the possibility for โ€œother time periodโ€ (continuous processing) scheduling. For example โ€ฆ

  • date_ps_ef.ksh 10+1.5:43 starts at the next โ€œ10:43โ€ and then every one hour and a half
  • date_ps_ef.ksh 10+40:43 starts at the next โ€œ10:43โ€ and then every forty minutes
  • date_ps_ef.ksh 10+60:43 starts at the next โ€œ10:43โ€ and then every minute (60 seconds)

And so, thechanged date_ps_efโšซksh Korn Shell script new logic parts for non-daily scheduling shows below โ€ฆ



if [ "`echo \"${1}\" | sed '/^0/s///g' | sed '/^1/s///g' | sed '/^2/s///g' | sed '/^3/s///g' | sed '/^4/s///g' | sed '/^5/s///g' | sed '/^6/s///g' | sed '/^7/s///g' | sed '/^8/s///g' | sed '/^9/s///g'`" != "`echo \"${1}\"" ]; then

if [ "`echo \"${1}\" | sed '/0$/s///g' | sed '/1$/s///g' | sed '/2$/s///g' | sed '/3$/s///g' | sed '/4$/s///g' | sed '/5$/s///g' | sed '/6$/s///g' | sed '/7$/s///g' | sed '/8$/s///g' | sed '/9$/s///g'`" != "`echo \"${1}\"" ]; then

if [ "`echo \"${1}\" | sed '/\:/s///g'`" != "`echo \"${1}\"" ]; then

pfrom=""

pto=""

preadddh=""

adddh=""

addh="0"

addm="0"

adds="0"


twoy=""

factor="1"

thsx="3600"

secstowait="0"

nowis="`date '+%H:%M:%S'`"

one="${1}"

oney="${1}"

his="`echo ${nowis} | cut -f 1 -d ':'`"

hfrom="`echo ${one}:00 | cut -f 1 -d ':' | cut -f 1 -d '-' | cut -f 1 -d '+' | tr -d '-'`"

mis="`echo ${nowis} | cut -f 2 -d ':'`"

mfrom="`echo ${one}:00 | cut -f 2 -d ':' | tr -d '-' | tr -d '+'`"

sis="`echo ${nowis} | cut -f 3 -d ':'`"

sfrom="`echo ${one}:00 | cut -f 3 -d ':' | tr -d '-' | tr -d '+'`"

if [ "`echo ${1} | tr -d '-'`" != "`echo ${1}`" ]; then

twoy="`echo ${1} | sed '/\:00\:00\:00\:00/s///g'`:00:00:00:00"

if [ "`echo ${1} | sed '/\:\-/s///g'`" == "`echo ${1}`" ]; then

preadddh="-"

adddh="`echo \"${one}:00\" | cut -f 2 -d '-' | cut -f 1 -d ':'`"

xadddh="`echo \"${adddh}\" | cut -f 1 -d '.'`"

if [ "`expr ${xadddh} \>= 24`" == "1" ]; then

if [ "`expr ${xadddh} \< 60`" == "1" ]; then

thsx="60"

factor="1"

else

thsx="1"

factor="1"

fi

fi

if [ "${adddh}" != "${xadddh}" ]; then

if [ "`expr ${xadddh} \>= 24`" == "1" ]; then

if [ "`expr ${xadddh} \< 60`" == "1" ]; then

thsx="60"

else

thsx="1"

fi

fi

zadddh="`echo \"${adddh}.\" | cut -f 2 -d '.'`"

zlen="`echo \"${zadddh}\" | tr -d ' ' | wc -c | tr -d ' '`"

if [ "${zlen}" == "0" -o "${thsx}" == "1" ]; then

factor="1"

elif [ "${zlen}" == "1" -o "${thsx}" == "1" ]; then

factor="1"

elif [ "${zlen}" == "2" -o "${thsx}" == "60" ]; then

factor="10"

xadddh="`echo ${xadddh}${zadddh:0:1}`"

elif [ "${zlen}" == "3" ]; then

factor="100"

xadddh="`echo ${xadddh}${zadddh:0:2}`"

else

factor="100"

xadddh="`echo ${xadddh}${zadddh:0:2}`"

fi

fi

if [ ! -z "${adddh}" ]; then

addh="`echo \"0${adddh}\" | cut -f 1 -d '.'`"

if [ "$thsx" == "1" ]; then

addh="`expr $xadddh \\/ 3600`"

elif [ "$thsx" == "60" ]; then

addh="`expr $xadddh \\/ 60`"

fi

adds="`expr ${xadddh} \\* ${thsx} \\/ ${factor}`"

adds="`echo \"${adds}\" | cut -f 1 -d '.'`"

adds="`expr ${adds} - ${addh} \\* 3600`"

addm="`expr ${adds} \\/ 60`"

addm="`echo \"${addm}\" | cut -f 1 -d '.'`"

adds="`expr ${adds} - ${addm} \\* 60`"

pfrom="${1}"

pto="${1}"

fi

fi


elif [ "`echo ${1} | tr -d '+'`" != "`echo ${1}`" ]; then

twoy="`echo ${1} | sed '/\:00\:00\:00\:00/s///g'`:00:00:00:00"

if [ "`echo ${1} | sed '/\:\+/s///g'`" == "`echo ${1}`" ]; then

preadddh="+"

adddh="`echo \"${one}:00\" | cut -f 2 -d '+' | cut -f 1 -d ':'`"

xadddh="`echo \"${adddh}\" | cut -f 1 -d '.'`"

if [ "`expr ${xadddh} \>= 24`" == "1" ]; then

if [ "`expr ${xadddh} \< 60`" == "1" ]; then

thsx="60"

factor="1"

else

thsx="1"

factor="1"

fi

fi

if [ "${adddh}" != "${xadddh}" ]; then

if [ "`expr ${xadddh} \>= 24`" == "1" ]; then

if [ "`expr ${xadddh} \< 60`" == "1" ]; then

thsx="60"

else

thsx="1"

fi

fi

zadddh="`echo \"${adddh}.\" | cut -f 2 -d '.'`"

zlen="`echo \"${zadddh}\" | tr -d ' ' | wc -c | tr -d ' '`"

if [ "${zlen}" == "0" -o "${thsx}" == "1" ]; then

factor="1"

elif [ "${zlen}" == "1" -o "${thsx}" == "1" ]; then

factor="1"

elif [ "${zlen}" == "2" -o "${thsx}" == "60" ]; then

factor="10"

xadddh="`echo ${xadddh}${zadddh:0:1}`"

elif [ "${zlen}" == "3" ]; then

factor="100"

xadddh="`echo ${xadddh}${zadddh:0:2}`"

else

factor="100"

xadddh="`echo ${xadddh}${zadddh:0:2}`"

fi

fi

if [ ! -z "${adddh}" ]; then

addh="`echo \"0${adddh}\" | cut -f 1 -d '.'`"

if [ "$thsx" == "1" ]; then

addh="`expr $xadddh \\/ 3600`"

elif [ "$thsx" == "60" ]; then

addh="`expr $xadddh \\/ 60`"

fi

adds="`expr ${xadddh} \\* ${thsx} \\/ ${factor}`"

adds="`echo \"${adds}\" | cut -f 1 -d '.'`"

adds="`expr ${adds} - ${addh} \\* 3600`"

addm="`expr ${adds} \\/ 60`"

addm="`echo \"${addm}\" | cut -f 1 -d '.'`"

adds="`expr ${adds} - ${addm} \\* 60`"

pfrom="${1}"

pto="${1}"

fi

fi


fi

if [ ! -z "${preTZ}" -o ! -z "${adddh}" ]; then

bnowis="`date '+%H:%M'`"

if [ -z "${preTZ}" ]; then

ccnowis="`date '+%H:%M:%S'`"

cnowis="`date '+%H:%M'`"

else


ccnowis="`TZ=${preTZ} date '+%H:%M:%S'`"

cnowis="`TZ=${preTZ} date '+%H:%M'`"

fi

if [ "`echo ${nowis} | sed '/${cnowis}/s///g'`" == "`echo ${nowis}`" -o ! -z "${adddh}" ]; then

chis="`echo ${cnowis}:00 | cut -f 1 -d ':'`"

cmis="`echo ${cnowis}:00 | cut -f 2 -d ':'`"

csis="`echo ${ccnowis}:00 | cut -f 3 -d ':'`"




if [ ! -z "${adddh}" ]; then

news="`expr ${sfrom} + ${adds}`"

if [ "`expr ${news} \< 60`" == "1" ]; then

newm="`expr ${mfrom} + ${addm}`"

else

news="`expr ${news} - 60`"

newm="`expr ${mfrom} + ${addm} + 1`"

fi

if [ "`expr ${newm} \< 60`" == "1" ]; then

newh="`expr ${hfrom} + ${addh}`"

else

newm="`expr ${newm} - 60`"

newh="`expr ${hfrom} + ${addh} + 1`"

fi

if [ "`expr ${newh} \>= 24`" == "1" ]; then

newh="`expr ${newh} - 24`"

fi

pto="${newh}${preadddh}${adddh}:${newm}:${news}"

fi





#one="`expr ${chis} - ${his} + ${hfrom} + ${addh}`:`expr ${cmis} - ${mis} + ${mfrom} + ${addm}`:`expr ${csis} - ${sis} + ${sfrom} + ${adds}`"

one="`expr ${chis} - ${his} + ${hfrom}`:`expr ${cmis} - ${mis} + ${mfrom}`:`expr ${csis} - ${sis} + ${sfrom}`"




hfrom="`echo ${one}:00 | cut -f 1 -d ':' | cut -f 1 -d '-' | cut -f 1 -d '+' | tr -d '-'`"

mfrom="`echo ${one}:00 | cut -f 2 -d ':' | cut -f 1 -d '-' | cut -f 1 -d '+' | tr -d '-'`"

sfrom="`echo ${one}:00 | cut -f 3 -d ':' | cut -f 1 -d '-' | cut -f 1 -d '+' | tr -d '-'`"




his="`echo ${cnowis}:00 | cut -f 1 -d ':'`"

mis="`echo ${cnowis}:00 | cut -f 2 -d ':'`"

sis="`echo ${ccnowis}:00 | cut -f 3 -d ':'`"

nowis="${ccnowis}"

fi

else

bnowis="`date '+%H:%M'`"

cnowis="`date '+%H:%M'`"

fi

if [ "`expr ${hfrom} - ${his} \<= 0`" == "1" ]; then

#echo "Time found ${one} versus ${nowis} ... `expr ${hfrom} - ${his}`"

if [ "`expr ${hfrom} - ${his} \< 0`" == "1" ]; then

hfrom="`expr ${hfrom} + 24`"

else




if [ "`expr ${mfrom} - ${mis} \<= 0`" == "1" ]; then

if [ "`expr ${mfrom} - ${mis} \< 0`" == "1" ]; then

hfrom="`expr ${hfrom} + 24`"

else




if [ "`expr ${sfrom} - ${sis} \<= 0`" == "1" ]; then

if [ "`expr ${sfrom} - ${sis} \< 0`" == "1" ]; then

hfrom="`expr ${hfrom} + 24`"

fi

fi




fi

fi




fi

fi

curpid="$$"

precmdline="`ps -p ${curpid} -o args | sed '/^ARGS/s///g' | sed '/^ksh /s///g' | tr -d \"\n\"`"

if [ -z "${twoy}" ]; then

cmdline=`echo ${precmdline} | awk -v FS="${1}" '{ print $1 $2; }'`

else

rtd="`echo ${1} | sed '/\:00\:00\:00\:00/s///g'`"

cmdline="`echo ${precmdline} | awk -v FS="${rtd}" '{ print $1 FS \":00:00:00:00\" $2; }'`"

cmdline="`echo ${cmdline} | sed \"/${1}:00:00:00:00${1}:00:00:00:00/s//${1}:00:00:00:00/g\" | sed \"/${1}${1}/s//${1}/g\"`"

fi

cmdline="`echo ${cmdline} | sed '/\:00\:00\:00\:00\:00\:00\:00\:00/s//\:00\:00\:00\:00/g'`"

if [ ! -z "${pfrom}" -a ! -z "${pto}" ]; then

if [ ! -z "${pto}" -a "`echo \"${cmdline}\" | sed '/\:00\:00\:00\:00\:00\:00\:00\:00/s///g'`" == "`echo \"${cmdline}\"`" ]; then

cmdline="`echo ${cmdline} | sed \"/${pfrom}/s//${pto}:00:00:00:00/g\"`"

else

cmdline="`echo ${cmdline} | sed \"/${pfrom}/s//${pto}/g\"`"

fi

fi


secstowait="`expr ${hfrom} - ${his}`"

secstowait="`expr ${secstowait} \\* 3600`"

stowait="`expr ${mfrom} - ${mis}`"

stowait="`expr ${stowait} \\* 60`"

secstowait="`expr ${stowait} + ${secstowait}`"

stowait="`expr ${sfrom} - ${sis}`"

secstowait="`expr ${stowait} + ${secstowait}`"

if [ ! -z "${twoy}" ]; then

secstowait="`expr 1 + ${secstowait}`"

fi

cmdline="`echo ${cmdline} | sed '/\:00\:00\:00\:00\:00\:00\:00\:00/s//\:00\:00\:00\:00/g'`"

#echo "TIME found ${1} versus ${nowis} ... `expr ${hfrom} - ${his}` ... ${secstowait} ... ${cmdline} ... ${nowis} ... ${cnowis} ... sleep ${secstowait}; `echo ${cmdline}` nohup ksh -c \"sleep ${secstowait} ; cd \\\"`pwd`\\\" ; `echo ${cmdline}` ;\" > /dev/null 2> /dev/null"

nohup ksh -c "sleep ${secstowait} ; cd \"`pwd`\" ; ksh `echo ${cmdline}` ;" > /dev/null 2>> /dev/null &

if [ "`echo ${1} | sed '/\:00\:00\:00\:00/s///g'`" == "`echo ${1}`" ]; then

exit

fi

else

ppid="${1}"

#if [ "`ps -ef | grep ' ${1} ' | grep -v 'grep'`" ]; then

# exit

#fi

fi

fi

fi


Previous relevant Linux sendmail nohup Scheduling Tutorial is shown below.

Linux sendmail nohup Scheduling Tutorial

Linux sendmail nohup Scheduling Tutorial

As far as Linux or unix operating systems (for web servers) go for โ€œscheduling processesโ€, it is โ€ฆ

  • great if you have access to crontab because it can be โ€ฆ
    1. scheduled to the minute
    2. the actions can be repeated (and scheduled) in a hugely different number of ways
    3. starts up again on a reboot of the (web) server (in a normal arrangement)
      1. but less formalized can be a simple (Korn (in our case)) shell scripting procedure that involves โ€ฆ
        1. nohup
        2. โ€œ&โ€ background processing
        3. recursion (perhaps)

โ€ฆ the latter representing an idea you have for either (eg. timed for 10:43) โ€ฆ

  • a one off scheduled procedure โ€ฆ eg. date_ps_ef.ksh 10:43 โ€ฆ for next 10:43 (local time if locally executed (as we tested here on MAMP, and mapped times via informing the script of the timezone of the destination web server as per โ€ฆ


    # Local time the Korn Shell will be hosted at

    preTZ="Australia/Perth"


    thispid="`echo $$`"

    postiftwoquit="`ps -ef | grep \" ${thispid} \" | grep -c ':00:00:00:00'`"

    iftwoquit="1"


    โ€ฆ or web server time) โ€ฆ or โ€ฆ
  • a daily scheduled procedure โ€ฆ eg. date_ps_ef.ksh 10:-43

โ€ฆ via โ€ฆ



if [ "`echo \"${1}\" | sed '/^0/s///g' | sed '/^1/s///g' | sed '/^2/s///g' | sed '/^3/s///g' | sed '/^4/s///g' | sed '/^5/s///g' | sed '/^6/s///g' | sed '/^7/s///g' | sed '/^8/s///g' | sed '/^9/s///g'`" != "`echo \"${1}\"" ]; then

if [ "`echo \"${1}\" | sed '/0$/s///g' | sed '/1$/s///g' | sed '/2$/s///g' | sed '/3$/s///g' | sed '/4$/s///g' | sed '/5$/s///g' | sed '/6$/s///g' | sed '/7$/s///g' | sed '/8$/s///g' | sed '/9$/s///g'`" != "`echo \"${1}\"" ]; then

if [ "`echo \"${1}\" | sed '/\:/s///g'`" != "`echo \"${1}\"" ]; then

twoy=""

secstowait="0"

nowis="`date '+%H:%M:%S'`"

one="${1}"

oney="${1}"

if [ "`echo ${1} | tr -d '-'`" != "`echo ${1}`" ]; then

twoy="`echo ${1} | sed '/\:00\:00\:00\:00/s///g'`:00:00:00:00"

fi

his="`echo ${nowis} | cut -f 1 -d ':'`"

hfrom="`echo ${one}:00 | cut -f 1 -d ':' | tr -d '-'`"

mis="`echo ${nowis} | cut -f 2 -d ':'`"

mfrom="`echo ${one}:00 | cut -f 2 -d ':' | tr -d '-'`"

sis="`echo ${nowis} | cut -f 3 -d ':'`"

sfrom="`echo ${one}:00 | cut -f 3 -d ':' | tr -d '-'`"

if [ ! -z "${preTZ}" ]; then

bnowis="`date '+%H:%M'`"

ccnowis="`TZ=${preTZ} date '+%H:%M:%S'`"

cnowis="`TZ=${preTZ} date '+%H:%M'`"

if [ "`echo ${nowis} | sed '/${cnowis}/s///g'`" == "`echo ${nowis}`" ]; then

chis="`echo ${cnowis}:00 | cut -f 1 -d ':'`"

cmis="`echo ${cnowis}:00 | cut -f 2 -d ':'`"

csis="`echo ${ccnowis}:00 | cut -f 3 -d ':'`"




one="`expr ${chis} - ${his} + ${hfrom}`:`expr ${cmis} - ${mis} + ${mfrom}`:`expr ${csis} - ${sis} + ${sfrom}`"




hfrom="`echo ${one}:00 | cut -f 1 -d ':' | tr -d '-'`"

mfrom="`echo ${one}:00 | cut -f 2 -d ':' | tr -d '-'`"

sfrom="`echo ${one}:00 | cut -f 3 -d ':' | tr -d '-'`"




his="`echo ${cnowis}:00 | cut -f 1 -d ':'`"

mis="`echo ${cnowis}:00 | cut -f 2 -d ':'`"

sis="`echo ${ccnowis}:00 | cut -f 3 -d ':'`"

nowis="${ccnowis}"

fi

else

bnowis="`date '+%H:%M'`"

cnowis="`date '+%H:%M'`"

fi

if [ "`expr ${hfrom} - ${his} \<= 0`" == "1" ]; then

#echo "Time found ${one} versus ${nowis} ... `expr ${hfrom} - ${his}`"

if [ "`expr ${hfrom} - ${his} \< 0`" == "1" ]; then

hfrom="`expr ${hfrom} + 24`"

else




if [ "`expr ${mfrom} - ${mis} \<= 0`" == "1" ]; then

if [ "`expr ${mfrom} - ${mis} \< 0`" == "1" ]; then

hfrom="`expr ${hfrom} + 24`"

else




if [ "`expr ${sfrom} - ${sis} \<= 0`" == "1" ]; then

if [ "`expr ${sfrom} - ${sis} \< 0`" == "1" ]; then

hfrom="`expr ${hfrom} + 24`"

fi

fi




fi

fi




fi

fi

curpid="$$"

precmdline="`ps -p ${curpid} -o args | sed '/^ARGS/s///g' | sed '/^ksh /s///g' | tr -d \"\n\"`"

if [ -z "${twoy}" ]; then

cmdline=`echo ${precmdline} | awk -v FS="${1}" '{ print $1 $2; }'`

else

rtd="`echo ${1} | sed '/\:00\:00\:00\:00/s///g'`"

cmdline="`echo ${precmdline} | awk -v FS="${rtd}" '{ print $1 FS \":00:00:00:00\" $2; }'`"

fi

cmdline="`echo ${cmdline} | sed '/\:00\:00\:00\:00\:00\:00\:00\:00/s//\:00\:00\:00\:00/g'`"

secstowait="`expr ${hfrom} - ${his}`"

secstowait="`expr ${secstowait} \\* 3600`"

stowait="`expr ${mfrom} - ${mis}`"

stowait="`expr ${stowait} \\* 60`"

secstowait="`expr ${stowait} + ${secstowait}`"

stowait="`expr ${sfrom} - ${sis}`"

secstowait="`expr ${stowait} + ${secstowait}`"

if [ ! -z "${twoy}" ]; then

secstowait="`expr 1 + ${secstowait}`"

fi

#echo "TIME found ${1} versus ${nowis} ... `expr ${hfrom} - ${his}` ... ${secstowait} ... ${cmdline} ... ${nowis} ... ${cnowis} ... sleep ${secstowait}; `echo ${cmdline}` nohup ksh -c \"sleep ${secstowait} ; cd \\\"`pwd`\\\" ; `echo ${cmdline}` ;\" > /dev/null 2> /dev/null"

nohup ksh -c "sleep ${secstowait} ; cd \"`pwd`\" ; ksh `echo ${cmdline}` ;" > /dev/null 2>> /dev/null &

if [ "`echo ${1} | sed '/\:00\:00\:00\:00/s///g'`" == "`echo ${1}`" ]; then

exit

fi

else

ppid="${1}"

#if [ "`ps -ef | grep ' ${1} ' | grep -v 'grep'`" ]; then

# exit

#fi

fi

fi

fi

โ€ฆ adding that โ€œscheduling layerโ€ capability on top of the progress of Linux sendmail Remote Attachment Tutorial below.

In effect, thechanged date_ps_efโšซksh Korn Shell script, on the user defining โ€ฆ

  • an argument of the โ€œhh:mmโ€ form (or โ€œhh:-mmโ€ daily repeated form) will โ€ฆ
  • calculate the number of seconds (eg. ${secstowait} below) until โ€œhh:mmโ€ next happens โ€ฆ


  • nohup ksh -c "sleep ${secstowait} ; cd \"`pwd`\" ; ksh `echo ${cmdline}` ;" > /dev/null 2>> /dev/null &


    โ€ฆ that โ€ฆ


    if [ ! -z "${twoy}" ]; then

    secstowait="`expr 1 + ${secstowait}`"

    fi


    โ€ฆ conditionally causing the one second overshoot on date_ps_ef.ksh 10:-43 daily scheduling that will ensure a huge (around about 86400 (seconds in a day) ${secstowait}) โ€œsleepโ€ before the next call โ€ฆ
  • and in the case of one of those date_ps_ef.ksh 10:-43 daily scheduling calls parents will exit when a child starts running for real

โ€ฆ being a methodology getting towards the crontab ideal (but will not resurrect itself on a system reboot, unless you script for it), and you can get the gist of by examining todayโ€™s tutorial picture of a Korn Shell via nohup scheduling execution.


Previous relevant Linux sendmail Remote Attachment Tutorial is shown below.

Linux sendmail Remote Attachment Tutorial

Linux sendmail Remote Attachment Tutorial

Programmingโ€™s full of shells of functionality. And the way you may approach adding functionality to desktop (command line) applications such as the Korn Shell Script one featuring in yesterdayโ€™s Linux sendmail Mime Type Attachment Tutorial could go a bit like โ€ฆ

  • weโ€™ve written logic for the attachment of local media files attached to emails and sent off via Linux sendmail โ€ฆ
    so why not today write functionality to cater for remote media file/URLs (where allowed, that is โ€ฆ via โ€ฆ


    filen="`echo \"${1}\" | sed '/^https:/s//http:/g' | sed '/^HTTPS:/s//http:/g' | sed '/^Https:/s//http:/g'"

    cfilen="`curl ${filen}`"

    basechars="`echo -n \"${cfilen}\" | base64 | tr -d \"\\n\"`"


    )
  • in the โ€œbodyโ€ section part of the email above the attachment weโ€™ve written functionality for Content-Type: text/plain โ€ฆ

    so why not today write functionality to cater for Content-Type: text/html here (if allowed โ€ฆ spoiler alert โ€ฆ yes, it is โ€ฆ we tried some, and it worked, and we do this when a user defines their own tailored email subject, as talked about below)
  • weโ€™ve written functionality for a single file execution via a single relevant command line argument โ€ฆ

    so why not today write functionality to cater for multiple file executions via a wildcard file specification โ€ฆ for example โ€ฆ


    ksh date_ps_ef.ksh Mac/SQLite*.jpg > /dev/null 2> /dev/null &


    โ€ฆ or to use a larger (ie. via HTML h1 element) on the body section text on top of the attachment โ€ฆ


    ksh date_ps_ef.ksh "A List of Images ... [file]" Mac/SQLite*.jpg > /dev/null 2> /dev/null &


    โ€ฆ or space delimited list of files command line argument (if allowed โ€ฆ spoiler alert โ€ฆ yes, we can do that)
  • weโ€™ve written functionality for email subjects to a pattern with prefix First or Changed and suffix at [datetimestamp] โ€ฆ

    so why not today write functionality to cater for user defined subject content here (if user uses a double quote delimited argument with one space or more, and substitutional for the token strings [date] or [file])

Hopefully that sounds interesting, and promising to you too, in which case you might want to examine thechanged date_ps_efโšซksh Korn Shell script by downloading it and implementing it yourself, perhaps.


Previous relevant Linux sendmail Mime Type Attachment Tutorial is shown below.

Linux sendmail Mime Type Attachment Tutorial

Linux sendmail Mime Type Attachment Tutorial

Yesterdayโ€™s Linux sendmail Content Type Tutorial had us โ€ฆ

  • following up (the Primer tutorial) sending of Content-Type: text/plain emails via sendmail on Linux โ€ฆ by โ€ฆ
  • allowing for Inline HTML Email (report) sending of Content-Type: text/html emails via sendmail on Linux โ€ฆ but โ€ฆ
  • there are more Mime Types than just these two, but we can make email attachments out of other Mime Type data forms (often regarding โ€œimageโ€, โ€œvideoโ€ and โ€œaudioโ€ media Mime Types)

โ€ฆ and, of course, this opens up this command line Korn Shell scripting to so much more about what the Internet is about โ€œsharing media filesโ€ (often created on mobile devices by the users themselves). This ability makes users โ€œuploadersโ€ of content, as so many more of us are becoming every day.

We have a favoured approach to interpretive software (though the same approach works well with non-interpretive coding too) language (the types that do not need compiling) development where a project โ€ฆ

  • starts as a guinea pig exercise to solve a specific set of criteria (remember โ€œChecking on /world.php ps -ef Reportingโ€?) โ€ฆ and we โ€ฆ
  • genericize by โ€œparameterizingโ€ the โ€œhardcoded wordsโ€ in the code โ€ฆ for example, the color coded โ€œhardcodingsโ€ of yesterdayโ€™s Linux sendmail Content Type Tutorial โ€œFirst Reportโ€ email creation โ€ฆ


    echo -e "Content-Type: text/html\nFrom: rmetcalfe@rjmprogramming.com.au\nto: rmetcalfe15@gmail.com\ncc: rmetcalfe@rjmprogramming.com.au\nSubject: First Date ps-ef world.php Report at `date`\n\n<html><head><style> tr:nth-child(even) {background-color: #CCC !important;} tr:nth-child(odd) {background-color: #FFF !important;} </style></head><body><h1>First Date ps-ef world.php Report at `date`</h1><table style='border:5px dotted olive;width:70%;height:100%;margin: 5 5 5 5;font-family:Courier-New;'><tr><th>UID</th><th>PID</th><th>PPID</th><th>C</th><th>STIME</th><th>TTY</th><th>TIME</th><th>CMD</th></tr>`cat date_ps_ef_first.txt | sed '/^/s//<tr><td>/g' | sed 's/ \{1,\}/<\/td><td>/g' | awk '{ t=0; while (getline \$0) { if (t == 0) { print \"<tr style=background-color:#e7e7e7 !important;\" substr(\$0,3); } else { print \$0; } t=1-t; } }' | sed '/$/s//<\/td><\/tr>/g'`</table></body></html>" | sendmail -t -f rmetcalfe15@gmail.com


    โ€ฆ becomes โ€ฆ


    echo -e "${mimetype}From: ${emailfrom}\nTo: ${emailto}\nCC: ${emailcc}\n${emailbcc}Subject: First ${subjmiddle} at `date`\n${attachrest}" | sendmail -t -f ${emailto}


    โ€ฆ via โ€ฆ
  • command line argument logic (ie. parameterization) helping derive those Korn Shell Script โ€œ$โ€ variable value determination โ€ฆ
    #!/bin/ksh


    mimetype="Content-Type: text/html\\n"

    emailfrom="rmetcalfe@rjmprogramming.com.au"

    emailto="rmetcalfe15@gmail.com"

    emailcc="rmetcalfe@rjmprogramming.com.au"

    emailbcc=""

    subjmiddle="Date ps-ef world.php Report"

    lastcur=""

    filen=""



    attachrest="\\n<html><head><style> tr:nth-child(even) {background-color: #CCC !important;} tr:nth-child(odd) {background-color: #FFF !important;} </style></head><body><h1>First First ${subjmiddle} at `date`</h1><table style='border:5px dotted olive;width:70%;height:100%;margin: 5 5 5 5;font-family:Courier-New;'><tr><th>UID</th><th>PID</th><th>PPID</th><th>C</th><th>STIME</th><th>TTY</th><th>TIME</th><th>CMD</th></tr>`cat date_ps_ef_first.txt | sed '/^/s//<tr><td>/g' | sed 's/ \{1,\}/<\/td><td>/g' | awk '{ t=0; while (getline \$0) { if (t == 0) { print \"<tr style=background-color:#e7e7e7 !important;\" substr(\$0,3); } else { print \$0; } t=1-t; } }' | sed '/$/s//<\/td><\/tr>/g'`</table></body></html>"

    if [ ! -z "$1" ]; then

    while [ ! -z "$1" ]; do

    if [ "`echo \"${1}\" | tr -d '@'`" != "`echo \"${1}\"" ]; then

    if [ "`echo \"${emailto}\" | tr -d ' '`" == "`echo \"${emailto}\"" ]; then

    emailto="${1} "

    elif [ "`echo \"${emailcc}\" | tr -d ' '`" == "`echo \"${emailcc}\"" ]; then

    emailcc="${1} "

    else

    emailbcc="BCC: ${1}\\n"

    fi

    elif [ -f "${1}" ]; then

    if [ ! -z "${mimetype}" ]; then

    filen="${1}"

    mimetype=""

    shortf=""

    basechars="`base64 ${filen} | tr -d \"\\n\"`"

    i=0

    flast="`echo ${1} | tr '/' ' ' | sed '/\\\\/s// /g'`"

    for filebits in ${flast}; do

    shortf=$filebits

    ((i=i+1))

    done

    subjmiddle="$shortf"

    attachrest="Mime-Version: 1.0\\nContent-Type: multipart/mixed; boundary=\"19032019ABCDE\"\\n\\n--19032019ABCDE\\nContent-Type: text/plain; charset=\"iso-8859-1\"\\nContent-Transfer-Encoding: 8bit\\n\\nFirst ${subjmiddle} at `date`\\n\\n--19032019ABCDE\\nContent-Type: application/octet-stream; name=\"${shortf}\";\\nContent-Transfer-Encoding: base64\\nContent-Disposition: attachment;filename=\"${shortf}\"\\n\\n${basechars}\\n--19032019ABCDE--"

    fi

    fi

    shift

    done

    emailfrom="`echo ${emailfrom} | tr -d ' '`"

    emailto="`echo ${emailto} | tr -d ' '`"

    emailcc="`echo ${emailcc} | tr -d ' '`"

    fi


    โ€ฆ the main extra argument can point at a rjmprogramming.com.au domain web server file

โ€ฆ leaving โ€ฆ



ksh date_ps_ef.ksh > /dev/null 2> /dev/null &

โ€ฆ unchanged as a rjmprogramming.com.au domain โ€œ/world.phpโ€ ps -ef Report monitor โ€ฆ and the same code called โ€ฆ



ksh date_ps_ef.ksh ./please_sign.mp4 > /dev/null 2> /dev/null &

โ€ฆ serving to email a โ€œFirst Reportโ€ email attachment that is that โ€œplease_sign.mp4โ€ video (media) file (playable for the emailee at that email), and if anything changes about that file a โ€œChanged Reportโ€ email attachment that is that โ€œplease_sign.mp4โ€ video (media) file (playable for the emailee at that email) will be sent to the same emailee recipients.

And so thechanged date_ps_efโšซksh Korn Shell script has a far bigger โ€œpotential footprintโ€ as of this incarnation.


Previous relevant Linux sendmail Content Type Tutorial is shown below.

Linux sendmail Content Type Tutorial

Linux sendmail Content Type Tutorial

Yesterdayโ€™s Linux sendmail Primer Tutorialโ€˜s command line emailing really felt โ€œcommand lineโ€. We do not consider this an insult per se, and we tend towards โ€œthe badge of honour thinkingโ€ here. But given reports are more trusted when impactive (we dare to figure) โ€ฆ so โ€ฆ letโ€™s add a bit of โ€œsparkโ€ โ€ฆ luckily the CSS restrictions of HTML Inline Email โ€œcurbs the enthusiasmโ€ anyway โ€ฆ to the email reporting started yesterday.

The key to what we change is โ€ฆ

  • in the sendmail headers we change Content-Type: text/plain to Content-Type: text/html and that step alone opens the door to โ€œa little bit ofโ€ style in the body section of the email โ€ฆ but โ€ฆ
  • given a lot of CSS3 is not supported in HTML Inline Email styling we had to forgo โ€ฆ


    style="background:linear-gradient(top,pink,yellow);"


    โ€ฆ for a linear-gradient background โ€ฆ and โ€ฆ


    <head><style> tr:nth-child(even) {background-color: #CCC !important;} tr:nth-child(odd) {background-color: #FFF !important;} </style</head>


    โ€ฆ for alternate table row colouring (as per the heads up at this link, thanks) โ€ฆ for good โ€˜ol โ€ฆ

    1. sed (thanks to this useful link for advice)
    2. awk (and its excellent getline method, and thanks to this useful link for advice)

    โ€ฆ scripting interventions instead โ€ฆ so that for that โ€œFirst Reportโ€ we output the report (largely) in an HTML table element as per โ€ฆ


    echo -e "Content-Type: text/html\nFrom: rmetcalfe@rjmprogramming.com.au\nto: rmetcalfe15@gmail.com\ncc: rmetcalfe@rjmprogramming.com.au\nSubject: First Date ps-ef world.php Report at `date`\n\n<html><head><style> tr:nth-child(even) {background-color: #CCC !important;} tr:nth-child(odd) {background-color: #FFF !important;} </style></head><body><h1>First Date ps-ef world.php Report at `date`</h1><table style='border:5px dotted olive;width:70%;height:100%;margin: 5 5 5 5;font-family:Courier-New;'><tr><th>UID</th><th>PID</th><th>PPID</th><th>C</th><th>STIME</th><th>TTY</th><th>TIME</th><th>CMD</th></tr>`cat date_ps_ef_first.txt | sed '/^/s//<tr><td>/g' | sed 's/ \{1,\}/<\/td><td>/g' | awk '{ t=0; while (getline \$0) { if (t == 0) { print \"<tr style=background-color:#e7e7e7 !important;\" substr(\$0,3); } else { print \$0; } t=1-t; } }' | sed '/$/s//<\/td><\/tr>/g'`</table></body></html>" | sendmail -t -f rmetcalfe15@gmail.com


    โ€ฆ and for the โ€œChanged Reportโ€ we output the report (largely) in an HTML textarea element as per โ€ฆ


    echo -e "Content-Type: text/html\nFrom: rmetcalfe@rjmprogramming.com.au\nto: rmetcalfe15@gmail.com\ncc: rmetcalfe@rjmprogramming.com.au\nSubject: Changed Date ps-ef world.php Report at `date`\n\n<html><body><h1>Changed Date ps-ef world.php Report at `date`</h1><textarea rows=${cur} style='background-color:#e7e7e7;border:5px dotted olive;width:70%;height:100%;margin: 5 5 5 5;font-family:Courier-New;'>`diff date_ps_ef_first.txt date_ps_ef_next.txt`</textarea></body></html>" | sendmail -t -f rmetcalfe15@gmail.com

To get to the HTML textarea element stage wemade these changes, and then to progress onto a tabular โ€œFirst Reportโ€ weapplied these changes to the final date_ps_efโšซksh Korn Shell script that finished up on the rjmprogramming.com.au web server, again, started via โ€ฆ



ksh date_ps_ef.ksh > /dev/null 2> /dev/null &

โ€ฆ to โ€œdo its thaingโ€ in the background, quietly, like.


Previous relevant Linux sendmail Primer Tutorial is shown below.

Linux sendmail Primer Tutorial

Linux sendmail Primer Tutorial

The Linux mailx Primer Tutorial outlined some very useful Linux (and Unix and perhaps macOS (or Mac OS X)) command line tools to email useful information to emailees.

Today, we want to outline a sendmail alternative approach for reporting purposes, perhaps, again, from the command line, and weโ€™d like to thank this link for great advice, here.

Along the way, today, towards the creation of a Korn Shell Script solution to a reporting issue where we wanted to monitor a Linux systemโ€™s โ€œps -efโ€ mentions of โ€œ/world.phpโ€ (for our rjmprogramming.com.au CentOS Linux web server operating system), and email relevant report information as a result of that monitoring environment changing, we wanted to emphasise โ€ฆ

  • usefulness of Linux echoโ€˜s -e switch โ€ฆ

    -e enable interpretation of backslash escapes

    โ€ฆ to help out the construction of sendmail headers that require line feed characters to work

  • usefulness of Linux/Unix backtick to include varieties of data into the subject and body sections of the email
  • usefulness of sendmail headers featuring heavily in the Korn Shell Email (from command line) commands as per โ€ฆ


    echo -e "Content-Type: text/plain\nFrom: rmetcalfe@rjmprogramming.com.au\nto: rmetcalfe15@gmail.com\ncc: rmetcalfe@rjmprogramming.com.au\nSubject: First Date ps-ef world.php Report at `date`\n\n`cat date_ps_ef_first.txt`" | sendmail -t -f rmetcalfe15@gmail.com

    echo -e "Content-Type: text/plain\nFrom: rmetcalfe@rjmprogramming.com.au\nto: rmetcalfe15@gmail.com\ncc: rmetcalfe@rjmprogramming.com.au\nSubject: Changed Date ps-ef world.php Report at `date`\n\n`diff date_ps_ef_first.txt date_ps_ef_next.txt`" | sendmail -t -f rmetcalfe15@gmail.com

  • usefulness of & background processing as per the โ€ฆ


    ksh date_ps_ef.ksh > /dev/null 2> /dev/null &


    โ€ฆ we ended up setting off our date_ps_efโšซksh Korn Shell Script reporter โ€ฆ


    #!/bin/ksh

    # date_ps_ef.ksh

    # Report on world.php

    lastcur=""

    while [ 0 -lt 1 ]; do

    cur="`ps -ef | grep '/world.php' | grep -v 'grep ' | wc -l`"

    echo "`date` $cur"

    if [ "$lastcur" != "$cur" ]; then

    if [ -z "$lastcur" ]; then

    echo "`ps -ef | grep '/world.php' | grep -v 'grep '`" > date_ps_ef_first.txt

    echo -e "Content-Type: text/plain\nFrom: rmetcalfe@rjmprogramming.com.au\nto: rmetcalfe15@gmail.com\ncc: rmetcalfe@rjmprogramming.com.au\nSubject: First Date ps-ef world.php Report at `date`\n\n`cat date_ps_ef_first.txt`" | sendmail -t -f rmetcalfe15@gmail.com

    else

    echo "`ps -ef | grep '/world.php' | grep -v 'grep '`" > date_ps_ef_next.txt

    echo -e "Content-Type: text/plain\nFrom: rmetcalfe@rjmprogramming.com.au\nto: rmetcalfe15@gmail.com\ncc: rmetcalfe@rjmprogramming.com.au\nSubject: Changed Date ps-ef world.php Report at `date`\n\n`diff date_ps_ef_first.txt date_ps_ef_next.txt`" | sendmail -t -f rmetcalfe15@gmail.com

    cat date_ps_ef_next.txt > date_ps_ef_first.txt

    fi

    lastcur="$cur"

    fi

    # ps -ef | grep '/world.php' | grep -v 'grep '

    sleep 30

    done

    exit

Take a look at some of all this in action with todayโ€™s PDF presentation.


Previous relevant Linux mailx Primer Tutorial is shown below.

Linux mailx Primer Tutorial

Linux mailx Primer Tutorial

Think Linux and you may not associate it with email, but Linux can be excellent for many email requirements, especially using mailx and uuencode. The use of uuencode allows you to give your email an attachment, and the mailx -s switch for the subject of the email can be used for both the purpose it was meant for, that is to establish an email subject, and with a stretch of imagination of usage, the body text, because of the quirk whereby anything after the first line of the subject will spill over into the body text of the email. So, am sure there would be limits to the length of this body text, but you can often be brief when there is a good attachment to provide your email recipient. Naturally, in the day and age of worry about computer viruses, your attachment will most likely be vetted by the receiving email client software for viability, so be aware of this. Other than all that, this method of sending emails is potentially very powerful. Notice that great way Linux and Unix can use `cat body.txt` type of syntax to embed one command within another โ€ฆ sometimes Linux is so simple, powerful, brilliant! You may have noticed how short all the commands in Linux and Unix tend to be, and that is because it was intended to be short and powerful, and this is brilliant.

Background reading for tutorial:

Here is a tutorial that introduces you to some email with attachment, subject and body text from the Linux commandโœ‚line.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

This entry was posted in eLearning, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *