Raspberry Pi automate certain tasks – script example

Now, if you have followed these :

fetchmail

ssmtp

Then you already have a working system for sending and receiving mail. Now, you can set the mda in the fetmailrc to a script which can do few things for you. The script below will get a page and mail it to you, if you have the subject as “get” and send “wake on LAN” to desired PC if you have subject as “wol”. Cool 🙂

Original idea from here.

Here is the script:

#!/bin/bash

expectedFrom=""
expectedFrom2=""
homePC="MAC Here"

mailHelp() {
	sendMail $1 "Help - Possible Commands" "Help"
}

sendMail() {
	echo "To: "$1 > $tmpMail
	echo "From: From address here" >> $tmpMail
	echo "Subject: "$2 >> $tmpMail
	echo "Content-Type: text/html" >> $tmpMail
	echo "" >> $tmpMail
	echo $3 >> $tmpMail
	cat $tempMail >> $tmpMail
	cat $tmpMail|/usr/sbin/ssmtp  $1
}
#here we start the actual processing

rightSender=0
sender=""
tmpFile=/tmp/mailtemp
tmpMail="/var/tmp/mailtxt.txt"
tempMail="/tmp/tosend.txt"
>$tempMail
>$tmpFile
>$tmpMail

#Write the mail to tmpFile
while read line
do
	echo $line >> $tmpFile
done

grep "From:" $tmpFile | grep $expectedFrom > /dev/null
if [ $? -eq 0 ]; then
	rightSender=1
	sender=$expectedFrom
fi

grep "From:" $tmpFile | grep $expectedFrom2 > /dev/null
if [ $? -eq 0 ]; then
	rightSender=1
	sender=$expectedFrom2
fi

if [ $rightSender -eq 1 ]; then
	task=`grep "Subject:" $tmpFile`
	task=${task:9}
	task=`echo $task | tr [:upper:] [:lower:]`

	echo $task | grep "help" > /dev/null
	if [ $? -eq 0 ]; then
		mailHelp $sender
		exit
	fi
fi
while read line
do
	if [[ $line =~ ^$|^Content*:*|^charset=*|^--=* ]]; then
		continue;
	fi
	echo "LINE :: $line"
	case $task in
		get)
			cmd="wget -o /dev/null -O - $line"
		;;
		wol)
			cmd="sudo etherwake $$line"
		;;
		*)
			cmd="$line"
		;;
	esac
	eval $cmd >> $tempMail
done < <( sed '1,/^$/ d' $tmpFile|sed '/^--$/,$ d')
sendMail $sender "Output result of command $task" "Happy Hacking"

rm $tmpFile
rm $tmpMail
rm $tempMail
Enhanced by Zemanta

Splitting strings with IFS


Today I want to discuss splitting strings into tokens or “words”. I previously discussed how to do this with the IFS variable and promised a more in depth discussion. Today, I will make the case on WHY to use IFS to split strings as opposed to using a subshell combined with awk or cut.

I wrote this script which reads the /etc/password file line-by-line and prints the username of any user which has a UID greater than 10 and has the shell of /sbin/nologin. Each test function performs this task 10 times to increase the length of the test:

 [root@sandbox ~]# cat ifs-test.sh #!/bin/bash split_words_cut() { # execute 10 times for i in {0..9} do while read line do # get uid id=$(echo $line | cut -d: -f3) if [[ $id -gt 10 ]] then # get shell shell=$(echo $line | echo $line | cut -d: -f7) if [[ \'/sbin/nologin\' == \"$shell\" ]] then # print username echo $line | cut -d: -f1 fi fi done < /etc/passwd done }

split_words_awk() { # execute 10 times for i in {0..9} do while read line do # get uid id=$(echo $line | awk -F: \'{print $3}\') if [[ $id -gt 10 ]] then # get shell shell=$(echo $line | awk -F: \'{print $NF}\') if [[ \'/sbin/nologin\' == \"$shell\" ]] then # print username echo $line | awk -F: \'{print $1}\' fi fi done < /etc/passwd done } split_words_native() { # execute 10 times for i in {0..9} do while read line do oldIFS=$IFS IFS=: set -- $line IFS=$oldIFS # at this point $1 is the username, $3 # is the uid, and $7 is the shell if [[ $3 -gt 10 ]] && [[ \'/sbin/nologin\' == \"$7\" ]] then echo $1 fi done < /etc/passwd done } echo -e \"---Cut---\" time split_words_cut >/dev/null echo -e \"n---Awk---\" time split_words_awk >/dev/null echo -e \"n---Native---\" time split_words_native >/dev/null

As you can see, using the shell itself is about two orders of magnitude faster than using the subshell awk/cut method:

 [root@sandbox ~]# ./ifs-test.sh
\"Reblog