Scripts

Scripts are small programs that are not compiled, but interpreted. They are often written in languages such as Perl, PHP, JavaScript. See here for a list of interpreted languages.

If not specified otherwise, a script is usually written in bash.

= Bash scripting = Main article: bash tips

Hello world
The minimal bash script that only outputs "hello world" looks like this: echo "hello world"
 * 1) !/bin/bash

Find out your distribution
Main article: find out your distribution

The following script tells you what distribution you have installed on your computer. found=0; if [ -e /etc/SuSE-release ]; then echo "You have a SUSE distro"; export found=1; fi if [ -e /etc/redhat-release ]; then echo "You have a Red Hat distro"; export found=1; fi if [ -e /etc/fedora-release ]; then echo "You have a Fedora distro"; export found=1; fi if [ -e /etc/debian-version ]; then echo "You have a Debian, Ubuntu, Kubuntu, Edubuntu or Flubuntu distro"; export found=1; fi if [ -e /etc/slackware-version ]; then echo "You have a SlackWare distro"; export found=1; fi if ! [ $found = 1 ]; then echo "I could not find out your distro"; fi It looks if the respective files exist (if [ -e /etc/SuSE-release ];) and prints the distribution they flag (using the command echo).
 * 1) !/bin/bash

Tonka Script
Changes your console to some other colours.


 * 1) !/bin/bash

function tonka {


 * 1)   Named "Tonka" because of the colour scheme

local WHITE="\[\033[1;37m\]" local LIGHT_BLUE="\[\033[1;34m\]" local YELLOW="\[\033[1;33m\]" local NO_COLOUR="\[\033[0m\]"

case $TERM in   xterm*|rxvt*)        TITLEBAR='\[\033]0;\u@\h:\w\007\]'        ;;    *) TITLEBAR="" ;; esac

PS1="$TITLEBAR\ $YELLOW-$LIGHT_BLUE-(\ $YELLOW\u$LIGHT_BLUE@$YELLOW\h\ $LIGHT_BLUE)-(\ $YELLOW\$PWD\ $LIGHT_BLUE)-$YELLOW-\ \n\ $YELLOW-$LIGHT_BLUE-(\ $YELLOW\$(date +%H%M)$LIGHT_BLUE:$YELLOW\$(date \"+%a,%d %b %y\")\ $LIGHT_BLUE:$WHITE\\$ $LIGHT_BLUE)-$YELLOW-$NO_COLOUR "

PS2="$LIGHT_BLUE-$YELLOW-$YELLOW-$NO_COLOUR "

}

Get your ip
/sbin/ifconfig $1 | grep inet | awk '{print $2}' | sed 's/^addr://g'
 * 1) !/bin/bash
 * 2) get ip

To get your Internet address if you are behind a NAT:

if [ "$1" = "-n" ] then ip=$(lynx -dump http://cfaj.freeshell.org/ipaddr.cgi) else if=$1  ## specify which interface, e.g. eth0, fxp0 system=$(uname) case $system in     FreeBSD) sep="inet " ;;      Linux) sep="addr:" ;; esac temp=$(ifconfig $if) temp=${temp#*"$sep"} ip=${temp%% *} fi
 * 1) The -n option retrieves the Internet IP address
 * 2) if you are behind a NAT

printf "%s\n" "$ip"
 * 1) CFAJ ###

Connect to a wireless access point (WPA compatible)
Tested in Ubuntu 8.10
 * 1) !/bin/bash

rm list.temp 2>/dev/null
 * 1) removing possible previous temp file


 * 1) scans for wifi connections & isolates wifi AP name
 * 2) thanks to jonjgc for the array solution
 * 3) thanks to ghostdog74 for the AWK suggestion

eval list=( $(sudo iwlist scan 2>/dev/null | awk -F":" '/ESSID/{print $2}') )

PS3="Choose wifi connection: "
 * 1) sets prompt

