commit bash-20060316 snapshot

This commit is contained in:
Chet Ramey
2011-12-07 09:05:27 -05:00
parent 97be3d8ed9
commit 28157acd2d
1546 changed files with 713954 additions and 55608 deletions
@@ -0,0 +1,103 @@
# usage: reverse arrayname
reverse()
{
local -a R
local -i i
local rlen temp
# make r a copy of the array whose name is passed as an arg
eval R=\( \"\$\{$1\[@\]\}\" \)
# reverse R
rlen=${#R[@]}
for ((i=0; i < rlen/2; i++ ))
do
temp=${R[i]}
R[i]=${R[rlen-i-1]}
R[rlen-i-1]=$temp
done
# and assign R back to array whose name is passed as an arg
eval $1=\( \"\$\{R\[@\]\}\" \)
}
A=(1 2 3 4 5 6 7)
echo "${A[@]}"
reverse A
echo "${A[@]}"
reverse A
echo "${A[@]}"
# unset last element of A
alen=${#A[@]}
unset A[$alen-1]
echo "${A[@]}"
# ashift -- like shift, but for arrays
ashift()
{
local -a R
local n
case $# in
1) n=1 ;;
2) n=$2 ;;
*) echo "$FUNCNAME: usage: $FUNCNAME array [count]" >&2
exit 2;;
esac
# make r a copy of the array whose name is passed as an arg
eval R=\( \"\$\{$1\[@\]\}\" \)
# shift R
R=( "${R[@]:$n}" )
# and assign R back to array whose name is passed as an arg
eval $1=\( \"\$\{R\[@\]\}\" \)
}
ashift A 2
echo "${A[@]}"
ashift A
echo "${A[@]}"
ashift A 7
echo "${A[@]}"
# Sort the members of the array whose name is passed as the first non-option
# arg. If -u is the first arg, remove duplicate array members.
array_sort()
{
local -a R
local u
case "$1" in
-u) u=-u ; shift ;;
esac
if [ $# -eq 0 ]; then
echo "array_sort: argument expected" >&2
return 1
fi
# make r a copy of the array whose name is passed as an arg
eval R=\( \"\$\{$1\[@\]\}\" \)
# sort R
R=( $( printf "%s\n" "${A[@]}" | sort $u) )
# and assign R back to array whose name is passed as an arg
eval $1=\( \"\$\{R\[@\]\}\" \)
return 0
}
A=(3 1 4 1 5 9 2 6 5 3 2)
array_sort A
echo "${A[@]}"
A=(3 1 4 1 5 9 2 6 5 3 2)
array_sort -u A
echo "${A[@]}"
@@ -0,0 +1,15 @@
#! /bin/bash
# Format: array_to_string vname_of_array vname_of_string separator
array_to_string()
{
(( ($# < 2) || ($# > 3) )) && {
"$FUNCNAME: usage: $FUNCNAME arrayname stringname [separator]"
return 2
}
local array=$1 string=$2
((3==$#)) && [[ $3 = ? ]] && local IFS="${3}${IFS}"
eval $string="\"\${$array[*]}\""
return 0
}
+111
View File
@@ -0,0 +1,111 @@
#
# An almost ksh-compatible `autoload'. A function declared as `autoload' will
# be read in from a file the same name as the function found by searching the
# $FPATH (which works the same as $PATH), then that definition will be run.
#
# To do this without source support, we define a dummy function that, when
# executed, will load the file (thereby re-defining the function), then
# execute that newly-redefined function with the original arguments.
#
# It's not identical to ksh because ksh apparently does lazy evaluation
# and looks for the file to load from only when the function is referenced.
# This one requires that the file exist when the function is declared as
# `autoload'.
#
# usage: autoload func [func...]
#
# The first cut of this was by Bill Trost, trost@reed.bitnet
#
# Chet Ramey
# chet@ins.CWRU.Edu
#
# Declare a function ($1) to be autoloaded from a file ($2) when it is first
# called. This defines a `temporary' function that will `.' the file
# containg the real function definition, then execute that new definition with
# the arguments given to this `fake' function. The autoload function defined
# by the file and the file itself *must* be named identically.
#
aload()
{
eval $1 '() { . '$2' ; '$1' "$@" ; return $? ; }'
}
#
# Search $FPATH for a file the same name as the function given as $1, and
# autoload the function from that file. There is no default $FPATH.
#
autoload()
{
#
# Save the list of functions; we're going to blow away the arguments
# in a second. If any of the names contain white space, TFB.
#
local args="$*"
#
# This should, I think, list the functions marked as autoload and not
# yet defined, but we don't have enough information to do that here.
#
if [ $# -eq 0 ] ; then
echo "usage: autoload function [function...]" >&2
return 1
fi
#
# If there is no $FPATH, there is no work to be done
#
if [ -z "$FPATH" ] ; then
echo autoload: FPATH not set or null >&2
return 1
fi
#
# This treats FPATH exactly like PATH: a null field anywhere in the
# FPATH is treated the same as the current directory.
#
# The path splitting command is taken from Kernighan and Pike
#
# fp=$(echo $FPATH | sed 's/^:/.:/
# s/::/:.:/g
# s/:$/:./
# s/:/ /g')
# replaced with builtin mechanisms 2001 Oct 10
fp=${FPATH/#:/.:}
fp=${fp//::/:.:}
fp=${fp/%:/:.}
fp=${fp//:/ }
for FUNC in $args ; do
#
# We're blowing away the arguments to autoload here...
# We have to; there are no arrays (well, there are, but
# this doesn't use them yet).
#
set -- $fp
while [ $# -ne 0 ] ; do
if [ -f $1/$FUNC ] ; then
break # found it!
fi
shift
done
if [ $# -eq 0 ] ; then
echo "$FUNC: autoload function not found" >&2
continue
fi
# echo auto-loading $FUNC from $1/$FUNC
aload $FUNC $1/$FUNC
done
return 0
}
@@ -0,0 +1,192 @@
#
# An almost ksh-compatible `autoload'. A function declared as `autoload' will
# be read in from a file the same name as the function found by searching the
# $FPATH (which works the same as $PATH), then that definition will be run.
#
# To do this without source support, we define a dummy function that, when
# executed, will load the file (thereby re-defining the function), then
# execute that newly-redefined function with the original arguments.
#
# It's not identical to ksh because ksh apparently does lazy evaluation
# and looks for the file to load from only when the function is referenced.
# This one requires that the file exist when the function is declared as
# `autoload'.
#
# usage: autoload [-pu] [func ...]
#
# options:
# -p print in a format that can be reused as input
# -u unset each function and remove it from the autoload list
#
# The first cut of this was by Bill Trost, trost@reed.edu
#
# Chet Ramey
# chet@ins.CWRU.Edu
unset _AUTOLOADS
_aindex=0
#
# Declare a function ($1) to be autoloaded from a file ($2) when it is first
# called. This defines a `temporary' function that will `.' the file
# containg the real function definition, then execute that new definition with
# the arguments given to this `fake' function. The autoload function defined
# by the file and the file itself *must* be named identically.
#
_aload()
{
eval $1 '() { . '$2' ; '$1' "$@" ; return $? ; }'
_autoload_addlist "$1"
}
_autoload_addlist()
{
local i=0
while (( i < $_aindex )); do
case "${_AUTOLOADS[i]}" in
"$1") return 1 ;;
esac
(( i += 1 ))
done
_AUTOLOADS[_aindex]="$1"
(( _aindex += 1 ))
return 0
}
_autoload_dump()
{
local func
for func in ${_AUTOLOADS[@]}; do
[ -n "$1" ] && echo -n "autoload "
echo "$func"
done
}
# Remove $1 from the list of autoloaded functions
_autoload_remove_one()
{
local i=0 nnl=0
local -a nlist
while (( i < _aindex )); do
case "${_AUTOLOADS[i]}" in
"$1") ;;
*) nlist[nnl]="${_AUTOLOADS[i]}" ; (( nnl += 1 ));;
esac
(( i += 1 ))
done
unset _AUTOLOADS _aindex
eval _AUTOLOADS=( ${nlist[@]} )
_aindex=$nnl
}
# Remove all function arguments from the list of autoloaded functions
_autoload_remove()
{
local func i es=0
# first unset the autoloaded functions
for func; do
i=0
while (( i < _aindex )); do
case "${_AUTOLOADS[i]}" in
"$func") unset -f $func ; break ;;
esac
(( i += 1 ))
done
if (( i == _aindex )); then
echo "autoload: $func: not an autoloaded function" >&2
es=1
fi
done
# then rebuild the list of autoloaded functions
for func ; do
_autoload_remove_one "$func"
done
return $es
}
#
# Search $FPATH for a file the same name as the function given as $1, and
# autoload the function from that file. There is no default $FPATH.
#
autoload()
{
local -a fp
local _autoload_unset nfp i
if (( $# == 0 )) ; then
_autoload_dump
return 0
fi
OPTIND=1
while getopts pu opt
do
case "$opt" in
p) _autoload_dump printable; return 0;;
u) _autoload_unset=y ;;
*) echo "autoload: usage: autoload [-pu] [function ...]" >&2
return 1 ;;
esac
done
shift $(( $OPTIND - 1 ))
if [ -n "$_autoload_unset" ]; then
_autoload_remove "$@"
return $?
fi
#
# If there is no $FPATH, there is no work to be done
#
if [ -z "$FPATH" ] ; then
echo "autoload: FPATH not set or null" >&2
return 1
fi
#
# This treats FPATH exactly like PATH: a null field anywhere in the
# FPATH is treated the same as the current directory.
#
# This turns $FPATH into an array, substituting `.' for `'
#
eval fp=( $(
IFS=':'
set -- ${FPATH}
for p in "$@" ; do echo -n "${p:-.} "; done
)
)
nfp=${#fp[@]}
for FUNC ; do
i=0;
while (( i < nfp )) ; do
if [ -f ${fp[i]}/$FUNC ] ; then
break # found it!
fi
(( i += 1 ))
done
if (( i == nfp )) ; then
echo "autoload: $FUNC: autoload function not found" >&2
es=1
continue
fi
# echo auto-loading $FUNC from ${fp[i]}/$FUNC
_aload $FUNC ${fp[i]}/$FUNC
es=0
done
return $es
}
@@ -0,0 +1,125 @@
#From: Mark Kennedy <mtk@ny.ubs.com>
#Message-ID: <35E2B899.63A02DF5@ny.ubs.com>
#Date: Tue, 25 Aug 1998 09:14:01 -0400
#To: chet@nike.ins.cwru.edu
#Subject: a newer version of the ksh-style 'autoload'
#enclosed you'll find 'autoload.v3', a version of the autoloader
#that emulates the ksh semantics of delaying the resolution (and loading) of the function
#until its first use. i took the liberty of simplifying the code a bit although it still uses the
#same functional breakdown. i recently went through the exercise of converting
#my ksh-based environment to bash (a very, very pleasant experience)
#and this popped out.
# the psuedo-ksh autoloader.
# The first cut of this was by Bill Trost, trost@reed.bitnet.
# The second cut came from Chet Ramey, chet@ins.CWRU.Edu
# The third cut came from Mark Kennedy, mtk@ny.ubs.com. 1998/08/25
unset _AUTOLOADS
_aload()
{
local func
for func; do
eval $func '()
{
local f=$(_autoload_resolve '$func')
if [[ $f ]]; then
. $f
'$func' "$@"
return $?
else
return 1
fi
}'
_autoload_addlist $func
done
}
_autoload_addlist()
{
local func
for func in ${_AUTOLOADS[@]}; do
[[ $func = "$1" ]] && return
done
_AUTOLOADS[${#_AUTOLOADS[@]}]=$1
}
_autoload_dump()
{
local func
for func in ${_AUTOLOADS[@]}; do
[[ $1 ]] && echo -n "autoload "
echo $func
done
}
_autoload_remove_one()
{
local func
local -a NEW_AUTOLOADS
for func in ${_AUTOLOADS[@]}; do
[[ $func != "$1" ]] && NEW_AUTOLOADS[${#NEW_AUTOLOADS[@]}]=$func
done
_AUTOLOADS=( ${NEW_AUTOLOADS[@]} )
}
_autoload_remove()
{
local victim func
for victim; do
for func in ${_AUTOLOADS[@]}; do
[[ $victim = "$func" ]] && unset -f $func && continue 2
done
echo "autoload: $func: not an autoloaded function" >&2
done
for func; do
_autoload_remove_one $func
done
}
_autoload_resolve()
{
if [[ ! "$FPATH" ]]; then
echo "autoload: FPATH not set or null" >&2
return
fi
local p
for p in $( (IFS=':'; set -- ${FPATH}; echo "$@") ); do
p=${p:-.}
if [ -f $p/$1 ]; then echo $p/$1; return; fi
done
echo "autoload: $1: function source file not found" >&2
}
autoload()
{
if (( $# == 0 )) ; then _autoload_dump; return; fi
local opt OPTIND
while getopts pu opt
do
case $opt in
p) _autoload_dump printable; return;;
u) shift $((OPTIND-1)); _autoload_remove "$@"; return;;
*) echo "autoload: usage: autoload [-pu] [function ...]" >&2; return;;
esac
done
shift $(($OPTIND-1))
_aload "$@"
}
+23
View File
@@ -0,0 +1,23 @@
# Date: Fri, 11 Oct 91 11:22:36 edt
# From: friedman@gnu.ai.mit.edu
# To: bfox@gnu.ai.mit.edu
# A replacement for basename(1). Not all the systems I use have this
# program. Usage: basename [path] {extension}
function basename ()
{
local path="$1"
local suffix="$2"
local tpath="${path%/}"
# Strip trailing '/' characters from path (unusual that this should
# ever occur, but basename(1) seems to deal with it.)
while [ "${tpath}" != "${path}" ]; do
tpath="${path}"
path="${tpath%/}"
done
path="${path##*/}" # Strip off pathname
echo ${path%${suffix}} # Also strip off extension, if any.
}
@@ -0,0 +1,43 @@
#From: "Grigoriy Strokin" <grg@philol.msu.ru>
#Newsgroups: comp.unix.shell
#Subject: fast basename and dirname functions for BASH/SH
#Date: Sat, 27 Dec 1997 21:18:40 +0300
#
#Please send your comments to grg@philol.msu.ru
function basename()
{
local name="${1##*/}"
echo "${name%$2}"
}
function dirname()
{
local dir="${1%${1##*/}}"
[ "${dir:=./}" != "/" ] && dir="${dir%?}"
echo "$dir"
}
# Two additional functions:
# 1) namename prints the basename without extension
# 2) ext prints extension of a file, including "."
function namename()
{
local name=${1##*/}
local name0="${name%.*}"
echo "${name0:-$name}"
}
function ext()
{
local name=${1##*/}
local name0="${name%.*}"
local ext=${name0:+${name#$name0}}
echo "${ext:-.}"
}
@@ -0,0 +1,108 @@
# coprocess.bash
#
# vi:set sts=2 sw=2 ai:
#
coprocess_pid=
#
# coprocess - Start, control, and end coprocesses.
#
function coprocess ()
{
while (( $# > 0 )) ; do
case "$1" in
#
# coprocess close
#
c|cl|clo|clos|close)
shift
exec 61>&- 62<&-
coprocess_pid=
if [ "$1" = "-SIGPIPE" ] ; then
# Only print message in an interactive shell
case "$-" in
*i*)
echo 'SIGPIPE' >&2
;;
esac
return 1
fi
return 0
;;
#
# coprocess open
#
o|op|ope|open)
shift
local fifo="/var/tmp/coprocess.$$.$RANDOM"
local cmd="/bin/bash"
if (( $# > 0 )) ; then
cmd="$@"
fi
mkfifo "$fifo.in" || return $?
mkfifo "$fifo.out" || {
ret=$?
rm -f "$fifo.in"
return $?
}
( "$@" <$fifo.in >$fifo.out ; rm -f "$fifo.in" "$fifo.out" ) &
coprocess_pid=$!
exec 61>$fifo.in 62<$fifo.out
return 0
;;
#
# coprocess print - write to the coprocess
#
p|pr|pri|prin|print)
shift
local old_trap=$(trap -p SIGPIPE)
trap 'coprocess close -SIGPIPE' SIGPIPE
if [ $# -eq 1 ] && [ "$1" = "--stdin" ] ; then
cat >&61
else
echo "$@" >&61
fi
local ret=$?
eval "$old_trap"
return $ret
;;
#
# coprocess read - read from the coprocess
#
r|re|rea|read)
shift
local old_trap=$(trap -p SIGPIPE)
trap '_coprocess_close -SIGPIPE' SIGPIPE
builtin read "$@" <&62
local ret=$?
eval "$old_trap"
return $ret
;;
s|st|sta|stat|statu|status)
if [ -z "$coprocess_pid" ] ; then
echo 'no active coprocess'
return 1
else
echo " coprocess is active [$coprocess_pid]"
return 0
fi
;;
*)
coprocess print "$@"
return $?
;;
esac
shift
done
coprocess status
return $?
}
@@ -0,0 +1,53 @@
Date: Fri, 21 Sep 2001 14:50:29 -0400
From: "Jason M. Felice" <jfelice@cronosys.com>
To: bash-maintainers@gnu.org, chet@po.cwru.edu
Subject: Bash co-processes functions
Message-ID: <20010921145029.A6093@argo.eraserhead.net>
Mime-Version: 1.0
Attached to this message you will find coprocess.bash and coshell.bash.
Here's a brief synopsis of use:
coprocess open telnet localhost
while coprocess read il ; do
echo "$il"
case "$il" in
*ogin:*)
coprocess print 'user'
;;
*ord:*)
echo 'pass' |coprocess print --stdin
;;
*$ *)
coprocess print 'exit'
break
;;
esac
done
coprocess close
And here's an example of the coshell function:
coshell open ssh -l root otherbox
coshell eval hostname
coshell ls -l
if coshell test -d /tmp ; then echo 'otherbox has a /tmp!' ; fi
coshell sendfile /var/lib/upgrade.rpm /tmp/test.rpm || exit $?
coshell eval rpm -ivh /tmp/test.rpm || exit $?
coshell eval rm -f /tmp/test.rpm || exit $?
coshell close
exit 0
There are a few minor issues that I'd like to work out, but it works well
enough for me ;-) The issues are:
- Shell quoting issue with 'coshell eval' commands - need to somehow
re-quote words.
- Interactive commands hang 'coshell eval', tried redirecting in </dev/null
to executed command, but it caused strange shell exit problems.
- Some way to copy stdin from local coshell eval to remote shell. Probably
logically impossible, but would be wonderfully useful.
I'm using it for writing scripts to publish websites and other scripts to
co-located servers.
@@ -0,0 +1,127 @@
# vi:set sts=2 sw=2 ai:
#
# coshell.bash - Control shell coprocesses (see coprocess.bash).
#
function coshell ()
{
while (( $# > 0 )) ; do
case "$1" in
#
# coshell open
#
o|op|ope|open)
shift
coprocess open "$@"
local ret=$?
# This should eat any ssh error messages or what not.
coshell eval : >/dev/null 2>&1
return $ret
;;
#
# coshell close
#
c|cl|clo|close)
shift
coprocess close "$@"
return $?
;;
#
# coshell eval
#
e|ev|eva|eval)
shift
local cookie=$RANDOM
if (( $# == 0 )) ; then
echo "coshell eval: no argumentsl" >&2
return 1
fi
if [ x$coprocess_pid = x ] ; then
echo "coshell eval: no active coshell" >&2
return 1
fi
coprocess print "$@"
coprocess print "coprocess_rc=\$?"
coprocess print "printf 'coprocess-$cookie----\n%d\n' \$coprocess_rc"
if [ x$coprocess_pid = x ] ; then
return 0
fi
local ol
while coprocess read ol ; do
case "$ol" in
*coprocess-$cookie----*)
ol="${ol%coprocess-$cookie----}"
echo -n "$ol"
break
;;
esac
echo "$ol"
done
coprocess read ol
return $ol
;;
#
# coshell sendfile
#
s|se|sen|send|sendf|sendfi|sendfil|sendfile)
shift
if (( $# != 2 )) ; then
echo "coshell sendfile: syntax is 'coshell sendfile SRC TARGET'" >&2
return 1
fi
if [ x$coprocess_pid = x ] ; then
echo "coshell sendfile: no active coshell" >&2
return 1
fi
local target=$2
if coshell test -d "$target" ; then
target="$target/${1##*/}"
fi
coprocess print "uudecode <<END_OF_FILE"
uuencode -m "$target" <$1 |coprocess print --stdin
coshell eval "END_OF_FILE"
return $?
;;
#
# coshell getfile
#
g|ge|get|getf|getfi|getfil|getfile)
shift
if (( $# != 2 )) ; then
echo "coshell getfile: syntax is 'coshell getfile SRC TARGET'" >&2
return 1
fi
if [ x$coprocess_pid = x ] ; then
echo "coshell getfile: no active coshell" >&2
return 1
fi
local target=$2
if test -d "$target" ; then
target="$target/${1##*/}"
fi
coshell eval uuencode -m "$target" "<" "$1" |uudecode
return $?
;;
*)
coshell eval "$@"
return $?
;;
esac
shift
done
coprocess status
return $?
}
@@ -0,0 +1,48 @@
# C-shell compatabilty package.
# setenv VAR VALUE
function setenv ()
{
export $1="$2"
}
function unsetenv ()
{
unset $1
}
# Can't write foreach yet. Need pattern matching, and a few extras.
function foreach () {
echo 'Can'\''t do `foreach'\'' yet. Type "help for".'
}
# Make this work like csh's. Special case "term" and "path".
#set () {
#}
chdir ()
{
builtin cd "$@"
}
# alias - convert csh alias commands to bash functions
# from Mohit Aron <aron@cs.rice.edu>
# posted to usenet as <4i5p17$bnu@larry.rice.edu>
function alias ()
{
if [ "x$2" = "x" ]
then
declare -f $1
else
case $2 in
*[#\!]*)
comm=$(echo $2 | sed 's/\\!\*/\"$\@\"/g
s/\\!:\([1-9]\)/\"$\1\"/g
s/#/\\#/g')
;;
*)
comm="$2 \"\$@\"" ;;
esac
eval function $1 \(\) "{" command "$comm" "; }"
fi
}
+142
View File
@@ -0,0 +1,142 @@
#
# Directory manipulation functions from the book 'The Korn Shell'
# Modified for use with bash Mon Apr 18 08:37 1994 by
# Ken Konecki (kenk@wfg.com)
#
# Modified by Chet Ramey
#
# This could stand to have calls to `select' added back in
#
alias integer="declare -i"
integer _push_max=${CDSTACK-31} _push_top=${CDSTACK-31}
unalias cd
# alias cd=_cd
# Display directory stack -- $HOME display as ~
dirs()
{
dir="${PWD#$HOME/}"
case $dir in
$HOME) dir=\~ ;;
/*) ;;
*) dir=\~/$dir ;;
esac
integer i=_push_top
integer n=1
echo "$n) $dir"
while let "i < $_push_max"
do
n=n+1
eval "echo \$n\) \$_push_stack_$i"
i=i+1
done
}
# Change directory and put directory on front of stack
cd()
{
typeset dir=
integer n=0 type=4 i
case $1 in
-|-1|2) # cd -
n=_push_top type=1
;;
-[1-9]|-[1-9][0-9]) # cd -n
n=_push_top+${1#-}-1 type=2
;;
1) # keep present directory
echo "$PWD"
return
;;
[2-9]|[1-9][0-9]) # cd n
n=_push_top+${1}-2 type=2
;;
*)
if let "_push_top <= 0"; then
type=3 n=_push_max
fi
;;
esac
if let "type < 3"; then
if let "n >= _push_max"; then
echo cd: Directory stack not that deep
return 1
else
eval dir=\${_push_stack_$n}
fi
fi
case $dir in
~*) dir=$HOME${dir#\~} ;;
esac
cd2 ${dir:-$@} > /dev/null || return 1
dir=${OLDPWD#$HOME/}
case $dir in
$HOME) dir=\~ ;;
/*) ;;
*) dir=\~/$dir ;;
esac
case $type in
1) # swap first two elements
eval _push_stack_$_push_top=\$dir ;;
2|3) # put $dir on top and shift down by one until top
i=_push_top
unset _dirlist
while let "i < $_push_max" ; do
eval _dirlist=\"\$_dirlist \$_push_stack_$i\"
i=i+1
done
i=_push_top
for dir in "$dir" ${_dirlist} ; do
let "i > n" && break
eval _push_stack_$i=\$dir
i=i+1
done
;;
4) # push name
_push_top=_push_top-1;
eval _push_stack_$_push_top=\$dir
;;
esac
echo "$PWD"
}
# Menu-driven change directory command
function mcd
{
dirs
echo -n "Select by number or enter a name: "
read
cd $REPLY
}
# Emulate ksh cd substitution
cd2()
{
case "$#" in
0) builtin cd "$HOME" ;;
1) builtin cd "$1" ;;
2) newDir=$(echo $PWD | sed -e "s:$1:$2:g")
case "$newDir" in
$PWD) echo "bash:: cd: bad substitution" >&2 ; return 1 ;;
*) builtin cd "$newDir" ;;
esac ;;
*) echo "bash: cd: wrong arg count" 1>&2 ; return 1 ;;
esac
}
+21
View File
@@ -0,0 +1,21 @@
# Date: Fri, 11 Oct 91 11:22:36 edt
# From: friedman@gnu.ai.mit.edu
# To: bfox@gnu.ai.mit.edu
# A replacement for dirname(1). This one appears less often on some
# systems I use than basename(1), and I really depend on it for some
# things. Usage: dirname [path]
function dirname ()
{
local dir="$1"
local tdir="${dir%/}"
# Strip trailing '/' characters from dir (unusual that this should
# ever occur, but dirname(1) seems to deal with it.)
while [ "${tdir}" != "${dir}" ]; do
tdir="${dir}"
dir="${tdir%/}"
done
echo "${dir%/*}"
}
+28
View File
@@ -0,0 +1,28 @@
#! /bin/bash
#
#Derived from:
#
#From: damercer@mmm.com (Dan Mercer)
#Newsgroups: comp.unix.admin,comp.unix.shell,comp.unix.programmer,comp.sys.sun.admin
#Subject: Re: Command to find out if a directory is empty
#Date: 17 Aug 2000 14:35:56 GMT
#Message-ID: <8ngt8c$fmr$1@magnum.mmm.com>
# usage: emptydir [dirname] ; default dirname is "."
emptydir()
{
typeset file dir=${1:-.}
[[ -d $dir ]] || {
echo "$FUNCNAME: $dir is not a directory" >&2
return 2
}
for file in $dir/.* $dir/*
do
case ${file#$dir/} in
.|..) ;;
\*) [[ -e $file ]];let $?;return;;
*) return 1;;
esac
done
}
+22
View File
@@ -0,0 +1,22 @@
# Contributed by Noah Friedman and Roland McGrath.
# To be run by the PROMPT_COMMAND variable, so that one can see what
# the exit status of processes are.
function check_exit_status ()
{
local status="$?"
local signal=""
if [ ${status} -ne 0 ] && [ ${status} != 128 ]; then
# If process exited by a signal, determine name of signal.
if [ ${status} -gt 128 ]; then
signal="$(builtin kill -l $((${status} - 128)) 2>/dev/null)"
if [ "$signal" ]; then signal="($signal)"; fi
fi
echo "[Exit ${status} ${signal}]" 1>&2
fi
return 0
}
PROMPT_COMMAND=check_exit_status
+50
View File
@@ -0,0 +1,50 @@
# Contributed by Noah Friedman.
# To avoid using a function in bash, you can use the `builtin' or
# `command' builtins, but neither guarantees that you use an external
# program instead of a bash builtin if there's a builtin by that name. So
# this function can be used like `command' except that it guarantees the
# program is external by first disabling any builtin by that name. After
# the command is done executing, the state of the builtin is restored.
function external ()
{
local state=""
local exit_status
if builtin_p "$1"; then
state="builtin"
enable -n "$1"
fi
command "$@"
exit_status=$?
if [ "$state" = "builtin" ]; then
enable "$1"
fi
return ${exit_status}
}
# What is does is tell you if a particular keyword is currently enabled as
# a shell builtin. It does NOT tell you if invoking that keyword will
# necessarily run the builtin. For that, do something like
#
# test "$(builtin type -type [keyword])" = "builtin"
#
# Note also, that disabling a builtin with "enable -n" will make builtin_p
# return false, since the builtin is no longer available.
function builtin_p ()
{
local word
set $(builtin type -all -type "$1")
for word in "$@" ; do
if [ "${word}" = "builtin" ]; then
return 0
fi
done
return 1
}
+13
View File
@@ -0,0 +1,13 @@
# Who said shells can't use recursion? Here is a factorial function.
# You call it with a number as an argument, and it returns the factorial
# of that number.
fact ()
{
local num=$1;
if [ "$num" = 1 ] ; then
echo 1
return ;
fi;
echo $(( $num * $(fact $(( $num - 1 )) ) ))
}
+59
View File
@@ -0,0 +1,59 @@
#
# A function that works as a front end for both stty and the `bind'
# builtin, so the tty driver and readline see the same changes
#
#
# Convert between the stty ^H control character form and the readline \C-H
# form
#
cvt()
{
echo "$@" | cat -v | sed 's/\^/\\C-/'
}
#
# stty front-end. Parses the argument list and creates two command strings,
# one for stty, another for bind.
#
fstty()
{
local cmd="" bargs=""
local e
while [ $# -gt 0 ]
do
case "$1" in
-a) cmd="$cmd everything"
;;
erase) shift;
e=$(cvt "$1")
cmd="$cmd erase $1"
bargs="$bargs '\"$e\": backward-delete-char'"
;;
kill) shift
e=$(cvt "$1")
cmd="$cmd kill $1"
bargs="$bargs '\"$e\": unix-line-discard'"
;;
werase) shift;
e=$(cvt "$1")
cmd="$cmd erase $1"
bargs="$bargs '\"$e\": backward-kill-word'"
;;
lnext) shift;
e=$(cvt "$1")
cmd="$cmd erase $1"
bargs="$bargs '\"$e\": quoted-insert'"
;;
*) cmd="$cmd $1"
;;
esac
shift
done
command stty $cmd
if [ -n "$bargs" ]; then
builtin bind $bargs
fi
}
+27
View File
@@ -0,0 +1,27 @@
#
# func -- print out definitions for functions named by arguments
#
# usage: func name [name ...]
#
# Chet Ramey
# chet@ins.CWRU.Edu
func()
{
local status=0
if [ $# -eq 0 ] ; then
echo "usage: func name [name...]" 1>&2
return 1
fi
for f
do
if [ "$(builtin type -type $f)" != "function" ] ; then
echo "func: $f: not a function" 1>&2
status=1 # one failed
continue
fi
builtin type $f | sed 1d
done
return $status
}
+35
View File
@@ -0,0 +1,35 @@
#
# get_html -- get a web page from a remote server
#
# Original Author: Jeff Korn <jlk@cs.princeton.edu>
# Modified for bash by Chet Ramey <chet@po.cwru.edu>
#
# Example: get_html cnswww.cns.cwru.edu /~chet/ | more
get_html()
{
local host port
(($# < 2)) && {
echo "usage: $FUNCNAME hostname path [port]" >&2
return 1
}
host="$1"
port="${3:-80}"
exec 3<> /dev/tcp/$host/$port || {
echo "$FUNCNAME: $host/$port: cannot connect" >&2
exit 1
}
echo -e "GET $2 HTTP/1.0\n" >&3
cat <&3
exec 3<&-
return 0
}
get_html "$@"
@@ -0,0 +1,301 @@
#From: "Grigoriy Strokin" <grg@philol.msu.ru>
#Newsgroups: comp.unix.shell
#Subject: BASH: getopt function that parses long-named options
#Date: Mon, 22 Dec 1997 20:35:18 +0300
#Hi, I have written a BASH function named getoptex, that is like bash builtin
#"getopts", but does parse long-named options and optional arguments. It only
#uses builtin bash commands, so it is very fast. In order to use it in your
#bash scripts, include a command ". getopt.sh" (<dot> getopt.sh) to the file
#containing your script, and that will define functions getopt, getoptex, and
#optlistex (the file getopt.sh with its detailed description is listed
#below).
#*** file getopt.sh ***
#! /bin/bash
#
# getopt.sh:
# functions like getopts but do long-named options parsing
# and support optional arguments
#
# Version 1.0 1997 by Grigoriy Strokin (grg@philol.msu.ru), Public Domain
# Date created: December 21, 1997
# Date modified: December 21, 1997
#
# IMPORTANT FEATURES
#
# 1) Parses both short and long-named options
# 2) Supports optional arguments
# 3) Only uses bash builtins, thus no calls to external
# utilities such as expr or sed is done. Therefore,
# parsing speed is high enough
#
#
# DESCRIPTION
#
# FUNCTION getopt
# Usage: getopt OPTLIST {"$@"|ALTERNATIVE_PARAMETERS}
#
# like getopts, but parse options with both required and optional arguments,
# Options with optional arguments must have "." instead of ":" after them.
# Furthemore, a variable name to place option name cannot be specified
# and is always placed in OPTOPT variable
#
# This function is provided for compatibility with getopts()
# OPTLIST style, and it actually calls getoptex (see bellow)
#
# NOTE that a list of parameters is required and must be either "$@",
# if processing command line arguments, or some alternative parameters.
#
# FUNCTION getoptex
# Usage: getoptex OPTION_LIST {"$@"|ALTERNATIVE_PARAMETERS}
#
# like getopts, but parse long-named options.
#
# Both getopt and getoptex return 0 if an option has been parsed,
# and 1 if all options are already parsed or an error occured
#
# Both getopt and getoptex set or test the following variables:
#
# OPTERR -- tested for whether error messages must be given for invalid
options
#
# OPTOPT -- set to the name of an option parsed,
# or to "?" if no more options or error
# OPTARG -- set to the option argument, if any;
# unset if ther is no argument;
# on error, set to the erroneous option name
#
# OPTIND -- Initialized to 1.
# Then set to the number of the next parameter to be parsed
# when getopt or getoptex will be called next time.
# When all options are parsed, contains a number of
# the first non-option argument.
#
#
# OPTOFS -- If a parameter number $OPTIND containg an option parsed
# does not contain any more options, OPTOFS is unset;
# otherwise, OPTOFS is set to such a number of "?" signs
# which is equal to the number of options parsed
#
# You might not set variables OPTIND and OPTOFS yourself
# unless you want to parse a list of parameters more than once.
# Otherwise, you whould unset OPTIND (or set it to 1)
# and unset OPTOFS each time you want to parse a new parameters
list
#
# Option list format is DIFFERENT from one for getopts or getopt.
getopts-style
# option list can be converted to getoptex-style using a function optlistex
# (see bellow)
#
# DESCRIPTION of option list used with getoptex:
# Option names are separated by whitespace. Options consiting of
# more than one character are treated as long-named (--option)
#
# Special characters can appear at the and of option names specifying
# whether an argument is required (default is ";"):
# ";" (default) -- no argument
# ":" -- required argument
# "," -- optional argument
#
# For example, an option list "a b c help version f: file: separator."
# defines the following options:
# -a, -b, -c, --help, --version -- no argument
# -f, --file -- argument required
# --separator -- optional argument
#
# FUNCTION optlistex
# Usage new_style_optlist=`optlistex OLD_STYLE_OPTLIST`
#
# Converts getopts-style option list in a format suitable for use with getoptex
# Namely, it inserts spaces after each option name.
#
#
# HOW TO USE
#
# In order o use in your bash scripts the functions described,
# include a command ". getopt.sh" to the file containing the script,
# which will define functions getopt, getoptex, and optlistex
#
# EXAMPLES
#
# See files 'getopt1' and 'getopt2' that contain sample scripts that use
# getopt and getoptex functions respectively
#
#
# Please send your comments to grg@philol.msu.ru
function getoptex()
{
let $# || return 1
local optlist="${1#;}"
let OPTIND || OPTIND=1
[ $OPTIND -lt $# ] || return 1
shift $OPTIND
if [ "$1" != "-" ] && [ "$1" != "${1#-}" ]
then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ]
then
local o
o="-${1#-$OPTOFS}"
for opt in ${optlist#;}
do
OPTOPT="${opt%[;.:]}"
unset OPTARG
local opttype="${opt##*[^;:.]}"
[ -z "$opttype" ] && opttype=";"
if [ ${#OPTOPT} -gt 1 ]
then # long-named option
case $o in
"--$OPTOPT")
if [ "$opttype" != ":" ]; then return 0; fi
OPTARG="$2"
if [ -z "$OPTARG" ];
then # error: must have an agrument
let OPTERR && echo "$0: error: $OPTOPT must have an argument" >&2
OPTARG="$OPTOPT";
OPTOPT="?"
return 1;
fi
OPTIND=$[OPTIND+1] # skip option's argument
return 0
;;
"--$OPTOPT="*)
if [ "$opttype" = ";" ];
then # error: must not have arguments
let OPTERR && echo "$0: error: $OPTOPT must not have arguments" >&2
OPTARG="$OPTOPT"
OPTOPT="?"
return 1
fi
OPTARG=${o#"--$OPTOPT="}
return 0
;;
esac
else # short-named option
case "$o" in
"-$OPTOPT")
unset OPTOFS
[ "$opttype" != ":" ] && return 0
OPTARG="$2"
if [ -z "$OPTARG" ]
then
echo "$0: error: -$OPTOPT must have an argument" >&2
OPTARG="$OPTOPT"
OPTOPT="?"
return 1
fi
OPTIND=$[OPTIND+1] # skip option's argument
return 0
;;
"-$OPTOPT"*)
if [ $opttype = ";" ]
then # an option with no argument is in a chain of options
OPTOFS="$OPTOFS?" # move to the next option in the chain
OPTIND=$[OPTIND-1] # the chain still has other options
return 0
else
unset OPTOFS
OPTARG="${o#-$OPTOPT}"
return 0
fi
;;
esac
fi
done
echo "$0: error: invalid option: $o"
fi; fi
OPTOPT="?"
unset OPTARG
return 1
}
function optlistex
{
local l="$1"
local m # mask
local r # to store result
while [ ${#m} -lt $[${#l}-1] ]; do m="$m?"; done # create a "???..." mask
while [ -n "$l" ]
do
r="${r:+"$r "}${l%$m}" # append the first character of $l to $r
l="${l#?}" # cut the first charecter from $l
m="${m#?}" # cut one "?" sign from m
if [ -n "${l%%[^:.;]*}" ]
then # a special character (";", ".", or ":") was found
r="$r${l%$m}" # append it to $r
l="${l#?}" # cut the special character from l
m="${m#?}" # cut one more "?" sign
fi
done
echo $r
}
function getopt()
{
local optlist=`optlistex "$1"`
shift
getoptex "$optlist" "$@"
return $?
}
#**************************************
# cut here
#**************************************
#*** (end of getopt.sh) ***
#*** file getopt1 ***
#! /bin/bash
# getopt1:
# Sample script using the function getopt
#
# Type something like "getopt1 -ab -d 10 -e20 text1 text2"
# on the command line to see how it works
#
# See getopt.sh for more information
#. getopt.sh
#echo Using getopt to parse arguments:
#while getopt "abcd:e." "$@"
#do
# echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
#done
#shift $[OPTIND-1]
#for arg in "$@"
#do
# echo "Non option argument <$arg>"
#done
#
#**************************************
# cut here
#**************************************
#*** (end of getopt1) ***
#
#
#*** file getopt2 ***
#
#! /bin/bash
# getopt2:
# Sample script using the function getoptex
#
# Type something like "getopt2 -ab -d 10 -e20 --opt1 --opt4=100 text1 text2"
# to see how it works
#
# See getopt.sh for more information
. getopt.sh
#echo Using getoptex to parse arguments:
#while getoptex "a; b; c; d: e. opt1 opt2 opt3 opt4: opt5." "$@"
#do
# echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
#done
#shift $[OPTIND-1]
#for arg in "$@"
#do
# echo "Non option argument <$arg>"
#done
#
#**************************************
# cut here
#**************************************
#*** (end of getopt2) ***
+60
View File
@@ -0,0 +1,60 @@
#
# inet2hex - Internet address conversion, dotted-decimal to hex
#
inet2hex ()
{
local IFS
IFS=.
set -- $1
if (( $# != 4 )); then
echo "inet2hex: incorrect input format: $1" >&2
echo "inet2hex: usage: inet2hex XX.XX.XX.XX" >&2
return 2
fi
printf "0x%02x%02x%02x%02x\n" $1 $2 $3 $4
}
#
# hex2inet - Internet address conversion, hex to dotted-decimal
#
hex2inet ()
{
local x1 x2 x3 x4
local rev
OPTIND=1
while getopts "r" o
do
case "$o" in
r) rev=true;;
*) echo "hex2inet: usage: hex2inet [-r] [0x]XXXXXXXX" >&2 ; exit 2;;
esac
done
shift $(( $OPTIND - 1 ))
case "$1" in
0x*) h=${1#??} ;;
*) h=$1 ;;
esac
if (( ${#h} != 8 )); then
echo "hex2inet: $h not in inet format" >&2
echo "hex2inet: usage: hex2inet [0x]XXXXXXXX" >&2
return 2
fi
x1=$(( 0x${h:0:2} ))
x2=$(( 0x${h:2:2} ))
x3=$(( 0x${h:4:2} ))
x4=$(( 0x${h:6:2} ))
if [ -z "$rev" ] ; then
printf "%d.%d.%d.%d\n" $x1 $x2 $x3 $x4
else
printf "%d.%d.%d.%d\n" $x4 $x3 $x2 $x1
fi
return 0
}
+14
View File
@@ -0,0 +1,14 @@
inpath()
{
local PROG
path=$(echo $PATH | sed 's/^:/.:/
s/::/:.:/g
s/:$/:./
s/:/ /g')
for x in $path
do
[ -x $x/$1 ] && { PROG=$x/$1; break; }
done
[ -n "$PROG" ]
}
@@ -0,0 +1,52 @@
#From: jrmartin@rainey.blueneptune.com (James R. Martin)
#Newsgroups: comp.unix.shell
#Subject: Re: testing user input on numeric or character value
#Date: 26 Nov 1997 01:28:43 GMT
# isnum returns True if its argument is a valid number,
# and False (retval=1) if it is any other string.
# The first pattern requires a digit before the decimal
# point, and the second after the decimal point.
# BASH NOTE: make sure you have executed `shopt -s extglob' before
# trying to use this function, or it will not work
isnum() # string
{
case $1 in
?([-+])+([0-9])?(.)*([0-9])?([Ee]?([-+])+([0-9])) )
return 0;;
?([-+])*([0-9])?(.)+([0-9])?([Ee]?([-+])+([0-9])) )
return 0;;
*) return 1;;
esac
}
isnum2() # string
{
case $1 in
?([-+])+([[:digit:]])?(.)*([[:digit:]])?([Ee]?([-+])+([[:digit:]])) )
return 0;;
?([-+])*([[:digit:]])?(.)+([[:digit:]])?([Ee]?([-+])+([[:digit:]])) )
return 0;;
*) return 1;;
esac
}
isint() # string
{
case $1 in
?([-+])+([0-9]) )
return 0;;
*) return 1;;
esac
}
isint2() # string
{
case $1 in
?([-+])+([[:digit:]]) )
return 0;;
*) return 1;;
esac
}
+22
View File
@@ -0,0 +1,22 @@
isnum2()
{
case "$1" in
'[-+]' | '') return 1;; # empty or bare `-' or `+'
[-+]*[!0-9]*) return 1;; # non-digit with leading sign
[-+]*) return 0;; # OK
*[!0-9]*) return 1;; # non-digit
*) return 0;; # OK
esac
}
# this one handles floating point
isnum3()
{
case "$1" in
'') return 1;; # empty
*[!0-9.+-]*) return 1;; # non-digit, +, -, or .
*?[-+]*) return 1;; # sign as second or later char
*.*.*) return 1;; # multiple decimal points
*) return 0;; # OK
esac
}
@@ -0,0 +1,14 @@
# Thanks to Chris F. A. Johnson <c.f.a.johnson@rogers.com> for this one
is_validip()
{
case "$*" in
""|*[!0-9.]*|*[!0-9]) return 1 ;;
esac
local IFS=.
set -- $*
[ $# -eq 4 ] &&
[ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
[ ${3:-666} -le 255 ] && [ ${4:-666} -le 254 ]
}
@@ -0,0 +1,78 @@
#From: damatex@CAM.ORG (Mario Boudreault)
#Newsgroups: comp.unix.shell
#Subject: JULIAN DATE CONVERSION SUB
#Date: 4 Aug 1995 10:23:28 -0400
#Message-ID: <3vtah0$jb3@ocean.CAM.ORG>
#For those using shells and who want to convert dates to a julian number
#here is a shell script (wihtout validation) that can be used as a base
#program for your shell scripts.
#Special thanks to Ed Ferguson@ti.com who sent me the algorithm to compute
#that date.
#
# MODIFIED BY CHET RAMEY TO CONVERT TO bash v2 SYNTAX
#
# cnvdate - Conversion de dates en julienne et vice et versa...
#
# Par : Mario Boudreault Damatex Inc Montreal, Canada
# Date: 2 Aout 1995
# Rev.: 2 Aout 1995
#
# Usage:
# cvdate [-j] YYYMMDD pour convertir en nbre de jours
# cvdate -d {julian number} pour convertir en AAAAMMJJ
#
jul_date()
{
#
# Separe ANNEE, MOIS et JOUR...
#
YEAR=`echo $DATE | awk ' { print substr($0,1,4) } '`
MONTH=`echo $DATE | awk ' { print substr($0,5,2) } '`
DAY=`echo $DATE | awk ' { print substr($0,7,2) } '`
#
# Execute la formule magique...
#
A=$(( $DAY - 32075 + 1461 * ( $YEAR + 4800 - ( 14 - $MONTH ) / 12 ) \
/ 4 + 367 * ( $MONTH - 2 + ( 14 - $MONTH ) / 12 * 12 ) / 12 - \
3 * ( ( $YEAR + 4900 - ( 14 - $MONTH ) / 12 ) / 100 ) / 4 ))
echo $A
}
day_date()
{
TEMP1=$(( $DATE + 68569 ))
TEMP2=$(( 4 * $TEMP1 / 146097 ))
TEMP1=$(( $TEMP1 - ( 146097 * $TEMP2 + 3 ) / 4 ))
Y=$(( 4000 * ( $TEMP1 + 1 ) / 1461001 ))
TEMP1=$(( $TEMP1 - 1461 * $Y / 4 + 31 ))
M=$(( 80 * $TEMP1 / 2447 ))
D=$(( $TEMP1 - 2447 * $M / 80 ))
TEMP1=$(( $M / 11 ))
M=$(( $M + 2 - 12 * $TEMP1 ))
Y=$(( 100 * ( $TEMP2 - 49 ) + $Y + $TEMP1 ))
M=`echo $M | awk ' { M=$0 ; if ( length($0) == 1 ) M="0"$0 } END { print M } '`
D=`echo $D | awk ' { D=$0 ; if ( length($0) == 1 ) D="0"$0 } END { print D } '`
echo $Y$M$D
}
# main()
if [ $# -eq 1 ]; then
DATE=$1
jul_date
elif [ "$1" = '-j' ]; then
DATE=$2
jul_date
elif [ "$1" = '-d' ]; then
DATE=$2
day_date
fi
#
# Termine
#
exit 0
+12
View File
@@ -0,0 +1,12 @@
jj ()
{
p=$(jobs $1);
echo $p
case "$p" in
[*) echo matches '[*'
;;
*) echo not a match\?
;;
esac
}
+62
View File
@@ -0,0 +1,62 @@
# From: Seth Chaiklin <psykseth@aau.dk>
# To: chet@ins.CWRU.Edu
# Subject: bash functions (sorta)
#
# keep:
# usage: keep program
# declare the a program should be "kept". i.e. try to fg a stopped one
# and only when that fails start a fresh program.
#
keep()
{
case $# in
1|2) ;;
*) echo "usage: keep [alias] program" 1>&2 ; return 1;;
esac
# progname
pn=${1##*/}
# set up an alias for the kept program
if [ $# = 1 ]; then
alias "$pn=fg $1 2>/dev/null || $1"
else
alias "$1=fg $2 2>/dev/null || $2"
fi
}
#
# unkeep:
# usage: unkeep program
# unset the alias set up by the keep function
#
unkeep()
{
if [ $# != 1 ]; then
echo "usage: unkeep program"
return 2
fi
# unset the alias for the kept program
unalias "${1##*/}"
}
#
# kept:
# lists all kept programs in 'alias: program' form
#
kept()
{
alias | grep "fg.*2>" | sed "s/alias \(.*\)='fg.*||\(.*\)'$/\1:\2/"
}
# some things that should be kept
#keep /usr/local/bin/emacs
#keep e ${EDITOR:-/usr/local/bin/emacs}
#keep edit ${EDITOR:-/usr/local/bin/emacs}
#keep /usr/local/bin/emm
+35
View File
@@ -0,0 +1,35 @@
#
# ksh-like `cd': cd [-LP] [dir [change]]
#
cd()
{
OPTIND=1
while getopts "LP" opt
do
case $opt in
L|P) CDOPTS="$CDOPTS -$opt" ;;
*) echo "$FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2
return 2;;
esac
done
shift $(( $OPTIND - 1 ))
case $# in
0) builtin cd $CDOPTS "$HOME" ;;
1) builtin cd $CDOPTS "$@" ;;
2) old="$1" new="$2"
case "$PWD" in
*$old*) ;;
*) echo "${0##*/}: $FUNCNAME: bad substitution" >&2 ; return 1 ;;
esac
dir=${PWD//$old/$new}
builtin cd $CDOPTS "$dir" && echo "$PWD"
;;
*) echo "${0##*/}: $FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2
return 2 ;;
esac
}
@@ -0,0 +1,40 @@
#
# replacements for test/[ that do arithmetic expansion on the operands to
# the arithmetic operators, like ksh.
#
function test()
{
local -i n1 n3
case "$#" in
3) case "$2" in
-lt|-gt|-eq|-ne|-le|-ge) n1=$(( $1 ))
n3=$(( $3 ))
builtin test "$n1" $2 "$n3"
return $?;;
*) builtin test "$@" ;;
esac;;
*) builtin test "$@" ;;
esac
}
function [()
{
local -i n1 n3
case "$#" in
4) case "$2" in
-lt|-gt|-eq|-ne|-le|-ge) n1=$(( $1 ))
n3=$(( $3 ))
builtin [ "$n1" $2 "$n3" ]
return $?;;
*) builtin [ "$@" ;;
esac;;
*) builtin [ "$@" ;;
esac
}
q=7
[ q -lt 10 ]
echo $?
[ $q -lt 10 ]
echo $?
+228
View File
@@ -0,0 +1,228 @@
#
# .kshenv -- functions and aliases to provide the beginnings of a ksh
# environment for bash.
#
# Chet Ramey
# chet@ins.CWRU.Edu
#
#
# These are definitions for the ksh compiled-in `exported aliases'. There
# are others, but we already have substitutes for them: "history", "type",
# and "hash".
#
alias r="fc -s"
alias functions="typeset -f"
alias integer="typeset -i"
alias nohup="nohup "
alias command="command "
alias stop="kill -s STOP"
alias redirect="command exec"
alias hist="fc"
#
# An almost-ksh compatible `whence' command. This is as hairy as it is
# because of the desire to exactly mimic ksh (whose behavior was determined
# empirically).
#
# This depends somewhat on knowing the format of the output of the bash
# `builtin type' command.
#
whence()
{
local vflag pflag fflag defarg c
local path
vflag= aflag= pflag= fflag=
path=
if [ "$#" = "0" ] ; then
echo "whence: usage: whence [-afpv] name..." >&2
return 2
fi
OPTIND=1
while getopts "avfp" c
do
case "$c" in
a) defarg=-a ;;
f) fflag=1 ;; # no-op
p) pflag=1 ;;
v) vflag=1 ;;
?) echo "whence: $1: unknown option" >&2
echo "whence: usage: whence [-afpv] name..." >&2
return 2 ;;
esac
done
shift $(( $OPTIND - 1 ))
if [ "$#" = "0" ] ; then
echo "whence: usage: whence [-afpv] name..." >&2
return 2
fi
for cmd
do
if [ "$vflag" ] ; then
if [ -z "$defarg" ]; then
builtin type $cmd | sed 1q
else
if builtin type $defarg -t $cmd | grep 'function$' >/dev/null 2>&1; then
# HAIRY awk script to suppress
# printing of function body -- could
# do it with sed, but I don't have
# that kind of time
builtin type $defarg $cmd | awk '
BEGIN {printit = 1;}
$1 == "'$cmd'" && $2 == "()" {printit=0; next; }
/^}$/ { if (printit == 0) printit=1 ; else print $0; next ; }
/.*/ { if (printit) print $0; }'
else
builtin type $defarg $cmd
fi
fi
else
path=$(builtin type $defarg -p $cmd)
if [ "$path" ] ; then
echo $path
else
case "$cmd" in
/*) echo "" ;;
*) case "$(builtin type -t $cmd)" in
"") echo "" ;;
*) echo "$cmd" ;;
esac
;;
esac
fi
fi
done
return 0
}
#
# For real ksh homeboy fanatics, redefine the `type' builtin with a ksh
# version.
#
#type()
#{
# whence -v "$*"
#}
#
# ksh-like `cd': cd [-LP] [dir [change]]
#
cd()
{
OPTIND=1
while getopts "LP" opt
do
case $opt in
L|P) CDOPTS="$CDOPTS -$opt" ;;
*) echo "$FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2
return 2;;
esac
done
shift $(( $OPTIND - 1 ))
case $# in
0) builtin cd $CDOPTS "$HOME" ;;
1) builtin cd $CDOPTS "$@" ;;
2) old="$1" new="$2"
case "$PWD" in
*$old*) ;;
*) echo "${0##*/}: $FUNCNAME: bad substitution" >&2 ; return 1 ;;
esac
dir=${PWD//$old/$new}
builtin cd $CDOPTS "$dir" && echo "$PWD"
;;
*) echo "${0##*/}: $FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2
return 2 ;;
esac
}
#
# ksh print emulation
#
# print [-Rnprsu[n]] [-f format] [arg ...]
#
# - end of options
# -R BSD-style -- only accept -n, no escapes
# -n do not add trailing newline
# -p no-op (no coprocesses)
# -r no escapes
# -s print to the history file
# -u n redirect output to fd n
# -f format printf "$format" "$@"
#
print()
{
local eflag=-e
local nflag= fflag= c
local fd=1
OPTIND=1
while getopts "fRnprsu:" c
do
case $c in
R) eflag= ;;
r) eflag= ;;
n) nflag=-n ;;
s) sflag=y ;;
f) fflag=y ;;
u) fd=$OPTARG ;;
p) ;;
esac
done
shift $(( $OPTIND - 1 ))
if [ -n "$fflag" ]; then
builtin printf "$@" >&$fd
return
fi
case "$sflag" in
y) builtin history -s "$*" ;;
*) builtin echo $eflag $nflag "$@" >&$fd
esac
}
# substring function
# this function should be equivalent to the substring built-in which was
# eliminated after the 06/29/84 version
substring ()
{
local lpat flag str #local variables
set -f
case $1 in
-l|-L)
flag=$1
lpat=$2
shift 2
;;
esac
# test for too few or too many arguments
if [ x"$1" = x ] || [ $# -gt 2 ]; then
print -u2 'substring: bad argument count'
return 1
fi
str=$1
if [ x"$flag" = x-l ]; then #substring -l lpat
str=${str#$lpat}
elif [ x"$flag" = x-L ]; then
str=${str##$lpat} #substring -L lpat
fi
if [ x"$2" != x ]; then
echo ${str%$2}
else
echo $str
fi
return 0
}
+11
View File
@@ -0,0 +1,11 @@
# replace the `login' and `newgrp' builtins in old bourne shells
login()
{
exec login "$@"
}
newgrp()
{
exec newgrp "$@"
}
@@ -0,0 +1,27 @@
#! /bin/bash
#
# original from
# @(#) lowercase.ksh 1.0 92/10/08
# 92/10/08 john h. dubois iii (john@armory.com)
#
# conversion to bash v2 syntax done by Chet Ramey
lowercase()
{
for file; do
[ -f "$file" ] || continue
filename=${file##*/}
case "$file" 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
}
+129
View File
@@ -0,0 +1,129 @@
# Written from scratch by Tom Tromey (tromey@cns.caltech.edu)
#
# manpage -- find and print a manual page.
# usage: manpage section name [printing]
#
function manpage ()
{
local i h cmd zot sec
local num="$1"
local page="$2"
local printing="$3"
local mp
mp="${MANPATH:-/usr/man}"
if [ "$#" -lt 2 ]; then return 1; fi # should print usage
if [ "$num" != "" ]; then
sec="${num%%[a-zA-Z]*}"
else
sec='[168234571lnpo]'
num="$sec"
fi
for i in $(echo "$mp" | tr : ' '); do
if [ ! -d "$i" ]; then continue; fi
file="$i"/man"$sec"/"$page"."$num"*
set $file
file="$1"
if [ -f "$file" ]; then
zot=$(sed 1q "$file")
cmd=${MANROFF:-"nroff -man - | col | cat -s"}
h=${zot##"'"'\"'}
if [ "$h" != "$zot" ]; then
while [ "$h" != "" ]; do
case "$h" in
*e) cmd="${MANEQN:-neqn} | $cmd";;
*r) cmd="refer | $cmd";;
*t) cmd="tbl | $cmd";;
*v) cmd="vgrind | $cmd";;
*) ;; # should print error
esac
h=${h%?}
done
fi
if [ "$printing" != "" ]; then
(cd "$i"; eval "$cmd") < "$file" | ${PAGER:-more}
else
(cd "$i"; eval "$cmd") < "$file" > /tmp/manpage-$$
${PAGER:-more} /tmp/manpage-$$
rm -f /tmp/manpage-$$
fi
break
fi
done
}
function whatis_internal ()
{
local j
for j in $(echo "$MANPATH" | tr : ' '); do
if [ -f "$j/whatis" ]; then
eval $2 -i -e "$1" $j/whatis
fi
done
}
function whatis ()
{
local name=$(basename "$1")
whatis_internal "$name" "grep -w"
}
function apropos ()
{
whatis_internal "$1" "grep -F"
}
# Note: "-" and "-t" together not supported. This man could be
# made a lot better, but it does everything I want.
function man ()
{
local PAGER printing mpath MANROFF num
mpath="${MANPATH:-/usr/man}"
while true; do
case "$1" in
-) PAGER=cat
printing= ;;
-t)
MANROFF=${TROFF:-"ptroff -man -t"}
PAGER="${TCAT:-lpr}"
printing=yes ;;
-M)
mpath="$2"
shift;;
*) break;;
esac
shift
done
local MANPATH="$mpath"
case "$1" in
-f | -k)
local g a
if [ "$1" = "-f" ]; then
g="grep -w"
a=$(basename "$2")
else
g="grep -F"
a="$2"
fi
whatis_internal "$a" "$g"
;;
[0-9npol] | [0-9][a-z]* | new | public | old | local)
if [ "$1" = "new" ]; then
num=n
elif [ "$1" = "public" ]; then
num=p
elif [ "$1" = "old" ]; then
num=o
elif [ "$1" = "local" ]; then
num=l
else
num="$1"
fi
shift
manpage "$num" "$1" "$printing"
;;
*)
manpage "$num" "$1" "$printing"
;;
esac
}
+16
View File
@@ -0,0 +1,16 @@
# To: chet@ins.CWRU.Edu
# Subject: Bash functions
# From: Sandeep Mehta <sxm@philabs.Philips.Com>
# print MH folders, useful only because folders(1) doesn't print
# mod date/times
mhfold()
{
list=`folders | awk '{if (1 < NR) print $1}'`
/bin/ls -lag ~/Mail > /tmp/fold$$
for i in $list; do
grep $i /tmp/fold$$
done
/bin/rm -f /tmp/fold$$
}
@@ -0,0 +1,58 @@
trap _notify CHLD
NOTIFY_ALL=false
unset NOTIFY_LIST
unalias false
false()
{
return 1
}
_notify ()
{
local i j
local newlist=
if $NOTIFY_ALL
then
return # let bash take care of this itself
elif [ -z "$NOTIFY_LIST" ]; then
return
else
set -- $NOTIFY_LIST
for i in "$@"
do
j=$(jobs -n %$i)
if [ -n "$j" ]; then
echo "$j"
jobs -n %$i >/dev/null
else
newlist="newlist $i"
fi
done
NOTIFY_LIST="$newlist"
fi
}
notify ()
{
local i j
if [ $# -eq 0 ]; then
NOTIFY_ALL=:
set -b
return
else
for i in "$@"
do
# turn a valid job spec into a job number
j=$(jobs $i)
case "$j" in
[*) j=${j%%]*}
j=${j#[}
NOTIFY_LIST="$NOTIFY_LIST $j"
;;
esac
done
fi
}
@@ -0,0 +1,45 @@
#From: "Simon J. Gerraty" <sjg@zen.void.oz.au>
#Message-Id: <199510091130.VAA01188@zen.void.oz.au>
#Subject: Re: a shell idea?
#Date: Mon, 09 Oct 1995 21:30:20 +1000
# NAME:
# add_path.sh - add dir to path
#
# DESCRIPTION:
# These functions originated in /etc/profile and ksh.kshrc, but
# are more useful in a separate file.
#
# SEE ALSO:
# /etc/profile
#
# AUTHOR:
# Simon J. Gerraty <sjg@zen.void.oz.au>
# @(#)Copyright (c) 1991 Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
# Permission to copy, redistribute or otherwise
# use this file is hereby granted provided that
# the above copyright notice and this notice are
# left intact.
# is $1 missing from $2 (or PATH) ?
no_path() {
eval "case :\$${2-PATH}: in *:$1:*) return 1;; *) return 0;; esac"
}
# if $1 exists and is not in path, append it
add_path () {
[ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="\$${2:-PATH}:$1"
}
# if $1 exists and is not in path, prepend it
pre_path () {
[ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="$1:\$${2:-PATH}"
}
# if $1 is in path, remove it
del_path () {
no_path $* || eval ${2:-PATH}=`eval echo :'$'${2:-PATH}: |
sed -e "s;:$1:;:;g" -e "s;^:;;" -e "s;:\$;;"`
}
+63
View File
@@ -0,0 +1,63 @@
#!/bin/bash
#From: kaz@ashi.footprints.net (Kaz Kylheku)
#Newsgroups: comp.os.linux.misc
#Subject: Re: bash question: subdirectories
#Message-ID: <slrn8a0gu9.v5n.kaz@ashi.FootPrints.net>
#Date: Tue, 08 Feb 2000 16:24:35 GMT
#Actually it can be made to. That is to say, it is possible to code a recursive
#descender function in the bash language. Here is an example.
#
#What is nice about this is that you can embed the function into your shell
#script. The function changes the current working directory as it descends.
#So it can handle arbitrarily deep paths. Whereas paths generated by the
#find command can cause a problem when they get too long; the kernel has a
#hard limit on the length of the string passed to the open() and other
#system calls.
#There are races; what if the directory tree is blown away during the traversal?
#The function won't be able to crawl back up using the .. link and will just
#bail.
# Recursive Directory Traverser
# Author: Kaz Kylheku
# Date: Feb 27, 1999
# Copyright 1999
# Function parameter usage:
# $1 directory to search
# $2 pattern to search for
# $3 command to execute
# $4 secret argument for passing down path
function recurse
{
local file
local path
if [ "$4" = "" ] ; then
path="${1%/}/"
else
path="$4$1/"
fi
if cd "$1" ; then
for file in $2; do
if [ -f "$file" ] || [ -d "$file" ]; then
eval "$3"
fi
done
for file in .* * ; do
if [ "$file" = "." ] || [ "$file" = ".." ] ; then
continue
fi
if [ -d "$file" ] && [ ! -L "$file" ]; then
recurse "$file" "$2" "$3" "$path"
fi
done
cd ..
fi
}
recurse "$1" "$2" 'echo "$path$file"'
+43
View File
@@ -0,0 +1,43 @@
# To: chet@ins.CWRU.Edu
# Subject: Bash functions
# From: Sandeep Mehta <sxm@philabs.Philips.Com>
##########################################
#
# repeat - clone of C shell builtin `repeat'
#
# usage: repeat <count> <command>
#
# It has been tested inside other functions and in conditionals like
# if [ "`repeat <count> <command>`" ]; then COMMANDS [ else COMMANDS ] fi
# Please send me fixes/enhancements.
#
# Sandeep Mehta <sxm@philabs.Philips.Com>
##########################################
repeat()
{
local rcount=$1
if [ $# -le 1 ] || [ -z "$rcount" ]; then
echo "usage: repeat <count> <command>" 1>&2
return 2
fi
shift
local acmd=("$@")
if [ $rcount -le 0 ]; then
echo "count must be greater than 0"
echo "usage: repeat <count> <command>" 1>&2
return 2
fi
st=0
while [ $rcount -gt 0 ]; do
eval "${acmd[@]}"
st=$?
rcount=$((rcount - 1))
done
return $st
}
+12
View File
@@ -0,0 +1,12 @@
# From psamuels@jake.niar.twsu.edu (Peter Samuelson)
# posted to usenet, Message-ID: <6rtp8j$2a0$1@jake.niar.twsu.edu>
repeat ()
{
local i max; # note that you can use \$i in the command string
max=$1; shift;
i=1; while ((i <= max)); do
eval "$@"; ((i = i + 1));
done;
}
+29
View File
@@ -0,0 +1,29 @@
# Generate a sequence from m to n, m defaults to 1.
seq ()
{
declare -i lo hi i # makes local
local _SEQ
case $# in
1) seq 1 "$1" ; return $? ;;
2) lo=$1 hi=$2
i=$lo _SEQ=""
while let "i <= hi"; do
_SEQ="${_SEQ}$i "
let i+=1
done
echo "${_SEQ# }"
return 0 ;;
*) echo seq: usage: seq [low] high 1>&2 ; return 2 ;;
esac
}
# like the APL `iota' function (or at least how I remember it :-)
iota()
{
case $# in
1) seq 1 "$1"; return $?;;
*) echo "iota: usage: iota high" 1>&2; return 2;;
esac
}
+37
View File
@@ -0,0 +1,37 @@
# Generate a sequence from m to n, m defaults to 1.
seq ()
{
declare -i lo hi i # makes local
local _SEQ INIT COMPARE STEP
case "$1" in
-r) INIT='i=$hi _SEQ=""' COMPARE='let "i >= $lo"' STEP='let i-=1' ; shift ;;
*) INIT='i=$lo _SEQ=""' COMPARE='let "i <= $hi"' STEP='let i+=1' ;;
esac
case $# in
1) lo=1 hi="$1" ;;
2) lo=$1 hi=$2 ;;
*) echo seq: usage: seq [-r] [low] high 1>&2 ; return 2 ;;
esac
# equivalent to the as-yet-unimplemented
# for (( "$INIT" ; "$COMPARE" ; "$STEP" )); do _SEQ="${_SEQ}$i "; done
eval "$INIT"
while eval "$COMPARE"; do
_SEQ="${_SEQ}$i "
eval "$STEP"
done
echo "${_SEQ# }"
return 0
}
# like the APL `iota' function (or at least how I remember it :-)
iota()
{
case $# in
1) seq 1 "$1"; return $?;;
*) echo "iota: usage: iota high" 1>&2; return 2;;
esac
}
+7
View File
@@ -0,0 +1,7 @@
shcat()
{
while read -r line
do
echo "$line"
done
}
+19
View File
@@ -0,0 +1,19 @@
shcat()
{
while read -r line
do
echo "$line"
done
}
shcat2()
{
while [ $# -ge 1 ]; do
case "$1" in
-) shcat ;;
*) shcat < "$1" ;;
esac
shift
done
exit 0
}
@@ -0,0 +1,50 @@
# Sort the positional paramters.
# Make sure the positional parameters are passed as arguments to the function.
# If -u is the first arg, remove duplicate array members.
sort_posparams()
{
local -a R
local u
case "$1" in
-u) u=-u ; shift ;;
esac
# if you want the case of no positional parameters to return success,
# remove the error message and return 0
if [ $# -eq 0 ]; then
echo "$FUNCNAME: argument expected" >&2
return 1
fi
# make R a copy of the positional parameters
R=( "${@}" )
# sort R.
R=( $( printf "%s\n" "${R[@]}" | sort $u) )
printf "%s\n" "${R[@]}"
return 0
}
# will print everything on separate lines
set -- 3 1 4 1 5 9 2 6 5 3 2
sort_posparams "$@"
# sets without preserving quoted parameters
set -- $( sort_posparams "$@" )
echo "$@"
echo $#
# sets preserving quoted parameters, beware pos params with embedded newlines
set -- 'a b' 'a c' 'x z'
oifs=$IFS
IFS=$'\n'
set -- $( sort_posparams "$@" )
IFS="$oifs"
echo "$@"
echo $#
sort_posparams
+21
View File
@@ -0,0 +1,21 @@
#From: Syamala Rao Tadigadapa <stadigad@us.oracle.com>
#Subject: Re: Division in ksh(getting the exact number) Please HELP
#Date: Mon, 25 Oct 1999 15:05:08 -0700
#Message-ID: <3814D414.7B896084@us.oracle.com>
#Here is how to calculate the (integer part of the) square root
#of a number in a much cleaner way.
sqroot()
{
let arg=$1
let root=arg
while :
do
newroot=$(( (root+arg/root)/2 ))
(( newroot == root )) && { echo $root; return; }
let root=newroot
done
}
sqroot "$@"
+79
View File
@@ -0,0 +1,79 @@
#
# substr -- a function to emulate the ancient ksh builtin
#
#
# -l == shortest from left
# -L == longest from left
# -r == shortest from right (the default)
# -R == longest from right
substr()
{
local flag pat str
local usage="usage: substr -lLrR pat string or substr string pat"
case "$1" in
-l | -L | -r | -R)
flag="$1"
pat="$2"
shift 2
;;
-*)
echo "substr: unknown option: $1"
echo "$usage"
return 1
;;
*)
flag="-r"
pat="$2"
;;
esac
if [ "$#" -eq 0 ] || [ "$#" -gt 2 ] ; then
echo "substr: bad argument count"
return 2
fi
str="$1"
#
# We don't want -f, but we don't want to turn it back on if
# we didn't have it already
#
case "$-" in
"*f*")
;;
*)
fng=1
set -f
;;
esac
case "$flag" in
-l)
str="${str#$pat}" # substr -l pat string
;;
-L)
str="${str##$pat}" # substr -L pat string
;;
-r)
str="${str%$pat}" # substr -r pat string
;;
-R)
str="${str%%$pat}" # substr -R pat string
;;
*)
str="${str%$2}" # substr string pat
;;
esac
echo "$str"
#
# If we had file name generation when we started, re-enable it
#
if [ "$fng" = "1" ] ; then
set +f
fi
}
+81
View File
@@ -0,0 +1,81 @@
#
# substr -- a function to emulate the ancient ksh builtin
#
# -l == remove shortest from left
# -L == remove longest from left
# -r == remove shortest from right (the default)
# -R == remove longest from right
substr()
{
local flag pat str
local usage="usage: substr -lLrR pat string or substr string pat"
local options="l:L:r:R:"
OPTIND=1
while getopts "$options" c
do
case "$c" in
l | L | r | R)
flag="-$c"
pat="$OPTARG"
;;
'?')
echo "$usage"
return 1
;;
esac
done
if [ "$OPTIND" -gt 1 ] ; then
shift $[ $OPTIND -1 ]
fi
if [ "$#" -eq 0 ] || [ "$#" -gt 2 ] ; then
echo "substr: bad argument count"
return 2
fi
str="$1"
#
# We don't want -f, but we don't want to turn it back on if
# we didn't have it already
#
case "$-" in
"*f*")
;;
*)
fng=1
set -f
;;
esac
case "$flag" in
-l)
str="${str#$pat}" # substr -l pat string
;;
-L)
str="${str##$pat}" # substr -L pat string
;;
-r)
str="${str%$pat}" # substr -r pat string
;;
-R)
str="${str%%$pat}" # substr -R pat string
;;
*)
str="${str%$2}" # substr string pat
;;
esac
echo "$str"
#
# If we had file name generation when we started, re-enable it
#
if [ "$fng" = "1" ] ; then
set +f
fi
}
+35
View File
@@ -0,0 +1,35 @@
#
# term -- a shell function to set the terminal type interactively or not.
#
term()
{
local t
if [ $# != 0 ] ; then
eval $(tset -sQ $1)
else # interactive
if [ -z "$TERM" ] ; then
TERM="unknown"
fi
case "$TERM" in
network|dialup|unknown|lat)
TERM=unknown
;;
*)
eval $(tset -sQ)
;;
esac
while [ "$TERM" = "unknown" ] ; do
echo -n "Terminal type: "
read t
if [ -n "$t" ] ; then
eval $(tset -sQ $t)
fi
done
fi
}
+52
View File
@@ -0,0 +1,52 @@
#
# whatis -- and implementation of the 10th Edition Unix sh builtin `whatis'
# command.
#
# usage: whatis arg [...]
#
# For each argument, whatis prints the associated value as a parameter,
# builtin, function, alias, or executable file as appropriate. In each
# case, the value is printed in a form which would yield the same value
# if typed as input to the shell itself.
#
whatis()
{
local wusage='usage: whatis arg [arg...]'
local fail=0
if [ $# -eq 0 ] ; then
echo "$wusage"
return 1
fi
for arg
do
case $(builtin type -type $arg 2>/dev/null) in
"alias")
builtin alias "$arg"
;;
"function")
builtin type "$arg" | sed 1d
;;
"builtin")
echo builtin "$arg"
;;
"file")
builtin type -path "$arg"
;;
*)
# OK, we could have a variable, or we could have nada
if [ "$(eval echo \${$arg+set})" = "set" ] ; then
# It is a variable, and it is set
echo -n "$arg="
eval echo '\"'\$$arg'\"'
else
echo whatis: $arg: not found
fail=1
fi
;;
esac
done
return $fail
}
+59
View File
@@ -0,0 +1,59 @@
#
# An almost-ksh compatible `whence' command. This is as hairy as it is
# because of the desire to exactly mimic ksh.
#
# This depends somewhat on knowing the format of the output of the bash
# `builtin type' command.
#
# Chet Ramey
# chet@ins.CWRU.Edu
#
whence()
{
local vflag= path=
if [ "$#" = "0" ] ; then
echo "whence: argument expected"
return 1
fi
case "$1" in
-v) vflag=1
shift 1
;;
-*) echo "whence: bad option: $1"
return 1
;;
*) ;;
esac
if [ "$#" = "0" ] ; then
echo "whence: bad argument count"
return 1
fi
for cmd
do
if [ "$vflag" ] ; then
echo $(builtin type $cmd | sed 1q)
else
path=$(builtin type -path $cmd)
if [ "$path" ] ; then
echo $path
else
case "$cmd" in
/*) if [ -x "$cmd" ]; then
echo "$cmd"
fi
;;
*) case "$(builtin type -type $cmd)" in
"") ;;
*) echo "$cmd"
;;
esac
;;
esac
fi
fi
done
return 0
}
+44
View File
@@ -0,0 +1,44 @@
#
# which - emulation of `which' as it appears in FreeBSD
#
# usage: which [-as] command [command...]
#
which()
{
local aflag sflag ES a opt
OPTIND=1
while builtin getopts as opt ; do
case "$opt" in
a) aflag=-a ;;
s) sflag=1 ;;
?) echo "which: usage: which [-as] command [command ...]" >&2
exit 2 ;;
esac
done
(( $OPTIND > 1 )) && shift $(( $OPTIND - 1 ))
# without command arguments, exit with status 1
ES=1
# exit status is 0 if all commands are found, 1 if any are not found
for command; do
# if $command is a function, make sure we add -a so type
# will look in $PATH after finding the function
a=$aflag
case "$(builtin type -t $command)" in
"function") a=-a;;
esac
if [ -n "$sflag" ]; then
builtin type -p $a $command >/dev/null 2>&1
else
builtin type -p $a $command
fi
ES=$?
done
return $ES
}
@@ -0,0 +1,22 @@
# xalias - convert csh alias commands to bash functions
# from Mohit Aron <aron@cs.rice.edu>
# posted to usenet as <4i5p17$bnu@larry.rice.edu>
function xalias ()
{
if [ "x$2" = "x" ]
then
declare -f $1
else
case $2 in
*[#\!]*)
comm=$(echo $2 | sed 's/\\!\*/\"$\@\"/g
s/\\!:\([1-9]\)/\"$\1\"/g
s/#/\\#/g')
;;
*)
comm="$2 \"\$@\"" ;;
esac
eval function $1 \(\) "{" command "$comm" "; }"
fi
}
@@ -0,0 +1,52 @@
#! /bin/bash
#From: kaz@cafe.net (Kaz Kylheku)
#Newsgroups: comp.unix.shell
#Subject: Why not roll your own @#$% find! (was: splitting directory off from filename)
#Message-ID: <6n1117$tp1@espresso.cafe.net>
#Date: Fri, 26 Jun 1998 20:47:34 GMT
# $1 = dirname, $2 = pattern, optional $3 = action
xfind()
{
local x
local dir="$1"
# descend into specified directory
builtin cd -L "$1" || {
echo "${FUNCNAME}: cannot change dir to $1" >&2
return 1
}
#
# default action is to print the filename
#
if [ -n "$3" ]; then
action="$3"
else
action='printf -- "%s\n"'
fi
# process ordinary files that match pattern
for x in $2 ; do
if [ -f "$x" ] ; then
eval "$action" "$x"
fi
done
# now descend into subdirectories, avoiding symbolic links
# and directories that start with a period.
for x in * ; do
if [ -d "$x" ] && [ ! -L "$x" ] ; then
$FUNCNAME "$x" "$2" "$action"
fi
done
# finally, pop back up
builtin cd -L ..
}
#xfind "$@"