This commit is contained in:
gferg 2001-07-10 14:25:50 +00:00
parent d0751543ff
commit 8ebf0e0ba6
195 changed files with 25934 additions and 0 deletions

View File

@ -0,0 +1,26 @@
The following is the copyright notice for the two included "contrib" scripts
by Mark Moraes, behead.sh and ftpget.sh.
/*
* Copyright University of Toronto 1988, 1989.
* Written by Mark Moraes
*
* Permission is granted to anyone to use this software for any purpose on
* any computer system, and to alter it and redistribute it freely, subject
* to the following restrictions:
*
* 1. The author and the University of Toronto are not responsible
* for the consequences of use of this software, no matter how awful,
* even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits must appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits must appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
SOME SCRIPTS WILL NOT RUN
Note that the source code for a few of the example shell scripts
(ex57.sh, ex70.sh, ex71.sh, ex71a.sh, ex71b.sh, encryptedpw.sh, pw.sh,
du.sh, rnd.sh, logevents.sh, and rot13.sh) have the "<" and ">"
in place of angle brackets (< and >). This is necessary for the Docbook
SGML conversion. If you plan to run these scripts from the enclosed source
files, then it will, of course, be necessary to restore the angle brackets.
&lt; becomes <
&gt; becomes >
&lt;&lt; becomes <<
&gt;&gt; becomes >>

View File

@ -0,0 +1,16 @@
REM VIEWDATA: INSPIRED BY AN EXAMPLE IN "DOS POWERTOOLS", BY PAUL SOMERSON
@ECHO OFF
IF !%1==! GOTO VIEWDATA
REM IF NO COMMAND-LINE ARG...
FIND "%1" C:\BOZO\BOOKLIST.TXT
GOTO EXIT0
REM PRINT LINE WITH STRING MATCH, THEN EXIT.
:VIEWDATA
TYPE C:\BOZO\BOOKLIST.TXT | MORE
REM SHOW ENTIRE FILE, 1 PAGE AT A TIME.
:EXIT0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
#!/bin/bash
# Adding a second hard drive to system.
# Software configuration. Assumes hardware already mounted.
# From an article by the author of this document.
# in issue #38 of "Linux Gazette", http://www.linuxgazette.com.
# This script must be run as root.
# Use with extreme caution!
# If something goes wrong, you may wipe out your current filesystem.
NEWDISK=/dev/hdb # Assumes /dev/hdb vacant. Check!
MOUNTPOINT=/mnt/newdisk # Or choose another mount point.
fdisk $NEWDISK
mke2fs -cv $NEWDISK1 # Check for bad blocks & verbose output.
# Note: /dev/hdb1, *not* /dev/hdb!
mkdir $MOUNTPOINT
chmod 777 $MOUNTPOINT # Makes new drive accessible to all users.
# Now, test...
# mount -t ext2 /dev/hdb1 /mnt/newdisk
# Try creating a directory.
# If it works, umount it, and proceed.
# Final step:
# Add following line to /etc/fstab.
# /dev/hdb1 /mnt/newdisk ext2 defaults 1 1
exit 0

View File

@ -0,0 +1,63 @@
#!/bin/bash
# May need to be invoked with #!/bin/bash2 on older systems.
shopt -s expand_aliases
# Must set this option, else script will not expand aliases.
# First, some fun.
alias Jesse_James='echo "\"Alias Jesse James\" was a 1959 comedy starring Bob Hope."'
Jesse_James
echo; echo; echo;
alias ll="ls -l"
# May use either single (') or double (") quotes to define an alias.
echo "Trying aliased \"ll\":"
ll /usr/X11R6/bin/mk* # Alias works.
echo
directory=/usr/X11R6/bin/
prefix=mk* # See if wild-card causes problems.
echo "Variables \"directory\" + \"prefix\" = $directory$prefix"
echo
alias lll="ls -l $directory$prefix"
echo "Trying aliased \"lll\":"
lll # Long listing of all files in /usr/X11R6/bin stating with mk.
# Alias handles concatenated variables, including wild-card o.k.
TRUE=1
echo
if [ TRUE ]
then
alias rr="ls -l"
echo "Trying aliased \"rr\" within if/then statement:"
rr /usr/X11R6/bin/mk* # Error message results!
# Aliases not expanded within compound statements.
echo "However, previously expanded alias still recognized:"
ll /usr/X11R6/bin/mk*
fi
echo
count=0
while [ $count -lt 3 ]
do
alias rrr="ls -l"
echo "Trying aliased \"rrr\" within \"while\" loop:"
rrr /usr/X11R6/bin/mk* # Alias will not expand here either.
let count+=1
done
exit 0

View File

@ -0,0 +1,19 @@
#!/bin/bash
# allprofs - print all user profiles
# This script written by Heiner Steven, and modified by the document author.
FILE=.bashrc # File containing user profile,
# was ".profile" in original script.
for home in `awk -F: '{print $6}' /etc/passwd`
do
[ -d "$home" ] || continue # If no home directory, go to next.
[ -r "$home" ] || continue # If not readable, go to next.
(cd $home; [ -e $FILE ] && less $FILE)
done
# When script terminates, there is no need to 'cd' back to original directory,
# because 'cd $home' takes place in a subshell.
exit 0

View File

@ -0,0 +1,13 @@
#!/bin/bash
# am-i-root.sh: Am I root or not?
ROOT_UID=0 # Root has $UID 0.
if [ "$UID" -eq "$ROOT_UID" ]
then
echo "You are root."
else
echo "You are just an ordinary user (but mom loves you just the same)."
fi
exit 0

View File

@ -0,0 +1,15 @@
#!/bin/bash
ARGS=1 # Number of arguments expected.
E_BADARGS=65 # Exit value if incorrect number of args passed.
test $# -ne $ARGS && echo "Usage: `basename $0` $ARGS argument(s)" && exit $E_BADARGS
# If condition-1 true (wrong number of args passed to script),
# then the rest of the line executes, and script terminates.
# Line below executes only if the above test fails.
echo "Correct number of arguments passed to this script."
exit 0
# To check exit value, do a "echo $?" after script termination.

View File

@ -0,0 +1,60 @@
#!/bin/bash
a=24
b=47
if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]
then
echo "Test #1 succeeds."
else
echo "Test #1 fails."
fi
# ERROR: if [ "$a" -eq 24 && "$b" -eq 47 ]
# attempts to execute ' [ "$a" -eq 24 '
# and fails to finding matching ']'.
#
# if [[ $a -eq 24 && $b -eq 24 ]] works
# (The "&&" has a different meaning in line 17 than in line 6.)
# Thanks, Stephane Chazelas.
if [ "$a" -eq 98 ] || [ "$b" -eq 47 ]
then
echo "Test #2 succeeds."
else
echo "Test #2 fails."
fi
# The -a and -o options provide
# an alternative compound condition test.
# Thanks to Patrick Callahan for pointing this out.
if [ "$a" -eq 24 -a "$b" -eq 47 ]
then
echo "Test #3 succeeds."
else
echo "Test #3 fails."
fi
if [ "$a" -eq 98 -o "$b" -eq 47 ]
then
echo "Test #4 succeeds."
else
echo "Test #4 fails."
fi
a=rhino
b=crocodile
if [ "$a" = rhino ] && [ "$b" = crocodile ]
then
echo "Test #5 succeeds."
else
echo "Test #5 fails."
fi
exit 0

View File

@ -0,0 +1,37 @@
#!/bin/bash
# Invoke this script with several arguments, such as "one two three".
if [ ! -n "$1" ]
then
echo "Usage: `basename $0` argument1 argument2 etc."
exit 65
fi
echo
index=1
echo "Listing args with \"\$*\":"
for arg in "$*" # Doesn't work properly if "$*" isn't quoted.
do
echo "Arg #$index = $arg"
let "index+=1"
done # $* sees all arguments as single word.
echo "Entire arg list seen as single word."
echo
index=1
echo "Listing args with \"\$@\":"
for arg in "$@"
do
echo "Arg #$index = $arg"
let "index+=1"
done # $@ sees arguments as separate words.
echo "Arg list seen as separate words."
echo
exit 0

View File

@ -0,0 +1,30 @@
#!/bin/bash
# Counting to 6 in 5 different ways.
n=1; echo -n "$n "
let "n = $n + 1" # let "n = n + 1" also works.
echo -n "$n "
: $((n = $n + 1))
# ":" necessary because otherwise Bash attempts
# to interpret "$((n = $n + 1))" as a command.
echo -n "$n "
n=$(($n + 1))
echo -n "$n "
: $[ n = $n + 1 ]
# ":" necessary because otherwise Bash attempts
# to interpret "$((n = $n + 1))" as a command.
# Works even if "n" was initialized as a string.
echo -n "$n "
n=$[ $n + 1 ]
# Works even if "n" was initialized as a string.
# Avoid this type of construct, since it is obsolete and nonportable.
echo -n "$n "; echo
# Thanks, Stephane Chazelas.
exit 0

View File

@ -0,0 +1,12 @@
#!/bin/bash
# Arithmetic tests.
# The (( )) construct evaluates and tests numerical expressions.
(( 0 ))
echo "Exit status of \"(( 0 ))\" is $?."
(( 1 ))
echo "Exit status of \"(( 1\ ))" is $?."
exit 0

View File

@ -0,0 +1,99 @@
:
##########################################################################
# Shellscript: base.sh - print number to different bases (Bourne Shell)
# Author : Heiner Steven (heiner.steven@odn.de)
# Date : 07-03-95
# Category : Desktop
# $Id$
##########################################################################
# Description
#
# Changes
# 21-03-95 stv fixed error occuring with 0xb as input (0.2)
##########################################################################
# ==> Used in this document with the script author's permission.
# ==> Comments added by document author.
PN=`basename "$0"` # Program name
VER=`echo '$Revision$' | cut -d' ' -f2` # ==> VER=1.2
Usage () {
echo "$PN - print number to different bases, $VER (stv '95)
usage: $PN [number ...]
If no number is given, the numbers are read from standard input.
A number may be
binary (base 2) starting with 0b (i.e. 0b1100)
octal (base 8) starting with 0 (i.e. 014)
hexadecimal (base 16) starting with 0x (i.e. 0xc)
decimal otherwise (i.e. 12)" >&2
exit 65
}
Msg () {
for i # ==> in [list] missing.
do echo "$PN: $i" >&2
done
}
Fatal () { Msg "$@"; exit 66; }
PrintBases () {
# Determine base of the number
for i # ==> in [list] missing...
do # ==> so operates on command line arg(s).
case "$i" in
0b*) ibase=2;; # binary
0x*|[a-f]*|[A-F]*) ibase=16;; # hexadecimal
0*) ibase=8;; # octal
[1-9]*) ibase=10;; # decimal
*)
Msg "illegal number $i - ignored"
continue;;
esac
# Remove prefix, convert hex digits to uppercase (bc needs this)
number=`echo "$i" | sed -e 's:^0[bBxX]::' | tr '[a-f]' '[A-F]'`
# ==> Uses ":" as sed separator, rather than "/".
# Convert number to decimal
dec=`echo "ibase=$ibase; $number" | bc` # ==> 'bc' is calculator utility.
case "$dec" in
[0-9]*) ;; # number ok
*) continue;; # error: ignore
esac
# Print all conversions in one line.
# ==> 'here document' feeds command list to 'bc'.
echo `bc <<!
obase=16; "hex="; $dec
obase=10; "dec="; $dec
obase=8; "oct="; $dec
obase=2; "bin="; $dec
!
` | sed -e 's: : :g'
done
}
while [ $# -gt 0 ]
do
case "$1" in
--) shift; break;;
-h) Usage;; # ==> Help message.
-*) Usage;;
*) break;; # first number
esac # ==> More error checking for illegal input would be useful.
shift
done
if [ $# -gt 0 ]
then
PrintBases "$@"
else # read from stdin
while read line
do
PrintBases $line
done
fi

View File

@ -0,0 +1,440 @@
#===============================================================
#
# PERSONAL $HOME/.bashrc FILE for bash-2.04 (or later)
#
# This file is read (normally) by interactive shells only.
# Here is the place to define your aliases, functions and
# other interactive features like your prompt.
#
# This file was designed (originally) for Solaris.
# --> Modified for Linux.
#
#===============================================================
# --> Comments added by HOWTO author.
#-----------------------------------
# Source global definitions (if any)
#-----------------------------------
if [ -f /etc/bashrc ]; then
. /etc/bashrc # --> Read /etc/bashrc, if present.
fi
#-------------------------------------------------------------
# Automatic setting of $DISPLAY (if not set already)
# This works for linux and solaris - your mileage may vary....
#-------------------------------------------------------------
if [ -z ${DISPLAY:=""} ]; then
DISPLAY=$(who am i)
DISPLAY=${DISPLAY%%\!*}
if [ -n "$DISPLAY" ]; then
export DISPLAY=$DISPLAY:0.0
else
export DISPLAY=":0.0" # fallback
fi
fi
#---------------
# Some settings
#---------------
set -o notify
set -o noclobber
set -o ignoreeof
set -o nounset
#set -o xtrace # useful for debuging
shopt -s cdspell
shopt -s cdable_vars
shopt -s checkhash
shopt -s checkwinsize
shopt -s mailwarn
shopt -s sourcepath
shopt -s no_empty_cmd_completion
shopt -s histappend histreedit
shopt -s extglob # useful for programmable completion
#-----------------------
# Greeting, motd etc...
#-----------------------
# Define some colors first:
red='\e[0;31m'
RED='\e[1;31m'
blue='\e[0;34m'
BLUE='\e[1;34m'
cyan='\e[0;36m'
CYAN='\e[1;36m'
NC='\e[0m' # No Color
# --> Nice. Has the same effect as using "ansi.sys" in DOS.
# Looks best on a black background.....
echo -e "${CYAN}This is BASH ${RED}${BASH_VERSION%.*}${CYAN} - DISPLAY on ${RED}$DISPLAY${NC}\n"
date
function _exit() # function to run upon exit of shell
{
echo -e "${RED}Hasta la vista, baby${NC}"
}
trap _exit 0
#---------------
# Shell prompt
#---------------
function fastprompt()
{
unset PROMPT_COMMAND
case $TERM in
*term | rxvt )
PS1="[\h] \W > \[\033]0;[\u@\h] \w\007\]" ;;
*)
PS1="[\h] \W > " ;;
esac
}
function powerprompt()
{
_powerprompt()
{
LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")
TIME=$(date +%H:%M)
}
PROMPT_COMMAND=_powerprompt
case $TERM in
*term | rxvt )
PS1="${cyan}[\$TIME \$LOAD]$NC\n[\h \#] \W > \[\033]0;[\u@\h] \w\007\]" ;;
linux )
PS1="${cyan}[\$TIME - \$LOAD]$NC\n[\h \#] \w > " ;;
* )
PS1="[\$TIME - \$LOAD]\n[\h \#] \w > " ;;
esac
}
powerprompt # this is the default prompt - might be slow
# If too slow, use fastprompt instead....
#===============================================================
#
# ALIASES AND FUNCTIONS
#
# Arguably, some functions defined here are quite big
# (ie 'lowercase') but my workstation has 512Meg of RAM, so .....
# If you want to make this file smaller, these functions can
# be converted into scripts.
#
# Many functions were taken (almost) straight from the bash-2.04
# examples.
#
#===============================================================
#-------------------
# Personnal Aliases
#-------------------
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# -> Prevents accidentally clobbering files.
alias h='history'
alias j='jobs -l'
alias r='rlogin'
alias which='type -a'
alias ..='cd ..'
alias path='echo -e ${PATH//:/\\n}'
alias print='/usr/bin/lp -o nobanner -d $LPDEST'
alias pjet='enscript -h -G -fCourier9 -d $LPDEST '
alias vi='vim'
alias du='du -h'
alias df='df -kh'
alias ls='ls -hF --color'
alias lx='ls -lXB'
alias lk='ls -lSr'
alias la='ls -Al'
alias lr='ls -lR'
alias lt='ls -ltr'
alias lm='ls -al |more'
alias background='xv -root -quit -max -rmode 5'
alias more='less'
export PAGER=less
export LESSCHARSET='latin1'
export LESSOPEN='|lesspipe.sh %s' # Use this if lesspipe.sh exists
export LESS='-i -N -w -z-4 -g -e -M -X -F -R -P%t?f%f \
:stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...'
# spelling typos
alias xs='cd'
alias vf='cd'
alias moer='more'
alias moew='more'
alias kk='ll'
#----------------
# a few fun ones
#----------------
function xtitle ()
{
case $TERM in
*term | rxvt)
echo -n -e "\033]0;$*\007" ;;
*) ;;
esac
}
alias top='xtitle Processes on $HOST && top'
alias make='xtitle Making $(basename $PWD) ; make'
alias ncftp="xtitle ncFTP ; ncftp"
#---------------
# and functions
#---------------
function man ()
{
xtitle The $(basename $1|tr -d .[:digit:]) manual
man -a "$*"
}
function ll(){ ls -l $*| egrep "^d" ; ls -lh $* 2>&-| egrep -v "^d|total "; }
function xemacs() { { command xemacs -private $* 2>&- & } && disown ;}
function te() # wrapper around xemacs/gnuserv
{
if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then
gnuclient -q $@;
else
( xemacs $@ & );
fi
}
#-----------------------------------
# File & strings related functions:
#-----------------------------------
function ff() { find . -name '*'$1'*' ; }
function fe() { find . -name '*'$1'*' -exec $2 {} \; ; }
function fstr() # find a string in a set of files
{
if [ "$#" -gt 2 ]; then
echo "Usage: fstr \"pattern\" [files] "
return;
fi
SMSO=$(tput smso)
RMSO=$(tput rmso)
find . -type f -name "${2:-*}" -print | xargs grep -sin "$1" | \
sed "s/$1/$SMSO$1$RMSO/gI"
}
function cuttail() # cut last n lines in file, 10 by default
{
nlines=${2:-10}
sed -n -e :a -e "1,${nlines}!{P;N;D;};N;ba" $1
}
function lowercase() # move filenames to lowercase
{
for file ; do
filename=${file##*/}
case "$filename" in
*/*) dirname==${file%/*} ;;
*) dirname=.;;
esac
nf=$(echo $filename | tr A-Z a-z)
newname="${dirname}/${nf}"
if [ "$nf" != "$filename" ]; then
mv "$file" "$newname"
echo "lowercase: $file --> $newname"
else
echo "lowercase: $file not changed."
fi
done
}
function swap() # swap 2 filenames around
{
local TMPFILE=tmp.$$
mv $1 $TMPFILE
mv $2 $1
mv $TMPFILE $2
}
# Misc utilities:
function repeat() # repeat n times command
{
local i max
max=$1; shift;
for ((i=1; i <= max ; i++)); do # --> C-like syntax
eval "$@";
done
}
function ask()
{
echo -n "$@" '[y/n] ' ; read ans
case "$ans" in
y*|Y*) return 0 ;;
*) return 1 ;;
esac
}
#=========================================================================
#
# PROGRAMMABLE COMPLETION - ONLY IN BASH-2.04
# (Most are taken from the bash 2.04 documentation)
#
#=========================================================================
if [ "${BASH_VERSION%.*}" \< "2.04" ]; then
echo "No programmable completion available"
return
fi
shopt -s extglob # necessary
complete -A hostname rsh rcp telnet rlogin r ftp ping disk
complete -A command nohup exec eval trace gdb
complete -A command command type which
complete -A export printenv
complete -A variable export local readonly unset
complete -A enabled builtin
complete -A alias alias unalias
complete -A function function
complete -A user su mail finger
complete -A helptopic help # currently same as builtins
complete -A shopt shopt
complete -A stopped -P '%' bg
complete -A job -P '%' fg jobs disown
complete -A directory mkdir rmdir
complete -f -X '*.gz' gzip
complete -f -X '!*.ps' gs ghostview gv
complete -f -X '!*.pdf' acroread
complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|bmp)' xv gimp
_make_targets ()
{
local mdef makef gcmd cur prev i
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
# if prev argument is -f, return possible filename completions.
# we could be a little smarter here and return matches against
# `makefile Makefile *.mk', whatever exists
case "$prev" in
-*f) COMPREPLY=( $(compgen -f $cur ) ); return 0;;
esac
# if we want an option, return the possible posix options
case "$cur" in
-) COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;;
esac
# make reads `makefile' before `Makefile'
if [ -f makefile ]; then
mdef=makefile
elif [ -f Makefile ]; then
mdef=Makefile
else
mdef=*.mk # local convention
fi
# before we scan for targets, see if a makefile name was specified
# with -f
for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do
if [[ ${COMP_WORDS[i]} == -*f ]]; then
eval makef=${COMP_WORDS[i+1]} # eval for tilde expansion
break
fi
done
[ -z "$makef" ] && makef=$mdef
# if we have a partial word to complete, restrict completions to
# matches of that word
if [ -n "$2" ]; then gcmd='grep "^$2"' ; else gcmd=cat ; fi
# if we don't want to use *.mk, we can take out the cat and use
# test -f $makef and input redirection
COMPREPLY=( $(cat $makef 2>/dev/null | awk 'BEGIN {FS=":"} /^[^.# ][^=]*:/ {print $1}' | tr -s ' ' '\012' | sort -u | eval $gcmd ) )
}
complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake
_configure_func ()
{
case "$2" in
-*) ;;
*) return ;;
esac
case "$1" in
\~*) eval cmd=$1 ;;
*) cmd="$1" ;;
esac
COMPREPLY=( $("$cmd" --help | awk '{if ($1 ~ /--.*/) print $1}' | grep ^"$2" | sort -u) )
}
complete -F _configure_func configure
_killall ()
{
local cur prev
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
# get a list of processes (the first sed evaluation
# takes care of swapped out processes, the second
# takes care of getting the basename of the process)
COMPREPLY=( $( /usr/bin/ps -u $USER -o comm | \
sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \
awk '{if ($0 ~ /^'$cur'/) print $0}' ))
return 0
}
complete -F _killall killall
# Local Variables:
# mode:shell-script
# sh-shell:bash
# End:

