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:
#!/bin/bash echo "hello world"
Find out your distribution
Main article: find out your distribution
The following script tells you what distribution you have installed on your computer.
#!/bin/bash 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).
Tonka Script
Changes your console to some other colours.
#!/bin/bash function tonka { # 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
#!/bin/bash # get ip /sbin/ifconfig $1 | grep inet | awk '{print $2}' | sed 's/^addr://g'
To get your Internet address if you are behind a NAT:
## The -n option retrieves the Internet IP 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 printf "%s\n" "$ip" ### CFAJ ###
Connect to a wireless access point (WPA compatible)
Tested in Ubuntu 8.10
#!/bin/bash #removing possible previous temp file rm list.temp 2>/dev/null #scans for wifi connections & isolates wifi AP name # thanks to jonjgc for the array solution # thanks to ghostdog74 for the AWK suggestion eval list=( $(sudo iwlist scan 2>/dev/null | awk -F":" '/ESSID/{print $2}') ) #sets prompt PS3="Choose wifi connection: " #tests for number of wifi connections, exits if none if [ -z "${list[0]}" ]; then clear echo "No available wifi connection" exit 1 fi #menu of wifi connections select item in "${list[@]}"; do #sets essid as value for WIFI variable and displays information about the AP wifi=$(echo $item) sudo iwlist scan 2>/dev/null | sed -n "/$wifi/, +9p" > list.temp echo "$(cat list.temp | sed 's/^[ \t]*//')" #sets channel as value for CHANNEL variable channel=$(grep Channel: list.temp | sed 's/.*Channel://g') #test for mode, if mode = master, sets MODE variable to managed mode=$(grep Mode list.temp | sed 's/.*Mode://g') if [ "$mode" == "Master" ]; then mode="managed" else clear echo "Cannot connect" exit fi #tests for encryption key key=$(grep key: list.temp | sed 's/.*key://g') if [ $key == "on" ]; then echo -n "Enter encryption key: " read key fi #checks encryption algorithm IE=$(grep IE list.temp | sed 's/^ .*IE: \(...\).*/\1/') #writes to /etc/network/interfaces file for WPA encryption: essid, key, protocols, etc. 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 else #sets the wireless configuration for non WPA: essid, channel, mode, key, etc sudo iwconfig wlan0 essid \""$wifi"\" channel $channel mode $mode key $key echo "------------------------------------------------" echo "Connecting to: $wifi at channel: $channel, mode: $mode" echo "------------------------------------------------" #connects to wifi connection sudo dhclient exit fi done
Command Line Trash Can
#!/bin/bash # Script by Jim Collings # Written Sat Jan 30 14:01:38 EST 2010 # A simple trash script that handles spaces and integrates properly with GUI Trash system. # Handles spaces properly according to every test I've devised so far. 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
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.
#!/bin/bash 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
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
#!/bin/sh # written by John Sullivan 12/29/2010 # /usr/local/sbin/krb5kdc # description: Start and stop Kerberos5 krb5kdc process # processname: krb5kdc # Source function library . /etc/rc.d/init.d/functions # If the executable doesn't exist, then why bother? 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
Named /etc/init.d/kadm
Starts the /usr/local/sbin/kadmind proc
#!/bin/sh # written by John Sullivan 12/29/2010 # /usr/local/sbin/kadmind # description: Start and stop Kerberos5 kadmind process # processname: kadmind # Source function library . /etc/rc.d/init.d/functions # If the executable doesn't exist, then why bother? 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