if [ -z "${list[0]}" ]; then clear echo "No available wifi connection" exit 1 fi
 * 1) tests for number of wifi connections, exits if none

select item in "${list[@]}"; do
 * 1) menu of wifi connections

wifi=$(echo $item)
 * 1) sets essid as value for WIFI variable and displays information about the AP

sudo iwlist scan 2>/dev/null | sed -n "/$wifi/, +9p" > list.temp echo "$(cat list.temp | sed 's/^[ \t]*//')"

channel=$(grep Channel: list.temp | sed 's/.*Channel://g')
 * 1) sets channel as value for CHANNEL variable

mode=$(grep Mode list.temp | sed 's/.*Mode://g') if [ "$mode" == "Master" ]; then mode="managed" else clear echo "Cannot connect" exit fi
 * 1) test for mode, if mode = master, sets MODE variable to managed

key=$(grep key: list.temp | sed 's/.*key://g') if [ $key == "on" ]; then echo -n "Enter encryption key: " read key fi
 * 1) tests for encryption key

IE=$(grep IE list.temp | sed 's/^ .*IE: \(...\).*/\1/')
 * 1) checks encryption algorithm

if [ "$IE" == "WPA" ]; then sudo cp /etc/network/interfaces /etc/network/interfaces.bakup sudo sed -i 's/iface wlan0 inet manual/iface wlan0 inet dhcp/' /etc/network/interfaces sudo sed -i -e "/dhcp/a\wpa-passphrase $key" \ -e "/dhcp/a\wpa-driver wext" \ -e "/dhcp/a\wpa-key-mgmt WPA-PSK" \ -e "/dhcp/a\wpa-proto WPA" \ -e "/dhcp/a\wpa-ssid \"$wifi\"" /etc/network/interfaces sudo /etc/init.d/networking restart sudo cp /etc/network/interfaces.bakup /etc/network/interfaces sudo rm /etc/network/interfaces.bakup exit
 * 1) writes to /etc/network/interfaces file for WPA encryption: essid, key, protocols, etc.

else

sudo iwconfig wlan0 essid \""$wifi"\" channel $channel mode $mode key $key echo "" echo "Connecting to: $wifi at channel: $channel, mode: $mode" echo ""
 * 1) sets the wireless configuration for non WPA: essid, channel, mode, key, etc

sudo dhclient exit fi done = Command Line Trash Can =
 * 1) connects to wifi connection

set -e TRASHLOC="$HOME/.local/share/Trash" function move_it { COUNTER=0 TARGET_BASE_NAME=`/usr/bin/basename "$*"` TARGET_FILE_NAME="${TRASHLOC}/files/${TARGET_BASE_NAME}" TARGET_INFO_NAME="${TRASHLOC}/info/${TARGET_BASE_NAME}" XTENSION="" while [ -e "${TARGET_FILE_NAME}${XTENSION}" ] do       let COUNTER+=1 XTENSION="_${COUNTER}" done OLDDIR=`pwd` cd "`dirname "$*"`" FULLPATH=`pwd` FULLPATH="${FULLPATH}/"`/usr/bin/basename "$*"` FULLPATH=`echo "${FULLPATH}" | sed 's/ /%20/g'` cd "${OLDDIR}" mv -n "$*" "${TARGET_FILE_NAME}${XTENSION}" echo "[Trash Info]" > "${TARGET_INFO_NAME}${XTENSION}.trashinfo" echo "Path="${FULLPATH} >> "${TARGET_INFO_NAME}${XTENSION}.trashinfo" echo DeletionDate=`date +%Y-%m-%dT%H:%M:%S` >> "${TARGET_INFO_NAME}${XTENSION}.trashinfo" } until [ -z "$1" ] # Until all parameters used up... do      if [ -d "$1" ]; then #its a directory move_it "$1" elif [ -f "$1" ];then #its a file move_it "$1" elif [ -h "$1" ];then #its just a link rm -f "$1" else echo "Error condition: '""$1""' not found." echo "Usage: $0 [Pathnames]" echo "Where [Pathname] is a list of space delimited existing files or directories the current user has permissions for." echo "So like this: $0 file1 '""file two with spaces""' directoryOne '""directory two with spaces in the name""' ..." exit 1 fi      shift done exit 0
 * 1) !/bin/bash
 * 2) Script by Jim Collings
 * 3) Written Sat Jan 30 14:01:38 EST 2010
 * 4) A simple trash script that handles spaces and integrates properly with GUI Trash system.
 * 5) Handles spaces properly according to every test I've devised so far.