View File

@ -0,0 +1,24 @@
#! /bin/sh
# Strips off the header from a mail/News message i.e. till the first
# empty line
# Mark Moraes, University of Toronto
# --> These comments added by author of this document.
if [ $# -eq 0 ]; then
# --> If no command line args present, then works on file redirected to stdin.
sed -e '1,/^$/d' -e '/^[ ]*$/d'
# --> Delete empty lines and all lines until
# --> first one beginning with white space.
else
# --> If command line args present, then work on files named.
for i do
sed -e '1,/^$/d' -e '/^[ ]*$/d' $i
# --> Ditto, as above.
done
fi
# --> Exercise for the reader: Add error checking and other options.
# -->
# --> Note that the small sed script repeats, except for the arg passed.
# --> Does it make sense to embed it in a function? Why or why not?

View File

@ -0,0 +1,36 @@
#!/bin/bash
# Locates matching strings in a binary file.
# A "grep" replacement for binary files.
# Similar effect to "grep -a"
E_BADARGS=65
NOFILE=66
if [ $# -ne 2 ]
then
echo "Usage: `basename $0` string filename"
exit $E_BADARGS
fi
if [ ! -f "$2" ]
then
echo "File \"$2\" does not exist."
exit $NOFILE
fi
for word in $( strings "$2" | grep "$1" )
# The "strings" command lists strings in binary files,
# then piped to "grep", which tests for desired string.
do
echo $word
done
# As S.C. points out, the above for-loop could be replaced with the simpler
# strings "$2" | grep "$1" | tr -s "$IFS" '[\n*]'
# Try something like "./bin-grep mem /bin/ls" to exercise this script.
exit 0

View File

@ -0,0 +1,28 @@
#!/bin/bash
# Breaking out of loops.
# "break N" breaks out of N level loops.
for outerloop in 1 2 3 4 5
do
echo -n "Group $outerloop: "
for innerloop in 1 2 3 4 5
do
echo -n "$innerloop "
if [ "$innerloop" -eq 3 ]
then
break
# Replace the line above with break 2
# to see what happens ("breaks" out of both inner and outer loops.)
fi
done
echo
done
echo
exit 0

View File

@ -0,0 +1,70 @@
#!/bin/bash
# Bubble sort, of sorts.
# Recall the algorithm for a bubble sort. In this particular version...
# With each successive pass through the array to be sorted,
# compare two adjacent elements, and swap them if out of order.
# At the end of the first pass, the "heaviest" element has sunk to bottom.
# At the end of the second pass, the next "heaviest" one has sunk next to bottom.
# And so forth.
# This means that each successive pass needs to traverse less of the array.
# You will therefore notice a speeding up in the printing of the later passes.
exchange()
{
# Swaps two members of the array.
local temp=${Countries[$1]} # Temporary storage for element getting swapped out.
Countries[$1]=${Countries[$2]}
Countries[$2]=$temp
return
}
declare -a Countries # Declare array, optional here since it's initialized below.
Countries=(Netherlands Ukraine Zaire Turkey Russia Yemen Syria Brazil Argentina Nicaragua Japan Mexico Venezuela Greece England Israel Peru Canada Oman Denmark Wales France Kenya Qatar Liechtenstein Hungary)
# Couldn't think of one starting with X (darn).
clear # Clear the screen to start with.
echo "0: ${Countries[*]}" # List entire array at pass 0.
number_of_elements=${#Countries[@]}
let "comparisons = $number_of_elements - 1"
count=1 # Pass number.
while [ $comparisons -gt 0 ] # Beginning of outer loop
do
index=0 # Reset index to start of array after each pass.
while [ $index -lt $comparisons ] # Beginning of inner loop
do
if [ ${Countries[$index]} \> ${Countries[`expr $index + 1`]} ]
# If out of order...
# Recalling that \> is ASCII comparison operator.
then
exchange $index `expr $index + 1` # Swap.
fi
let "index += 1"
done # End of inner loop
let "comparisons -= 1"
# Since "heaviest" element bubbles to bottom, we need do one less comparison each pass.
echo
echo "$count: ${Countries[@]}"
# Print resultant array at end of each pass.
echo
let "count += 1" # Increment pass count.
done # End of outer loop
# All done.
exit 0

View File

@ -0,0 +1,43 @@
#!/bin/bash
# Manipulating a variable, C-style, using the ((...)) construct.
echo
(( a = 23 )) # Setting a value, C-style, with spaces on both sides of the "=".
echo "a (initial value) = $a"
(( a++ )) # Post-increment 'a', C-style.
echo "a (after a++) = $a"
(( a-- )) # Post-decrement 'a', C-style.
echo "a (after a--) = $a"
(( ++a )) # Pre-increment 'a', C-style.
echo "a (after ++a) = $a"
(( --a )) # Pre-decrement 'a', C-style.
echo "a (after --a) = $a"
echo
(( t = a<45?7:11 )) # C-style trinary operator.
echo "If a < 45, then t = 7, else t = 11."
echo "t = $t " # Yes!
echo
# -----------------
# Easter Egg alert!
# -----------------
# Chet Ramey apparently snuck a bunch of undocumented C-style constructs into Bash.
# In the Bash docs, Ramey calls ((...)) shell arithmetic, but it goes far beyond that.
# Sorry, Chet, the secret is now out.
# See also "for" and "while" loops using the ((...)) construct.
# Note: these may not work with early versions of Bash,
# or on other platforms besides Linux.
exit 0

View File

@ -0,0 +1,13 @@
#!/bin/bash
# Using command substitution to generate a "case" variable.
case $( arch ) in # "arch" returns machine architecture.
i386 ) echo "80386-based machine";;
i486 ) echo "80486-based machine";;
i586 ) echo "Pentium-based machine";;
i686 ) echo "Pentium2-based machine";;
* ) echo "Other type of machine";;
esac
exit 0

View File

@ -0,0 +1,51 @@
#!/bin/bash
# Adds up a specified column (of numbers) in the target file.
ARGS=2
WRONGARGS=65
if [ $# -ne "$ARGS" ]
# Check for proper no. of command line args.
then
echo "Usage: `basename $0` filename column-number"
exit $WRONGARGS
fi
filename=$1
column_number=$2
# Passing shell variables to the awk part of the script is a bit tricky.
# See the awk documentation for more details.
# A multi-line awk script is invoked by awk ' ..... '
# Begin awk script.
# -----------------------------
awk '
{ total += $'"${column_number}"'
}
END {
print total
}
' "$filename"
# -----------------------------
# End awk script.
# It may not be safe to pass shell variables to an embedded awk script,
# so Stephane Chazelas proposes the following alternative:
# ---------------------------------------
# awk -v column_number="$column_number" '
# { total += $column_number
# }
# END {
# print total
# }' "$filename"
# ---------------------------------------
exit 0

View File

@ -0,0 +1,45 @@
#!/bin/bash
# Another version of the "column totaler" script
# that adds up a specified column (of numbers) in the target file.
# This uses indirect references.
ARGS=2
WRONGARGS=65
if [ $# -ne "$ARGS" ]
# Check for proper no. of command line args.
then
echo "Usage: `basename $0` filename column-number"
exit $WRONGARGS
fi
filename=$1
column_number=$2
#===== Same as original script, up to this point =====#
# A multi-line awk script is invoked by awk ' ..... '
# Begin awk script.
# ------------------------------------------------
awk "
{ total += \$${column_number} # indirect reference
}
END {
print total
}
" "$filename"
# ------------------------------------------------
# End awk script.
# Indirect variable reference avoids the hassles
# of referencing a shell variable within the embedded awk script.
# Thanks, Stephane Chazelas.
exit 0

View File

@ -0,0 +1,37 @@
#!/bin/bash
# Yet another version of the "column totaler" script (col-totaler.sh)
# that adds up a specified column (of numbers) in the target file.
# This uses the environment to pass a script variable to 'awk'.
ARGS=2
WRONGARGS=65
if [ $# -ne "$ARGS" ]
# Check for proper no. of command line args.
then
echo "Usage: `basename $0` filename column-number"
exit $WRONGARGS
fi
filename=$1
column_number=$2
#===== Same as original script, up to this point =====#
export column_number
# Export column number to environment, so it's available for retrieval.
# Begin awk script.
# ------------------------------------------------
awk '{ total += $ENVIRON["column_number"]
}
END { print total }' $filename
# ------------------------------------------------
# End awk script.
# Thanks, Stephane Chazelas.
exit 0

View File

@ -0,0 +1,14 @@
#!/bin/bash
# This is a slight modification of the example file in the "column" man page.
(printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n" \
; ls -l | sed 1d) | column -t
# The "sed 1d" in the pipe deletes the first line of output,
# which would be "total N",
# where "N" is the total number of files found by "ls -l".
# The -t option to "column" pretty-prints a table.
exit 0

View File

@ -0,0 +1,45 @@
#!/bin/bash
PROCNAME=pppd # ppp daemon
PROCFILENAME=status # Where to look.
NOTCONNECTED=65
INTERVAL=2 # Update every 2 seconds.
pidno=$( ps ax | grep -v "ps ax" | grep -v grep | grep $PROCNAME | awk '{ print $1 }' )
# Finding the process number of 'pppd', the 'ppp daemon'.
# Have to filter out the process lines generated by the search itself.
if [ -z "$pidno" ] # If no pid, then process is not running.
then
echo "Not connected."
exit $NOTCONNECTED
else
echo "Connected."; echo
fi
while [ true ] # Endless loop, script can be improved here.
do
if [ ! -e "/proc/$pidno/$PROCFILENAME" ]
# While process running, then "status" file exists.
then
echo "Disconnected."
exit $NOTCONNECTED
fi
netstat -s | grep "packets received" # Get some connect statistics.
netstat -s | grep "packets delivered"
sleep $INTERVAL
echo; echo
done
exit 0
# As it stands, this script must be terminated with a Control-C.
# Exercises for the reader:
# Improve the script so it exits on a "q" keystroke.
# Make the script more user-friendly in other ways.

View File

@ -0,0 +1,27 @@
#!/bin/bash
# The "continue N" command, continuing at the Nth level loop.
for outer in I II III IV V # outer loop
do
echo; echo -n "Group $outer: "
for inner in 1 2 3 4 5 6 7 8 9 10 # inner loop
do
if [ "$inner" -eq 7 ]
then
continue 2 # Continue at loop on 2nd level, that is "outer loop".
# Replace above line with a simple "continue" to see normal loop behavior.
fi
echo -n "$inner " # 8 9 10 will never echo.
done
done
echo; echo
# Exercise for the reader:
# Come up with a meaningful use for "continue N" in a script.
exit 0

View File

@ -0,0 +1,49 @@
#!/bin/bash
# copy-cd.sh: copying a data CD
CDROM=/dev/cdrom # CD ROM device
OF=/home/bozo/projects/cdimage.iso # output file
# /xxxx/xxxxxxx/ Change to suit your system.
BLOCKSIZE=2048
SPEED=2 # May use higher speed if supported.
echo; echo "Insert source CD, but do *not* mount it."
echo "Press ENTER when ready. "
read ready # Wait for input, $ready not used.
echo; echo "Copying the source CD to $OF."
echo "This may take a while. Please be patient."
dd if=$CDROM of=$OF bs=$BLOCKSIZE # Raw device copy.
echo; echo "Remove data CD."
echo "Insert blank CDR."
echo "Press ENTER when ready. "
read ready # Wait for input, $ready not used.
echo "Copying $OF to CDR."
cdrecord -v -isosize speed=$SPEED dev=0,0 $OF
# Uses Joerg Schilling's "cdrecord" package (see its docs).
# (http://www.fokus.gmd.de/nthp/employees/schilling/cdrecord.html)
echo; echo "Done copying $OF to CDR on device $CDROM."
echo "Do you want to erase the image file (y/n)? " # Probably a huge file.
read answer
case "$answer" in
[yY]) rm -f $OF
echo "$OF erased."
;;
*) echo "$OF not erased.";;
esac
echo
# Exercise for the reader:
# Change the above "case" statement to also accept "yes" and "Yes" as input.
exit 0

View File

@ -0,0 +1,41 @@
# This is a data file loaded by a script.
# Files of this type may contain variables, functions, etc.
# It may be loaded with a 'source' or '.' command by a shell script.
# Let's initialize some variables.
variable1=22
variable2=474
variable3=5
variable4=97
message1="Hello, how are you?"
message2="Enough for now. Goodbye."
print_message ()
{
# Echoes any message passed to it.
if [ -z "$1" ]
then
return 1
# Error, if argument missing.
fi
echo
until [ -z "$1" ]
do
# Step through arguments passed to function.
echo -n "$1"
# Echo args one at a time, suppressing line feeds.
echo -n " "
# Insert spaces between words.
shift
# Next one.
done
echo
return 0
}

View File

@ -0,0 +1,21 @@
#!/bin/bash
# Capture keystrokes without needing to press ENTER.
keypresses=4 # Number of keypresses to capture.
old_tty_setting=$(stty -g) # Save old terminal settings.
echo "Press $keypresses keys."
stty -icanon -echo # Disable canonical mode.
# Disable local echo.
keys=$(dd bs=1 count=$keypresses 2> /dev/null)
# 'dd' uses stdin, if "if" not specified.
stty "$old_tty_setting" # Restore old terminal settings.
echo "You pressed the \"$keys\" keys."
# Thanks, S.C. for showing the way.
exit 0

View File

@ -0,0 +1,23 @@
#!/bin/bash
# du.sh: DOS to UNIX text file converter.
WRONGARGS=65
if [ -z "$1" ]
then
echo "Usage: `basename $0` filename-to-convert"
exit $WRONGARGS
fi
NEWFILENAME=$1.unx
CR='\015' # Carriage return.
# Lines in DOS text files end in a CR-LF.
tr -d $CR &lt; $1 &gt; $NEWFILENAME
# Delete CR and write to new file.
echo "Original DOS text file is \"$1\"."
echo "Converted UNIX text file is \"$NEWFILENAME\"."
exit 0

View File

@ -0,0 +1,28 @@
#!/bin/bash
# empty-array.sh
# An empty array is not the same as an array with empty elements.
array0=( first second third )
array1=( '' ) # "array1" has one empty element.
array2=( ) # No elements... "array2" is empty.
echo
echo "Elements in array0: ${array0[@]}"
echo "Elements in array1: ${array1[@]}"
echo "Elements in array2: ${array2[@]}"
echo
echo "Length of first element in array0 = ${#array0}"
echo "Length of first element in array1 = ${#array1}"
echo "Length of first element in array2 = ${#array2}"
echo
echo "Number of elements in array0 = ${#array0[*]}" # 3
echo "Number of elements in array1 = ${#array1[*]}" # 1 (surprise!)
echo "Number of elements in array2 = ${#array2[*]}" # 0
echo
# Thanks, S.C.
exit 0

View File

@ -0,0 +1,43 @@
#!/bin/bash
# Example 3-71 modified to use encrypted password.
if [ -z "$1" ]
then
echo "Usage: `basename $0` filename"
exit 65
fi
Username=bozo
# Change to suit.
Filename=`basename $1`
# Strips pathname out of file name
Server="XXX"
Directory="YYY"
# Change above to actual server name & directory.
password=`cruft &lt;pword`
# "pword" is the file containing encrypted password.
# Uses the author's own "cruft" file encryption package,
# based on the classic "onetime pad" algorithm,
# and obtainable from:
# Primary-site: ftp://metalab.unc.edu /pub/Linux/utils/file
# cruft-0.2.tar.gz [16k]
ftp -n $Server &lt;&lt;End-Of-Session
# -n option disables auto-logon
user $Username $Password
binary
bell
# Ring 'bell' after each file transfer
cd $Directory
put $Filename
bye
End-Of-Session
exit 0

View File

@ -0,0 +1,23 @@
#!/bin/bash
# Escaped characters
echo "\v\v\v\v" # Prints \v\v\v\v
# Must use the -e option with 'echo' to print escaped characters.
echo -e "\v\v\v\v" # Prints 4 vertical tabs.
echo -e "\042" # Prints " (quote, octal ASCII character 42).
# Bash, version 2 and later, permits using the $'\xxx' construct.
echo $'\n'
echo $'\a'
echo $'\t \042 \t' # Quote (") framed by tabs.
# Assigning ASCII characters to a variable.
# ----------------------------------------
quote=$'\042' # " assigned to a variable.
echo "$quote This is a quoted string, $quote and this lies outside the quotes."
# Concatenating ASCII chars in a variable.
triple_underline=$'\137\137\137' # 137 is octal ASCII code for _
echo "$triple_underline UNDERLINE $triple_underline"
exit 0

View File

@ -0,0 +1,7 @@
# cleanup
# Run as root, of course.
cd /var/log
cat /dev/null > messages
cat /dev/null > wtmp
echo "Logs cleaned up."

View File

@ -0,0 +1,83 @@
#!/bin/bash
echo
echo "Testing \"0\""
if [ 0 ]
#zero
then
echo "0 is true."
else
echo "0 is false."
fi
echo
echo "Testing \"NULL\""
if [ ]
#NULL (empty condition)
then
echo "NULL is true."
else
echo "NULL is false."
fi
echo
echo "Testing \"xyz\""
if [ xyz ]
#string
then
echo "Random string is true."
else
echo "Random string is false."
fi
echo
echo "Testing \"\$xyz\""
if [ $xyz ] # Tests if $xyz is null, but...
#string
then
echo "Uninitialized variable is true."
else
echo "Uninitialized variable is false."
fi
echo
echo "Testing \"-n \$xyz\""
if [ -n "$xyz" ] # ...this is better.
#string
then
echo "Uninitialized variable is true."
else
echo "Uninitialized variable is false."
fi
echo
# When is "false" true?
echo "Testing \"false\""
if [ "false" ]
then
echo "\"false\" is true."
else
echo "\"false\" is false."
fi
echo
echo "Testing \"\$false\"" # Again, uninitialized variable.
if [ "$false" ]
then
echo "\"\$false\" is true."
else
echo "\"\$false\" is false."
fi
echo
exit 0

View File

@ -0,0 +1,27 @@
#!/bin/bash
echo
if test -z "$1"
then
echo "No command-line arguments."
else
echo "First command-line argument is $1."
fi
# Both code blocks are functionally identical.
if [ -z "$1" ]
# if [ -z "$1"
# also works, but outputs an error message.
then
echo "No command-line arguments."
else
echo "First command-line argument is $1."
fi
echo
exit 0

View File

@ -0,0 +1,15 @@
#!/bin/bash
filename=sys.log
cat /dev/null > $filename; echo "Creating / cleaning out file."
# Creates file if it does not already exist,
# and truncates it to zero length if it does.
# : > filename would also work.
tail /var/log/messages > $filename
# /var/log/messages must have world read permission for this to work.
echo "$filename contains tail end of system log."
exit 0

View File

@ -0,0 +1,26 @@
#!/bin/bash
a=4
b=5
# Here a and b can be treated either as integers or strings.
# There is some blurring between the arithmetic and string comparisons.
# Be careful.
if [ "$a" -ne "$b" ]
then
echo "$a is not equal to $b"
echo "(arithmetic comparison)"
fi
echo
if [ "$a" != "$b" ]
then
echo "$a is not equal to $b."
echo "(string comparison)"
fi
echo
exit 0

View File

@ -0,0 +1,43 @@
#!/bin/bash
#View gzipped files with 'most'
NOARGS=65
NOTFOUND=66
NOTGZIP=67
if [ $# -eq 0 ] # same effect as: if [ -z "$1" ]
# $1 can be empty but present: zmost "" arg2 arg3
then
echo "Usage: `basename $0` filename" >&2
# Error message to stderr.
exit $NOARGS
# Returns 65 as exit status of script (error code).
fi
filename=$1
if [ ! -f "$filename" ] # Quoting $filename allows for possible spaces.
then
echo "File $filename not found!" >&2
# Error message to stderr.
exit $NOTFOUND
fi
if [ ${filename##*.} != "gz" ]
# Using bracket in variable substitution.
then
echo "File $1 is not a gzipped file!"
exit $NOTGZIP
fi
zcat $1 | most
# Uses the file viewer 'most' (similar to 'less').
# Later versions of 'most' have file decompression capabilities.
# May substitute 'more' or 'less', if desired.
exit $? # Script returns exit status of pipe.
# Actually "exit $?" unnecessary, as the script will, in any case,
# return the exit status of the last command executed.

View File

@ -0,0 +1,34 @@
#!/bin/bash
echo
# When is a variable "naked", i.e., lacking the '$' in front?
# Assignment
a=879
echo "The value of \"a\" is $a"
# Assignment using 'let'
let a=16+5
echo "The value of \"a\" is now $a"
echo
# In a 'for' loop (really, a type of disguised assignment)
echo -n "The values of \"a\" in the loop are "
for a in 7 8 9 11
do
echo -n "$a "
done
echo
echo
# In a 'read' statement
echo -n "Enter \"a\" "
read a
echo "The value of \"a\" is now $a"
echo
exit 0

View File

@ -0,0 +1,19 @@
#!/bin/bash
a=23
# Simple case
echo $a
b=$a
echo $b
# Now, getting a little bit fancier...
a=`echo Hello!`
# Assigns result of 'echo' command to 'a'
echo $a
a=`ls -l`
# Assigns result of 'ls -l' command to 'a'
echo $a
exit 0

View File

@ -0,0 +1,40 @@
#!/bin/bash
# Call this script with at least 10 parameters, for example
# ./scriptname 1 2 3 4 5 6 7 8 9 10
echo
echo "The name of this script is \"$0\"."
# Adds ./ for current directory
echo "The name of this script is \"`basename $0`\"."
# Strip out path name info (see 'basename')
echo
if [ -n "$1" ] # Tested variable is quoted.
then
echo "Parameter #1 is $1"
# Need quotes to escape #
fi
if [ -n "$2" ]
then
echo "Parameter #2 is $2"
fi
if [ -n "$3" ]
then
echo "Parameter #3 is $3"
fi
# ...
if [ -n "${10}" ] # Parameters > $9 must be enclosed in {brackets}.
then
echo "Parameter #10 is ${10}"
fi
echo
exit 0

View File

@ -0,0 +1,30 @@
#!/bin/bash
# Does a 'whois domain-name' lookup
# on any of 3 alternate servers:
# ripe.net, cw.net, radb.net
# Place this script, named 'wh' in /usr/local/bin
# Requires symbolic links:
# ln -s /usr/local/bin/wh /usr/local/bin/wh-ripe
# ln -s /usr/local/bin/wh /usr/local/bin/wh-cw
# ln -s /usr/local/bin/wh /usr/local/bin/wh-radb
if [ -z "$1" ]
then
echo "Usage: `basename $0` [domain-name]"
exit 65
fi
case `basename $0` in
# Checks script name and calls proper server
"wh" ) whois $1@whois.ripe.net;;
"wh-ripe") whois $1@whois.ripe.net;;
"wh-radb") whois $1@whois.radb.net;;
"wh-cw" ) whois $1@whois.cw.net;;
* ) echo "Usage: `basename $0` [domain-name]";;
esac
exit 0