= Managing Large Compressed Archives =

Assume that we have 3 directories, one of which has large amounts of data in it. We want to create a backup of this directory but we don't want any of the resulting archive files to exceed a certain size. The directories concerned are srcFilesDir, where the files are currently, arcFilesDir, which is where we want to put our archives, and extractedFilesDir which is where we will restore those files to.


 * tar :Tape ARchive, sticks files together end to end and will also compress them.


 * split :Will divide an input or file into chunks of an exact size.


 * cat :Does the opposite of split so it can be used to reassemble split files.

Example:

$ tar cvjpSf - srcFilesDir | split -b 1073741824 - arcFilesDir/largarchive.

The options used here are as follows:

For tar


 * c - Create an archive.
 * v - Produce lots of output so that we can see any errors.
 * j - Compress using bzip2 compression.
 * p - Preserve permissions and ownerships.
 * S - Handle "sparse" files effectively.
 * f - Specifies a file or output. In this case we use "-" so that we can also use a pipe (i.e. "|" ) to route the output through to the split command.

For split


 * b - Specify the maximum allowable size of the individual files created. In this case we are using one Gigabyte or 1073741824 bytes.

Each of the resulting files will begin with a prefix but will be appended with an alphabetic identifier that will be used by cat later on to reassemble the files in the correct order. If I specify a prefix of arcFilesDir/largarchive. then the data will be stored in the arcFilesDir subdirectory and file names will begin with 'largarchive.' but split will append an identifier after the ".".