View File

@ -0,0 +1,19 @@
#!/bin/bash
# Name this script something like shift000,
# and invoke it with some parameters, for example
# ./shift000 a b c def 23 skidoo
# Demo of using 'shift'
# to step through all the positional parameters.
until [ -z "$1" ]
do
echo -n "$1 "
shift
done
echo
# Extra line feed.
exit 0

View File

@ -0,0 +1,74 @@
#!/bin/bash
# cleanup, version 2
# Run as root, of course.
LOG_DIR=/var/log
ROOT_UID=0 # Only users with $UID 0 have root privileges.
LINES=50 # Default number of lines saved.
XCD=66 # Can't change directory?
NOTROOT=67 # Non-root exit error.
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "Must be root to run this script."
exit $NOTROOT
fi
if [ -n "$1" ]
# Test if command line argument present (non-empty).
then
lines=$1
else
lines=$LINES
# default, if not specified on command line.
fi
# Stephane Chazelas suggests the following,
# as a better way of checking command line arguments,
# but this is still a bit advanced for this stage of the tutorial.
#
# WRONGARGS=65 # Non-numerical argument (bad arg format)
#
# case "$1" in
# "" ) lines=50;;
# *[!0-9]*) echo "Usage: `basename $0` file-to-cleanup"; exit $WRONGARGS;;
# * ) lines=$1;;
# esac
#
# Skip ahead to "Loops" to understand this.
cd $LOG_DIR
if [ `pwd` != "$LOG_DIR" ] # or if [ "$PWD" != "LOG_DIR" ]
# Not in /var/log?
then
echo "Can't change to $LOG_DIR."
exit $XCD
fi # Doublecheck if in right directory, before messing with log file.
# far better is:
# ---
# cd /var/log || {
# echo "Cannot change to necessary directory." >&2
# exit $XCD;
# }
tail -$lines messages > mesg.temp # Saves last section of message log file.
mv mesg.temp messages # Becomes new log directory.
# cat /dev/null > messages
# No longer needed, as the above method is safer.
cat /dev/null > wtmp # > wtemp has the same effect.
echo "Logs cleaned up."
exit 0
# A zero return value from the script upon exit
# indicates success to the shell.

View File

@ -0,0 +1,34 @@
#!/bin/bash
func1 ()
{
echo This is a function.
}
declare -f
# Lists the function above.
echo
declare -i var1 # var1 is an integer.
var1=2367
echo "var1 declared as $var1"
var1=var1+1
# Integer declaration eliminates the need for 'let'.
echo "var1 incremented by 1 is $var1."
# Attempt to change variable declared as integer
echo "Attempting to change var1 to floating point value, 2367.1."
var1=2367.1
# Results in error message, with no change to variable.
echo "var1 is still $var1"
echo
declare -r var2=13.36
echo "var2 declared as $var2"
# Attempt to change readonly variable.
var2=13.37
# Generates error message, and exit from script.
echo "var2 is still $var2" # This line will not execute.
exit 0 # Script will not exit here.

View File

@ -0,0 +1,100 @@
#!/bin/bash
# $RANDOM returns a different random integer at each invocation.
# Nominal range: 0 - 32767 (signed integer).
MAXCOUNT=10
count=1
echo
echo "$MAXCOUNT random numbers:"
echo "-----------------"
while [ "$count" -le $MAXCOUNT ] # Generate 10 ($MAXCOUNT) random integers.
do
number=$RANDOM
echo $number
let "count += 1" # Increment count.
done
echo "-----------------"
# If you need a random int within a certain range, then use the 'modulo' operator.
# This returns the remainder of a division operation.
RANGE=500
echo
number=$RANDOM
let "number %= $RANGE"
echo "Random number less than $RANGE --> $number"
echo
# If you need a random int greater than a lower bound,
# then set up a test to discard all numbers below that.
FLOOR=200
number=0 #initialize
while [ "$number" -le $FLOOR ]
do
number=$RANDOM
done
echo "Random number greater than $FLOOR --> $number"
echo
# May combine above two techniques to retrieve random number between two limits.
number=0 #initialize
while [ "$number" -le $FLOOR ]
do
number=$RANDOM
let "number %= $RANGE" # Scales $number down within $RANGE.
done
echo "Random number between $FLOOR and $RANGE --> $number"
echo
# May generate binary choice, that is, "true" or "false" value.
BINARY=2
number=$RANDOM
T=1
let "number %= $BINARY"
# let "number >>= 14" gives a better random distribution
# (right shifts out everything except last binary digit).
if [ "$number" -eq $T ]
then
echo "TRUE"
else
echo "FALSE"
fi
echo
# May generate toss of the dice.
SPOTS=7
DICE=2
ZERO=0
die1=0
die2=0
# Tosses each die separately, and so gives correct odds.
while [ "$die1" -eq $ZERO ] #Can't have a zero come up.
do
let "die1 = $RANDOM % $SPOTS"
done
while [ "$die2" -eq $ZERO ]
do
let "die2 = $RANDOM % $SPOTS"
done
let "throw = $die1 + $die2"
echo "Throw of the dice = $throw"
echo
exit 0

View File

@ -0,0 +1,16 @@
#!/bin/bash
for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto
do
echo $planet
done
echo
# Entire 'list' enclosed in quotes creates a single variable.
for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"
do
echo $planet
done
exit 0

View File

@ -0,0 +1,21 @@
#!/bin/bash
# Planets revisited.
# Want to associate name of each planet with its distance from the sun.
for planet in "Mercury 36" "Venus 67" "Earth 93" "Mars 142" "Jupiter 483"
do
set -- $planet # Parses variable "planet" and sets positional parameters.
# the "--" prevents nasty surprises if $planet is null or begins with a dash.
# May need to save original positional parameters, since they get overwritten.
# One way of doing this is to use an array,
# original_params=("$@)
echo "$1 $2,000,000 miles from the sun"
#-------two tabs---concatenate zeroes onto parameter $2
done
# (Thanks, S.C., for additional clarification.)
exit 0

View File

@ -0,0 +1,14 @@
#!/bin/bash
# Invoke both with and without arguments,
# and see what happens.
for a
do
echo $a
done
# 'in list' missing, therefore operates on '$@'
# (command-line argument list, including white space)
exit 0

View File