$ cat arcFilesDir/* | tar xvjf - -C extractedFilesDir

This command follows many of the same rules. It is an example of how we can later reassemble the split files and restore the compressed data.

Options for tar in this case are:


 * x - Extract files from an archive.
 * v - Print lots of information about how things are going.
 * j - Used with x above, this means uncompress using bzip.
 * f - Used with x above, this specifies where we are getting our data from. In this case standard input.

Well, that's all I got on this right now. I will warn the reader that some compression programs, like zip / unzip, have very poor Large File support. Part of what spurred this HOWTO into being.

Here is how it all might go together:

[root@kaliklak root]# ls *FilesDir arcFilesDir: extractedFilesDir: srcFilesDir: First.iso Fourth.iso  Second.iso  Third.iso

So these are the files and directories we will be working with. This isn't the best way to handle CD images but as far as file size is concerned they'll work OK for this example.

[root@kaliklak root]# tar cvzpSf - srcFilesDir | split -b 1073741824 - arcFilesDir/largarchive. srcFilesDir/ srcFilesDir/Third.iso srcFilesDir/Second.iso srcFilesDir/Fourth.iso srcFilesDir/First.iso

So far, so good. Now lets see if the files are as they should be.

[root@kaliklak root]# ls -l arcFilesDir/ total 2687628 -rw-r--r-- 1 root root 1073741824 Jan 21 01:49 largarchive.aa -rw-r--r--  1 root root 1073741824 Jan 21 01:53 largarchive.ab -rw-r--r--  1 root root  601946112 Jan 21 01:55 largarchive.ac

Great! Now lets try our extraction.

[root@kaliklak root]# cat arcFilesDir/* | tar xzf - -C extractedFilesDir srcFilesDir/ srcFilesDir/Third.iso srcFilesDir/Second.iso srcFilesDir/Fourth.iso srcFilesDir/First.iso

Fantastic. So our files have extracted properly. Lets check them against the originals, just to be sure.

[root@kaliklak root]# ls -l srcFilesDir/* extractedFilesDir/* -rw-r--r-- 1 root root  728795136 Jan 20 18:53 srcFilesDir/First.iso -rw-r--r-- 1 root root  728795136 Jan 20 19:07 srcFilesDir/Fourth.iso -rw-r--r-- 1 root root  728563712 Jan 20 18:57 srcFilesDir/Second.iso -rw-r--r-- 1 root root  728563712 Jan 20 19:08 srcFilesDir/Third.iso

extractedFilesDir/srcFilesDir: total 2849208 -rw-r--r-- 1 root root 728795136 Jan 20 18:53 First.iso -rw-r--r-- 1 root root 728795136 Jan 20 19:07 Fourth.iso -rw-r--r-- 1 root root 728563712 Jan 20 18:57 Second.iso -rw-r--r-- 1 root root 728563712 Jan 20 19:08 Third.iso [root@kaliklak root]#

Notice that the files were written into the subdirectory extractedFilesDir/srcFilesDir. This is because tar stores the directory name unless told to do otherwise.

Everything's cool so we are good to go. :-) edit Comments on other compression protocols


 * zip - Will compress and concatenate files and store permissions and ownerships but does not support files larger than 2 Gigabytes. Also not self splitting.
 * tar - Does it all but can be complex to use. Not self splitting. Can use a variety of compression tools.
 * dar - A "fixed" version of tar. Self splitting is added. Not yet mainstream, though. I'm really itching to try it. :-) Currently however, the -P option seems broken. :-|

= Managing JVMs = So if your a Java developer, you probably don't use the etc/alternatives system. At least most that I know, don't. This next script manages a symbolic link such that you can easily switch out JVM's. Just set your ${JAVA_HOME} to ~/bin/java and the script will create a link here.

set -e JDKDIR="/opt/jdks/" #Must end in a / echo "Available jdks: " echo ctr=0 for I in `ls ${JDKDIR} | grep jdk`;do if -d ${JDKDIR}${I} ;then let "ctr +=1" echo ${ctr}. ${JDKDIR}${I} fi done ctr=0 echo echo Choose: read response for I in `ls ${JDKDIR} | grep jdk`;do if -d ${JDKDIR}${I} ;then let "ctr +=1" if ${ctr} == ${response} ;then rm -f "$HOME/bin/java" ln -s "${JDKDIR}${I}/bin" "$HOME/bin/java" fi fi done
 * 1) !/bin/bash

= Kerberos Startup Scripts = Tested on Centos 5.5 I built Kerberos from source and needed to run it at boot. Toward that end I wrote these two scripts and used webmin to enable the autostart. While I understand that chkconfig can and should be used in cases such as these, since I wrote these I figured I'd publish them in case someone else found them useful. Named /etc/init.d/kdcd Starts the /usr/local/sbin/krb5kdc proc . /etc/rc.d/init.d/functions test -f /usr/local/sbin/krb5kdc || echo "krb5kdc not found. Exiting script." exit 0 NAME=kdcd DESC="Start and stop Kerberos5 krb5kdc process" check_kdc_status { krb5kdc_pid=`ps -C krb5kdc -o pid=` if [ -z "$krb5kdc_pid" ]; then # krb5kdc is NOT running return 2 fi if [ -n "$krb5kdc_pid" ]; then # krb5kdc is running return 0 fi } case "$1" in 	start) 	echo "Starting krb5kdc... " 		check_kdc_status 		RETVAL=$? 	[ $RETVAL -eq 2 ] && /usr/local/sbin/krb5kdc && echo " krb5kdc started" ||  		echo "  krb5kdc already running!" 			;; 	stop) echo "Stopping krb5kdc: " check_kdc_status RETVAL=$? [ $RETVAL -eq 0 ] && kdc=`ps -C krb5kdc -o pid=` && `kill $kdc` && echo " krb5kdc stopped" || echo " krb5kdc was not running!" ;; 	restart|reload) 		check_kdc_status 		RETVAL=$? 	if [ $RETVAL -eq 2 ]; then 		echo "  krb5kdc was not running!" && echo "  starting krb5kdc: " &&  		/usr/local/sbin/krb5kdc && kdcpid=`ps x | grep -i krb5kdc | grep -v grep` && echo $kdcpid  	fi 	if [ $RETVAL -eq 0 ]; then 		echo "  stopping krb5kdc... " && kdc=`ps -C krb5kdc -o pid=` && `kill $kdc` &&  		echo "  starting krb5kdc... " && /usr/local/sbin/krb5kdc &&  		kdcpid=`ps x | grep -i krb5kdc | grep -v grep` && echo $kdcpid 	fi 	;; 	status) krb5kdc_pid=`ps -C krb5kdc -o pid=` [ -z $krb5kdc_pid ] && echo " krb5kdc NOT running" || echo "  krb5kdc running" ;; 	*) 		echo " Usage: kdcd {start|stop|restart|status}" 		exit 1 esac exit 0
 * 1) !/bin/sh
 * 2) written by John Sullivan 12/29/2010
 * 3) 	/usr/local/sbin/krb5kdc
 * 4) description: Start and stop Kerberos5 krb5kdc process
 * 5) processname: krb5kdc
 * 1) Source function library
 * 1) If the executable doesn't exist, then why bother?

Named /etc/init.d/kadm Starts the /usr/local/sbin/kadmind proc . /etc/rc.d/init.d/functions test -f /usr/local/sbin/kadmind || echo "kadmind not found. Exiting script." exit 0 NAME=kadm DESC="Start and stop Kerberos5 kadmind process" check_kadmin_status { kadmind_pid=`ps -C kadmind -o pid=` if [ -z "$kadmind_pid" ]; then # kadmind is NOT running return 2 fi if [ -n "$kadmind_pid" ]; then # kadmind is running return 0 fi } case "$1" in 	start) 	echo "Starting kadmind... " 		check_kadmin_status 		RETVAL=$? 	[ $RETVAL -eq 2 ] && /usr/local/sbin/kadmind && echo " kadmind started" ||  		echo "  kadmind already running!" 			;; 	stop) echo "Stopping kadmind: " check_kadmin_status RETVAL=$? [ $RETVAL -eq 0 ] && kdc=`ps -C kadmind -o pid=` && `kill $kdc` && echo " kadmind stopped" || echo " kadmind was not running!" ;; 	restart|reload) 		check_kadmin_status 		RETVAL=$? 	if [ $RETVAL -eq 2 ]; then 		echo "  kadmind was not running!" && echo "  starting kadmind: " &&  		/usr/local/sbin/kadmind && kdcpid=`ps x | grep -i kadmind | grep -v grep` && echo $kdcpid   	fi 	if [ $RETVAL -eq 0 ]; then 		echo "  stopping kadmind..." && kdc=`ps -C kadmind -o pid=` && `kill $kdc` &&  		echo "  starting kadmind: " && /usr/local/sbin/kadmind &&  		kdcpid=`ps x | grep -i kadmind | grep -v grep` && echo $kdcpid 	fi 	;; 	status) kadmind_pid=`ps -C kadmind -o pid=` [ -z $kadmind_pid ] && echo " kadmind NOT running" || echo "  kadmind running" ;; 	*) 		echo " Usage: kadm {start|stop|restart|status}" 		exit 1 esac exit 0
 * 1) !/bin/sh
 * 2) written by John Sullivan 12/29/2010
 * 3) 	/usr/local/sbin/kadmind
 * 4) description: Start and stop Kerberos5 kadmind process
 * 5) processname: kadmind
 * 1) Source function library
 * 1) If the executable doesn't exist, then why bother?

= See also =
 * Bash Tips
 * Category:Script