@ -0,0 +1,39 @@
#!/bin/bash
ARGS=2
E_BADARGS=65
if [ $# -ne $ARGS ]
# Check for proper no. of command line args.
then
echo "Usage: `basename $0` phone# text-file"
exit $E_BADARGS
fi
if [ ! -f "$2" ]
then
echo "File $2 is not a text file"
exit $E_BADARGS
fi
# Create fax formatted files from text files.
fax make $2
for file in $(ls $2.0*)
# Concatenate the converted files.
# Uses wild card in variable list.
do
fil="$fil $file"
done
# Do the work.
efax -d /dev/ttyS3 -o1 -t "T$1" $fil
# As S.C. points out, the for-loop can be eliminated with
# efax -d /dev/ttyS3 -o1 -t "T$1" $2.0*
# but it's not as instructive [grin].
exit 0

View File

@ -0,0 +1,16 @@
#!/bin/bash
var0=0
LIMIT=10
while [ "$var0" -lt "$LIMIT" ]
do
echo -n "$var0 "
# -n suppresses newline.
var0=`expr $var0 + 1`
# var0=$(($var0+1)) also works.
done
echo
exit 0

View File

@ -0,0 +1,17 @@
#!/bin/bash
echo
while [ "$var1" != "end" ]
do
echo "Input variable #1 (end to exit) "
read var1
# It's not 'read $var1' because value of var1 is being set.
echo "variable #1 = $var1"
# Need quotes because of #
echo
done
# Note: Echoes 'end' because termination condition tested for at top of loop.
exit 0

View File

@ -0,0 +1,21 @@
#!/bin/bash
var1=unset
previous=$var1
while echo "previous-variable = $previous"
echo
previous=$var1
[ "$var1" != end ] # Keeps track of what "var1" was previously.
# Four conditions on "while", but only last one controls loop.
# The *last* exit status is the one that counts.
do
echo "Input variable #1 (end to exit) "
read var1
echo "variable #1 = $var1"
done
# Try to figure out how this all works.
# It's a wee bit tricky.
exit 0

View File

@ -0,0 +1,12 @@
#!/bin/bash
until [ "$var1" = end ]
# Tests condition at top of loop.
do
echo "Input variable #1 "
echo "(end to exit)"
read var1
echo "variable #1 = $var1"
done
exit 0

View File

@ -0,0 +1,57 @@
#!/bin/bash
LIMIT=19 # Upper limit
echo
echo "Printing Numbers 1 through 20 (but not 3 and 11)."
a=0
while [ $a -le "$LIMIT" ]
do
a=$(($a+1))
if [ "$a" -eq 3 ] || [ "$a" -eq 11 ]
# Excludes 3 and 11
then
continue
# Skip rest of this particular loop iteration.
fi
echo -n "$a "
done
# Exercise for reader:
# Why does loop print up to 20?
echo
echo
echo Printing Numbers 1 through 20, but something happens after 2.
##################################################################
# Same loop, but substituting 'break' for 'continue'.
a=0
while [ "$a" -le "$LIMIT" ]
do
a=$(($a+1))
if [ "$a" -gt 2 ]
then
break
# Skip entire rest of loop.
fi
echo -n "$a "
done
echo
echo
echo
exit 0

View File

@ -0,0 +1,15 @@
#!/bin/bash
echo
echo "Hit a key, then hit return."
read Keypress
case "$Keypress" in
[a-z] ) echo "Lowercase letter";;
[A-Z] ) echo "Uppercase letter";;
[0-9] ) echo "Digit";;
* ) echo "Punctuation, whitespace, or other";;
esac
# Allows ranges of characters in [square brackets].
exit 0

View File

@ -0,0 +1,17 @@
#!/bin/bash
# This is a simple script that removes blank lines from a file.
# No argument checking.
# Same as
# sed -e '/^$/d' filename
# invoked from the command line.
sed -e /^$/d "$1"
# The '-e' means an "editing" command follows (optional here).
# '^' is beginning of line,
# '$' is end,
# and 'd' is delete.
# Quoting the command-line arg permits special chars in the filename.
exit 0

View File

@ -0,0 +1,62 @@
#!/bin/bash
# Crude rolodex-type database
clear
# Clear the screen.
echo " Contact List"
echo " ------- ----"
echo "Choose one of the following persons:"
echo
echo "[E]vans, Roland"
echo "[J]ones, Mildred"
echo "[S]mith, Julie"
echo "[Z]ane, Morris"
echo
read person
case "$person" in
# Note variable is quoted.
"E" | "e" )
# Accept upper or lowercase input.
echo
echo "Roland Evans"
echo "4321 Floppy Dr."
echo "Hardscrabble, CO 80753"
echo "(303) 734-9874"
echo "(303) 734-9892 fax"
echo "revans@zzy.net"
echo "Business partner & old friend"
;;
# Note double semicolon to terminate
# each option.
"J" | "j" )
echo
echo "Mildred Jones"
echo "249 E. 7th St., Apt. 19"
echo "New York, NY 10009"
echo "(212) 533-2814"
echo "(212) 533-9972 fax"
echo "milliej@loisaida.com"
echo "Girlfriend"
echo "Birthday: Feb. 11"
;;
# Add info for Smith & Zane later.
* )
# Default option.
echo
echo "Not yet in database."
;;
esac
echo
exit 0

View File

@ -0,0 +1,18 @@
#!/bin/bash
PS3='Choose your favorite vegetable: '
# Sets the prompt string.
echo
select vegetable in "beans" "carrots" "potatoes" "onions" "rutabagas"
do
echo
echo "Your favorite veggie is $vegetable."
echo "Yuck!"
echo
break
# if no 'break' here, keeps looping forever.
done
exit 0

View File

@ -0,0 +1,24 @@
#!/bin/bash
PS3='Choose your favorite vegetable: '
echo
choice_of()
{
select vegetable
# [in list] omitted, so 'select' uses arguments passed to function.
do
echo
echo "Your favorite veggie is $vegetable."
echo "Yuck!"
echo
break
done
}
choice_of beans rice carrots radishes tomatoes spinach
# $1 $2 $3 $4 $5 $6
# passed to choice_of() function
exit 0

View File

@ -0,0 +1,46 @@
#!/bin/bash
# 'getopts' processes command line arguments to script.
# The arguments are parsed as "options" (flags) and associated arguments.
# Usage: scriptname -options
# Note: dash (-) necessary
# Try invoking this script with
# 'scriptname -mn'
# 'scriptname -oq qOption' (qOption can be some arbitrary string.)
# 'scriptname -qXXX -r'
#
# 'scriptname -qr' - Unexpected result, takes "r" as the argument to option "q"
# 'scriptname -q -r' - Unexpected result, same as above
# If an option expects an argument ("flag:"), then it will grab
# whatever is next on the command line.
NO_ARGS=0
OPTERROR=65
if [ $# -eq "$NO_ARGS" ] # Script invoked with no command-line args?
then
echo "Usage: `basename $0` options (-mnopqrs)"
exit $OPTERROR # Exit and explain usage, if no argument(s) given.
fi
while getopts ":mnopq:rs" Option
do
case $Option in
m ) echo "Scenario #1: option -m-";;
n | o ) echo "Scenario #2: option -$Option-";;
p ) echo "Scenario #3: option -p-";;
q ) echo "Scenario #4: option -q-, with argument \"$OPTARG\"";;
# Note that option 'q' must have an associated argument,
# otherwise it falls through to the default.
r | s ) echo "Scenario #5: option -$Option-"'';;
* ) echo "Unimplemented option chosen.";; # DEFAULT
esac
done
shift $(($OPTIND - 1))
# Decrements the argument pointer
# so it points to next argument.
exit 0

View File

@ -0,0 +1,27 @@
#!/bin/bash
# script "set-test"
# Invoke this script with three command line parameters,
# for example, "./set-test one two three".
echo
echo "Positional parameters before set \`uname -a\` :"
echo "Command-line argument #1 = $1"
echo "Command-line argument #2 = $2"
echo "Command-line argument #3 = $3"
echo
set `uname -a`
# Sets the positional parameters to the output
# of the command `uname -a`
echo "Positional parameters after set \`uname -a\` :"
# $1, $2, $3, etc. reinitialized to result of `uname -a`
echo "Field #1 of 'uname -a' = $1"
echo "Field #2 of 'uname -a' = $2"
echo "Field #3 of 'uname -a' = $3"
echo
exit 0

View File

@ -0,0 +1,8 @@
#!/bin/bash
a=/home/heraclius/daily-journal.txt
echo "Basename of /home/heraclius/daily-journal.txt = `basename $a`"
echo "Dirname of /home/heraclius/daily-journal.txt = `dirname $a`"
exit 0

View File

@ -0,0 +1,21 @@
#!/bin/bash
echo -n "Enter the value of variable 'var1': "
# -n option to echo suppresses newline
read var1
# Note no '$' in front of var1, since it is being set.
echo "var1 = $var1"
# Note that a single 'read' statement can set multiple variables.
echo
echo -n "Enter the values of variables 'var2' and 'var3' (separated by a space or tab): "
read var2 var3
echo "var2 = $var2 var3 = $var3"
# If you input only one value, the other variable(s) will remain unset (null).
exit 0

View File

@ -0,0 +1,22 @@
#!/bin/bash
dir1=/usr/local
dir2=/var/spool
pushd $dir1
# Will do an automatic 'dirs'
# (list directory stack to stdout).
echo "Now in directory `pwd`."
# Uses back-quoted 'pwd'.
# Now, do some stuff in directory 'dir1'.
pushd $dir2
echo "Now in directory `pwd`."
# Now, do some stuff in directory 'dir2'.
echo "The top entry in the DIRSTACK array is $DIRSTACK."
popd
echo "Now back in directory `pwd`."
# Now, do some more stuff in directory 'dir1'.
popd
echo "Now back in original working directory `pwd`."
exit 0

View File

@ -0,0 +1,23 @@
#!/bin/bash
# Load a data file.
. data-file
# Same effect as "source data-file", but more portable.
# Note that the file "data-file", given below
# must be present in working directory.
# Now, reference some data from that file.
echo "variable1 (from data-file) = $variable1"
echo "variable3 (from data-file) = $variable3"
let "sum = $variable2 + $variable4"
echo "Sum of variable2 + variable4 (from data-file) = $sum"
echo "message1 (from data-file) is \"$message1\""
# Note: escaped quotes
print_message This is the message-print function in the data-file.
exit 0

View File

@ -0,0 +1,24 @@
#!/bin/bash
if [ -z "$1" ]
then
echo "Usage: `basename $0` find-string"
exit 65
fi
echo "Updating 'locate' database..."
echo "This may take a while."
updatedb /usr &
# Must be run as root.
wait
# Don't run the rest of the script until 'updatedb' finished.
# You want the the database updated before looking up the file name.
locate $1
# Lacking the wait command, in the worse case scenario,
# the script would exit while 'updatedb' was still running,
# leaving it as an orphan process.
exit 0

View File

@ -0,0 +1,39 @@
#!/bin/bash
# "subst", a script that substitutes one pattern for
# another in a file,
# i.e., "subst Smith Jones letter.txt".
ARGS=3
E_BADARGS=65 # Wrong number of arguments passed to script.
if [ $# -ne "$ARGS" ]
# Test number of arguments to script
# (always a good idea).
then
echo "Usage: `basename $0` old-pattern new-pattern filename"
exit $E_BADARGS
fi
old_pattern=$1
new_pattern=$2
if [ -f "$3" ]
then
file_name=$3
else
echo "File \"$3\" does not exist."
exit $E_BADARGS
fi
# Here is where the heavy work gets done.
sed -e "s/$old_pattern/$new_pattern/g" $file_name
# 's' is, of course, the substitute command in sed,
# and /pattern/ invokes address matching.
# The "g", or global flag causes substitution for *every*
# occurence of $old_pattern on each line, not just the first.
# Read the literature on 'sed' for a more
# in-depth explanation.
exit 0
# Successful invocation of the script returns 0.

View File

@ -0,0 +1,37 @@
#!/bin/bash
SPEED=2 # May use higher speed if supported.
IMAGEFILE=cdimage.iso
CONTENTSFILE=contents
DEFAULTDIR=/opt
# Script to automate burning a CDR.
# Uses Joerg Schilling's "cdrecord" package.
# (http://www.fokus.gmd.de/nthp/employees/schilling/cdrecord.html)
# If this script invoked as an ordinary user, need to suid cdrecord
# (chmod u+s /usr/bin/cdrecord, as root).
if [ -z "$1" ]
then
IMAGE_DIRECTORY=$DEFAULTDIR
# Default directory, if not specified on command line.
else
IMAGE_DIRECTORY=$1
fi
ls -lRF $IMAGE_DIRECTORY > $IMAGE_DIRECTORY/$CONTENTSFILE
# The "l" option gives a "long" file listing.
# The "R" option makes the listing recursive.
# The "F" option marks the file types (directories suffixed by a /).
echo "Creating table of contents."
mkisofs -r -o $IMAGFILE $IMAGE_DIRECTORY
echo "Creating ISO9660 file system image ($IMAGEFILE)."
cdrecord -v -isosize speed=$SPEED dev=0,0 $IMAGEFILE
echo "Burning the disk."
echo "Please be patient, this will take a while."
exit 0

View File

@ -0,0 +1,16 @@
#!/bin/bash
# Generates a log file in current directory
# from the tail end of /var/log/messages.
# Note: /var/log/messages must be readable by ordinary users
# if invoked by same (#root chmod 755 /var/log/messages).
( date; uname -a ) >>logfile
# Time and machine name
echo --------------------------------------------------------------------- >>logfile
tail -5 /var/log/messages | xargs | fmt -s >>logfile
echo >>logfile
echo >>logfile
exit 0

View File

@ -0,0 +1,18 @@
#!/bin/bash
# Copy (verbose) all files in current directory
# to directory specified on command line.
if [ -z "$1" ]
# Exit if no argument given.
then
echo "Usage: `basename $0` directory-to-copy-to"
exit 65
fi
ls . | xargs -i -t cp ./{} $1
# This is the exact equivalent of
# cp * $1
# unless any of the filenames has "whitespace" characters.
exit 0

View File

@ -0,0 +1,12 @@
#!/bin/bash
y=`eval ls -l` # Similar to y=`ls -l`
echo $y # but linefeeds removed.
y=`eval df` # Similar to y=`df`
echo $y # but linefeeds removed.
# Note that LF's not preserved,
# and this may make it easier to parse output.
exit 0

View File

@ -0,0 +1,22 @@
#!/bin/bash
y=`eval ps ax | sed -n '/ppp/p' | awk '{ print $1 }'`
# Finding the process number of 'ppp'
kill -9 $y
# Killing it
# Above lines may be replaced by
# kill -9 `ps ax | awk '/ppp/ { print $1 }'
# Restore to previous state...
chmod 666 /dev/ttyS3
# Doing a SIGKILL on ppp changes the permissions
# on the serial port. Must be restored.
rm /var/lock/LCK..ttyS3
# Remove the serial port lock file.
exit 0

View File

@ -0,0 +1,93 @@
#!/bin/bash
# Demonstrating some of the uses of 'expr'
# +++++++++++++++++++++++++++++++++++++++
echo
# Arithmetic Operators
echo "Arithmetic Operators"
echo
a=`expr 5 + 3`
echo "5 + 3 = $a"
a=`expr $a + 1`
echo
echo "a + 1 = $a"
echo "(incrementing a variable)"
a=`expr 5 % 3`
# modulo
echo
echo "5 mod 3 = $a"
echo
echo
# Logical Operators
echo "Logical Operators"
echo
a=3
echo "a = $a"
b=`expr $a \> 10`
echo 'b=`expr $a \> 10`, therefore...'
echo "If a > 10, b = 0 (false)"
echo "b = $b"
b=`expr $a \< 10`
echo "If a < 10, b = 1 (true)"
echo "b = $b"
echo
echo
# Comparison Operators
echo "Comparison Operators"
echo
a=zipper
echo "a is $a"
if [ `expr $a = snap` ]
# Force re-evaluation of variable 'a'
then
echo "a is not zipper"
fi
echo
echo
# String Operators
echo "String Operators"
echo
a=1234zipper43231
echo "The string being operated upon is \"$a\"."
# index: position of substring
b=`expr index $a 23`
echo "Numerical position of first \"23\" in \"$a\" is \"$b\"."
# substr: print substring, starting position & length specified
b=`expr substr $a 2 6`
echo "Substring of \"$a\", starting at position 2, and 6 chars long is \"$b\"."
# length: length of string
b=`expr length $a`
echo "Length of \"$a\" is $b."
# 'match' operations similarly to 'grep'
b=`expr match "$a" '[0-9]*'`
echo Number of digits at the beginning of \"$a\" is $b.
b=`expr match "$a" '\([0-9]*\)'`
echo "The digits at the beginning of \"$a\" are \"$b\"."
echo
exit 0

View File

@ -0,0 +1,26 @@
#!/bin/bash
echo
let a=11
# Same as 'a=11'
let a=a+5
# Equivalent to let "a = a + 5"
# (double quotes makes it more readable)
echo "a = $a"
let "a <<= 3"
# Equivalent of let "a = a << 3"
echo "a left-shifted 3 places = $a"
let "a /= 4"
# Equivalent to let "a = a / 4"
echo $a
let "a -= 5"
# Equivalent to let "a = a - 5"
echo $a
let "a = a * 10"
echo $a
let "a %= 8"
echo $a
exit 0

View File

@ -0,0 +1,27 @@
#!/bin/bash
# printf demo
PI=3.14159265358979
DecimalConstant=31373
Message1="Greetings,"
Message2="Earthling."
echo
printf "Pi to 2 decimal places = %1.2f" $PI
echo
printf "Pi to 9 decimal places = %1.9f" $PI
# Note correct round off.
printf "\n"
# Prints a line feed, equivalent to 'echo'.
printf "Constant = \t%d\n" $DecimalConstant
# Insert tab (\t)
printf "%s %s \n" $Message1 $Message2
echo
exit 0

View File

@ -0,0 +1,18 @@
#!/bin/bash
# Copying a directory tree using cpio.
ARGS=2
if [ $# -ne "$ARGS" ]
then
echo Usage: `basename $0` source destination
exit 65
fi
source=$1
destination=$2
find "$source" -depth | cpio -admvp "$destination"
exit 0

View File

@ -0,0 +1,19 @@
#!/bin/bash
# Changes a file to all uppercase.
E_BADARGS=65
if [ -z "$1" ]
# Standard check whether command line arg is present.
then
echo "Usage: `basename $0` filename"
exit $E_BADARGS
fi
tr a-z A-Z <"$1"
# Same effect as above, but using character set notation:
# tr '[:lower:]' '[:upper:]' <"$1"
# Thanks, S.C.
exit 0

View File

@ -0,0 +1,20 @@
#!/bin/bash
echo hello
echo $?
# exit status 0 returned
# because command successful.
lskdf
# bad command
echo $?
# non-zero exit status returned.
echo
exit 113
# Will return 113 to shell.
# To verify this, type "echo $?" after script terminates.
# By convention, an 'exit 0' shows success,
# while a non-zero exit value indicates an error or anomalous condition.

View File

@ -0,0 +1,13 @@
#!/bin/bash
# Get a file listing...
b=`ls /usr/local/bin`
# ...40 columns wide.
echo $b | fmt -w 40
# Could also have been done by
# echo $b | fold - -s -w 40
exit 0

View File

@ -0,0 +1,24 @@
#!/bin/bash
#Using the 'date' command
# Needs a leading '+' to invoke formatting.
echo "The number of days since the year's beginning is `date +%j`."
# %j gives day of year.
echo "The number of seconds elapsed since 01/01/1970 is `date +%s`."
# %s yields number of seconds since "UNIX epoch" began,
# but how is this useful?
prefix=temp
suffix=`eval date +%s`
filename=$prefix.$suffix
echo $filename
# It's great for creating "unique" temp filenames,
# even better than using $$.
# Read the 'date' man page for more formatting options.
exit 0

View File

@ -0,0 +1,26 @@
#!/bin/bash
lines=35
# Allow 35 lines for the header (very generous).
for File in *
# Test all the files in the current working directory...
do
search1=`head -$lines $File | grep begin | wc -w`
search2=`tail -$lines $File | grep end | wc -w`
# Uuencoded files have a "begin" near the beginning, and an "end" near the end.
if [ "$search1" -gt 0 ]
then
if [ "$search2" -gt 0 ]
then
echo "uudecoding - $File -"
uudecode $File
fi
fi
done
# Note that running this script upon itself fools it
# into thinking it is a uuencoded file,
# because it contains both "begin" and "end".
exit 0

View File

@ -0,0 +1,25 @@
#!/bin/bash
for a in `seq 80` # or for a in $( seq 80 )
# Same as for a in 1 2 3 4 5 ... 80 (saves much typing!).
# May also use 'jot' (if present on system).
do
echo -n "$a "
done
# Example of using the output of a command to generate
# the [list] in a "for" loop.
echo; echo
# Yes, "seq" may also take a replaceable parameter.
COUNT=80
for a in `seq $COUNT` # or for a in $( seq $COUNT )
do
echo -n "$a "
done
echo
exit 0

View File

@ -0,0 +1,9 @@
#!/bin/bash
exec echo "Exiting \"$0\"."
# Exit from script.
# The following lines never execute.
echo "This will never echo."
exit 0

View File

@ -0,0 +1,40 @@
#!/bin/sh
# --> Comments added by the author of this document marked by "-->".
# --> This is part of the 'rc' script package
# --> by Miquel van Smoorenburg, &lt;miquels@drinkel.nl.mugnet.org>
# --> This particular script seems to be Red Hat specific
# --> (may not be present in other distributions).
# Bring down all unneeded services that are still running (there shouldn't
# be any, so this is just a sanity check)
for i in /var/lock/subsys/*; do
# --> Standard for/in loop, but since "do" is on same line,
# --> it is necessary to add ";".
# Check if the script is there.
[ ! -f $i ] && continue
# --> This is a clever use of an "and list", equivalent to:
# --> if [ ! -f "$i" ]; then continue
# Get the subsystem name.
subsys=${i#/var/lock/subsys/}
# --> Match variable name, which, in this case, is the file name.
# --> This is the exact equivalent of subsys=`basename $i`.
# --> It gets it from the lock file name, and since if there
# --> is a lock file, that's proof the process has been running.
# --> See the "lockfile" entry, above.
# Bring the subsystem down.
if [ -f /etc/rc.d/init.d/$subsys.init ]; then
/etc/rc.d/init.d/$subsys.init stop
else
/etc/rc.d/init.d/$subsys stop
# --> Suspend running jobs and daemons
# --> using the 'stop' shell builtin.
fi
done

View File

@ -0,0 +1,10 @@
#!/bin/bash
# Some shell commands may precede the Perl script.
perl -e 'print "This is an embedded Perl script\n"'
# Like sed and awk, Perl also uses the "-e" option.
# Some shell commands may follow.
exit 0

View File

@ -0,0 +1,27 @@
#!/bin/bash
# Delete filenames in current directory containing bad characters.
for filename in *
do
badname=`echo "$filename" | sed -n /[\+\{\;\"\\\=\?~\(\)\<\>\&\*\|\$]/p`
# Files containing those nasties: + { ; " \ = ? ~ ( ) < > & * | $
rm $badname 2>/dev/null
# So error messages deep-sixed.
done
# Now, take care of files containing all manner of whitespace.
find . -name "* *" -exec rm -f {} \;
# The path name of the file that "find" finds replaces the "{}".
# The '\' ensures that the ';' is interpreted literally, as end of command.
exit 0
#---------------------------------------------------------------------
# Commands below this line will not execute because of "exit" command.
# An alternative to the above script:
find . -name '*[+{;"\\=?~()&lt;&gt;&*|$ ]*' -exec rm -f '{}' \;
exit 0
# (Thanks, S.C.)

View File

@ -0,0 +1,30 @@
#!/bin/bash
# Backs up all files in current directory
# modified within last 24 hours
# in a tarred and gzipped file.
if [ $# = 0 ]
then
echo "Usage: `basename $0` filename"
exit 65
fi
tar cvf - `find . -mtime -1 -type f -print` > $1.tar
gzip $1.tar
# Stephane Chazelas points out that the above code will fail
# if there are too many files found
# or if any filenames contain blank characters.
# He suggests the following alternatives:
# -------------------------------------------------------------
# find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$1.tar"
# using the GNU version of "find".
# find . -mtime -1 -type f -exec tar rvf "$1.tar" '{}' \;
# portable to other UNIX flavors, but much slower.
exit 0

View File

@ -0,0 +1,15 @@
#!/bin/bash
funky ()
{
echo This is a funky function.
echo Now exiting funky function.
}
# Note: function must precede call.
# Now, call the function.
funky
exit 0

View File

@ -0,0 +1,50 @@
#!/bin/bash
# Let's check some of the system's environmental variables.
# If, for example, $USER, the name of the person at the console, is not set,
# the machine will not recognize you.
: ${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?}
echo
echo "Name of the machine is $HOSTNAME."
echo "You are $USER."
echo "Your home directory is $HOME."
echo "Your mail INBOX is located in $MAIL."
echo
echo "If you are reading this message,"
echo "critical environmental variables have been set."
echo
echo
# ------------------------------------------------------
# The ${variablename?} construction can also check
# for variables set within the script.
ThisVariable=Value-of-ThisVariable
# Note, by the way, that string variables may be set
# to characters disallowed in their names.
: ${ThisVariable?}
echo "Value of ThisVariable is $ThisVariable".
echo
echo
: ${ZZXy23AB?"ZZXy23AB has not been set."}
# If ZZXy23AB has not been set, then the script terminates with an error message.
# You can specify the error message.
# : ${ZZXy23AB?"ZZXy23AB has not been set."}
# Same result with: dummy_variable=${ZZXy23AB?}
# dummy_variable=${ZZXy23AB?"ZXy23AB has not been set."}
#
# echo ${ZZXy23AB?} >/dev/null
echo "You will not see this message, because script terminated above."
HERE=0
exit $HERE # Will *not* exit here.

View File

@ -0,0 +1,47 @@
#!/bin/bash
func2 () {
if [ -z "$1" ]
# Checks if parameter #1 is zero length.
then
echo "-Parameter #1 is zero length.-" # Also if no parameter is passed.
else
echo "-Param #1 is \"$1\".-"
fi
if [ "$2" ]
then
echo "-Parameter #2 is \"$2\".-"
fi
return 0
}
echo
echo "Nothing passed."
func2 # Called with no params
echo
echo "Zero-length parameter passed."
func2 "" # Called with zero-length param
echo
echo "Null parameter passed."
func2 "$uninitialized_param" # Called with uninitialized param
echo
echo "One parameter passed."
func2 first # Called with one param
echo
echo "Two parameter passed."
func2 first second # Called with two params
echo
echo "\"\" \"second\" passed."
func2 "" second # Called with zero-length first parameter
echo # and ASCII string as a second one.
exit 0

View File

@ -0,0 +1,67 @@
#!/bin/bash
# Arabic number to Roman numeral conversion
# Range 0 - 200
# It's crude, but it works.
# Extending the range and otherwise improving the script
# is left as an exercise for the reader.
# Usage: roman number-to-convert
ARG_ERR=65
LIMIT=200
if [ -z "$1" ]
then
echo "Usage: `basename $0` number-to-convert"
exit $ARG_ERR
fi
num=$1
if [ "$num" -gt $LIMIT ]
then
echo "Out of range!"
exit $OUT_OF_RANGE
fi
to_roman ()
{
number=$1
factor=$2
rchar=$3
let "remainder = number - factor"
while [ "$remainder" -ge 0 ]
do
echo -n $rchar
let "number -= factor"
let "remainder = number - factor"
done
return $number
}
# Note: must declare function
# before first call to it.
to_roman $num 100 C
num=$?
to_roman $num 90 LXXXX
num=$?
to_roman $num 50 L
num=$?
to_roman $num 40 XL
num=$?
to_roman $num 10 X
num=$?
to_roman $num 9 IX
num=$?
to_roman $num 5 V
num=$?
to_roman $num 4 IV
num=$?
to_roman $num 1 I
echo
exit 0

View File

@ -0,0 +1,20 @@
#!/bin/bash
func ()
{
local a=23
echo
echo "a in function is $a"
echo
}
func
# Now, see if local 'a'
# exists outside function.
echo "a outside function is $a"
echo
# Nope, 'a' not visible globally.
exit 0

View File

@ -0,0 +1,50 @@
#!/bin/bash
# factorial
# ---------
# Does bash permit recursion?
# Well, yes, but...
# You gotta have rocks in your head to try it.
MAX_ARG=5
WRONG_ARGS=65
RANGE_ERR=66
if [ -z "$1" ]
then
echo "Usage: `basename $0` number"
exit $WRONG_ARGS
fi
if [ "$1" -gt $MAX_ARG ]
then
echo "Out of range (5 is maximum)."
# Let's get real now...
# If you want greater range than this, rewrite it in a real programming language.
exit $RANGE_ERR
fi
fact ()
{
local number=$1
# Variable "number" must be declared as local otherwise this doesn't work.
if [ "$number" -eq 0 ]
then
factorial=1
else
let "decrnum = number - 1"
fact $decrnum # Recursive function call.
let "factorial = $number * $?"
fi
return $factorial
}
fact $1
echo "Factorial of $1 is $?."
exit 0

View File

@ -0,0 +1,34 @@
#!/bin/bash
# "and list"
if [ ! -z "$1" ] && echo "Argument #1 = $1" && [ ! -z "$2" ] && echo "Argument #2 = $2"
then
echo "At least 2 arguments to script."
# All the chained commands return true.
else
echo "Less than 2 arguments to script."
# At least one of the chained commands returns false.
fi
# Note that "if [ ! -z $1 ]" works, but its supposed equivalent,
# if [ -n $1 ] does not. However, quoting fixes this.
# if [ -n "$1" ] works. Careful!
# It is best to always quote tested variables.
# This accomplishes the same thing, coded using "pure" if/then statements.
if [ ! -z "$1" ]
then
echo "Argument #1 = $1"
fi
if [ ! -z "$2" ]
then
echo "Argument #2 = $2"
echo "At least 2 arguments to script."
else
echo "Less than 2 arguments to script."
fi
# It's longer and less elegant than using an "and list".
exit 0

View File

@ -0,0 +1,28 @@
#!/bin/bash
# "Delete", not-so-cunning file deletion utility.
# Usage: delete filename
if [ -z "$1" ]
then
file=nothing
else
file=$1
fi
# Fetch file name (or "nothing") for deletion message.
[ ! -f "$1" ] && echo "$1 not found. Can't delete a nonexistent file."
# AND LIST, to give error message if file not present.
[ ! -f "$1" ] || ( rm -f $1; echo "$file deleted." )
# OR LIST, to delete file if present.
# ( command1 ; command2 ) is, in effect, an AND LIST variant.
# Note logic inversion above.
# AND LIST executes on true, OR LIST on false.
[ ! -z "$1" ] || echo "Usage: `basename $0` filename"
# OR LIST, to give error message if no command line arg (file name).
exit 0

View File

@ -0,0 +1,81 @@
#!/bin/bash
area[11]=23
area[13]=37
area[51]=UFOs
# Note that array members need not be consecutive
# or contiguous.
# Some members of the array can be left uninitialized.
# Gaps in the array are o.k.
echo -n "area[11] = "
echo ${area[11]}
echo -n "area[13] = "
echo ${area[13]}
# Note that {curly brackets} needed
echo "Contents of area[51] are ${area[51]}."
# Contents of uninitialized array variable print blank.
echo -n "area[43] = "
echo ${area[43]}
echo "(area[43] unassigned)"
echo
# Sum of two array variables assigned to third
area[5]=`expr ${area[11]} + ${area[13]}`
echo "area[5] = area[11] + area[13]"
echo -n "area[5] = "
echo ${area[5]}
area[6]=`expr ${area[11]} + ${area[51]}`
echo "area[6] = area[11] + area[51]"
echo -n "area[6] = "
echo ${area[6]}
# This doesn't work because
# adding an integer to a string is not permitted.
echo
echo
echo
# -----------------------------------------------------------------
# Another array, "area2".
# Another way of assigning array variables...
# array_name=( XXX YYY ZZZ ... )
area2=( zero one two three four )
echo -n "area2[0] = "
echo ${area2[0]}
# Aha, zero-based indexing (first element of array is [0], not [1]).
echo -n "area2[1] = "
echo ${area2[1]} # [1] is second element of array.
# -----------------------------------------------------------------
echo
echo
echo
# -----------------------------------------------
# Yet another array, "area3".
# Yet another way of assigning array variables...
# array_name=([xx]=XXX [yy]=YYY ...)
area3=([17]=seventeen [24]=twenty-four)
echo -n "area3[17] = "
echo ${area3[17]}
echo -n "area3[24] = "
echo ${area3[24]}
# -----------------------------------------------
exit 0

Some files were not shown because too many files have changed in this diff Show More