mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-25 14:55:25 +02:00
bash-20130308 additional cleanup
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
#Date: Wed, 31 Jan 2001 12:53:56 -0800
|
||||
#From: Aaron Smith <aaron@mutex.org>
|
||||
#To: freebsd-ports@freebsd.org
|
||||
#Subject: useful bash completion function for pkg commands
|
||||
#Message-ID: <20010131125356.G52003@gelatinous.com>
|
||||
|
||||
#hi all. i just wanted to share this bash completion function i wrote that
|
||||
#completes package names for pkg_info and pkg_delete. i find this a great
|
||||
#help when dealing with port management. programmed completion requires
|
||||
#bash-2.04.
|
||||
|
||||
_pkg_func ()
|
||||
{
|
||||
local cur
|
||||
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
|
||||
if [[ $cur == '-' ]]; then
|
||||
if [[ ${COMP_WORDS[0]} == 'pkg_info' ]]; then
|
||||
COMPREPLY=(-a -c -d -D -i -k -r -R -p -L -q -I -m -v -e -l)
|
||||
return 0;
|
||||
elif [[ ${COMP_WORDS[0]} == 'pkg_delete' ]]; then
|
||||
COMPREPLY=(-v -D -d -n -f -p)
|
||||
return 0;
|
||||
fi
|
||||
fi
|
||||
|
||||
COMPREPLY=( $(compgen -d /var/db/pkg/$cur | sed sN/var/db/pkg/NNg) )
|
||||
return 0
|
||||
}
|
||||
complete -F _pkg_func pkg_delete pkg_info
|
||||
@@ -1,43 +0,0 @@
|
||||
#
|
||||
# Originally from:
|
||||
#
|
||||
#Message-ID: <3B13EC65.179451AE@wanadoo.fr>
|
||||
#Date: Tue, 29 May 2001 20:37:25 +0200
|
||||
#From: Manu Rouat <emmanuel.rouat@wanadoo.fr>
|
||||
#Subject: [bash] Universal command options completion?
|
||||
#
|
||||
#
|
||||
#In the recent versions of bash (after 2.04) programmable
|
||||
#completion is available. A useful completion function
|
||||
#is , for a particular command, to enumerate all flags
|
||||
#that can be used in the command. Now, most GNU unix
|
||||
#commands have so-called 'long options' for example:
|
||||
#
|
||||
#ls --color=always --no-group --size
|
||||
#
|
||||
#and these are all listed when you issue a '--help' flag.
|
||||
#So the idea is to use that, then parse the output of the
|
||||
#'--help' and reinject this to compgen. The basis of the
|
||||
#following 'universal' completion funtion was the _configure_func'
|
||||
#written by Ian McDonnald (or is it Chet Ramey ?)
|
||||
#A dedicated function will always be better, but this is quite
|
||||
#convenient. I chose to use 'long options' because they are
|
||||
#easy to parse and explicit too (it's the point I guess...)
|
||||
#Lots of room for improvement !
|
||||
|
||||
_longopt_func ()
|
||||
{
|
||||
case "$2" in
|
||||
-*) ;;
|
||||
*) return ;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
\~*) eval cmd=$1 ;;
|
||||
*) cmd="$1" ;;
|
||||
esac
|
||||
COMPREPLY=( $("$cmd" --help | sed -e '/--/!d' -e 's/.*--\([^ ]*\).*/--\1/'| \
|
||||
grep ^"$2" |sort -u) )
|
||||
}
|
||||
|
||||
complete -o default -F _longopt_func ldd wget bash id info # some examples that work
|
||||
@@ -1,433 +0,0 @@
|
||||
#####
|
||||
#To: chet@po.cwru.edu, sarahmckenna@lucent.com
|
||||
#Message-Id: <slrn8mqioc.msb.ian@lovelorn.linuxcare.com>
|
||||
#Posted-To: comp.unix.shell, gnu.bash.bug
|
||||
#Subject: bash 2.04 programmable completion examples
|
||||
#Reply-To: ian@linuxcare.com, ian@caliban.org
|
||||
#Summary: examples of programmable completion for bash 2.04
|
||||
#Date: Thu, 13 Jul 2000 00:52:33 -0400 (EDT)
|
||||
#From: ianmacd@linuxcare.com (Ian Macdonald)
|
||||
#####
|
||||
|
||||
#########################################################################
|
||||
# Turn on extended globbing
|
||||
shopt -s extglob
|
||||
|
||||
# A lot of the following one-liners were taken directly from the
|
||||
# completion examples provided with the bash 2.04 source distribution
|
||||
|
||||
# Make directory commands see only directories
|
||||
complete -d cd mkdir rmdir pushd
|
||||
|
||||
# Make file commands see only files
|
||||
complete -f cat less more chown ln strip
|
||||
complete -f -X '*.gz' gzip
|
||||
complete -f -X '*.Z' compress
|
||||
complete -f -X '!*.+(Z|gz|tgz|Gz)' gunzip zcat zmore
|
||||
complete -f -X '!*.Z' uncompress zmore zcat
|
||||
complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|bmp)' ee xv
|
||||
complete -f -X '!*.+(ps|PS|ps.gz)' gv
|
||||
complete -f -X '!*.+(dvi|DVI)' dvips xdvi dviselect dvitype
|
||||
complete -f -X '!*.+(pdf|PDF)' acroread xpdf
|
||||
complete -f -X '!*.texi*' makeinfo texi2dvi texi2html
|
||||
complete -f -X '!*.+(tex|TEX)' tex latex slitex
|
||||
complete -f -X '!*.+(mp3|MP3)' mpg123
|
||||
|
||||
# kill sees only signals
|
||||
complete -A signal kill -P '%'
|
||||
|
||||
# user commands see only users
|
||||
complete -u finger su usermod userdel passwd
|
||||
|
||||
# bg completes with stopped jobs
|
||||
complete -A stopped -P '%' bg
|
||||
|
||||
# other job commands
|
||||
complete -j -P '%' fg jobs disown
|
||||
|
||||
# network commands complete with hostname
|
||||
complete -A hostname ssh rsh telnet rlogin ftp ping fping host traceroute \
|
||||
nslookup
|
||||
|
||||
# export and others complete with shell variables
|
||||
complete -v export local readonly unset
|
||||
|
||||
# set completes with set options
|
||||
complete -A setopt set
|
||||
|
||||
# shopt completes with shopt options
|
||||
complete -A shopt shopt
|
||||
|
||||
# helptopics
|
||||
complete -A helptopic help
|
||||
|
||||
# unalias completes with aliases
|
||||
complete -a unalias
|
||||
|
||||
# various commands complete with commands
|
||||
complete -c command type nohup exec nice eval strace gdb
|
||||
|
||||
# bind completes with readline bindings (make this more intelligent)
|
||||
complete -A binding bind
|
||||
|
||||
# Now we get to the meat of the file, the functions themselves. Some
|
||||
# of these are works in progress. Most assume GNU versions of the
|
||||
# tools in question and may require modifications for use on vanilla
|
||||
# UNIX systems.
|
||||
#
|
||||
# A couple of functions may have non-portable, Linux specific code in
|
||||
# them, but this will be noted where applicable
|
||||
|
||||
|
||||
# GNU chown(1) completion. This should be expanded to allow the use of
|
||||
# ':' as well as '.' as the user.group separator.
|
||||
#
|
||||
_chown ()
|
||||
{
|
||||
local cur prev user group
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
# do not attempt completion if we're specifying an option
|
||||
if [ "${cur:0:1}" = "-" ]; then return 0; fi
|
||||
|
||||
# first parameter on line or first since an option?
|
||||
if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then
|
||||
case "$cur" in
|
||||
[a-zA-Z]*.*)
|
||||
user=${cur%.*}
|
||||
group=${cur#*.}
|
||||
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
|
||||
{if ($1 ~ /^'$group'/) print $1}' \
|
||||
/etc/group ) )
|
||||
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
||||
COMPREPLY[i]=$user.${COMPREPLY[i]}
|
||||
done
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( compgen -u $cur -S '.' ) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
else
|
||||
COMPREPLY=( $( compgen -f $cur ) )
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
complete -F _chown chown
|
||||
|
||||
# umount(8) completion. This relies on the mount point being the third
|
||||
# space-delimited field in the output of mount(8)
|
||||
#
|
||||
_umount ()
|
||||
{
|
||||
local cur
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
|
||||
# could rewrite the cut | grep to be a sed command, but this is
|
||||
# clearer and doesn't result in much overhead
|
||||
COMPREPLY=( $( mount | cut -d' ' -f 3 | grep ^$cur) )
|
||||
return 0
|
||||
}
|
||||
complete -F _umount umount
|
||||
|
||||
# GID completion. This will get a list of all valid group names from
|
||||
# /etc/group and should work anywhere.
|
||||
#
|
||||
_gid_func ()
|
||||
{
|
||||
local cur
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
COMPREPLY=( $( awk 'BEGIN {FS=":"} {if ($1 ~ /^'$cur'/) print $1}' \
|
||||
/etc/group ) )
|
||||
return 0
|
||||
}
|
||||
complete -F _gid_func groupdel groupmod
|
||||
|
||||
# mount(8) completion. This will pull a list of possible mounts out of
|
||||
# /etc/fstab, unless the word being completed contains a ':', which
|
||||
# would indicate the specification of an NFS server. In that case, we
|
||||
# query the server for a list of all available exports and complete on
|
||||
# that instead.
|
||||
#
|
||||
_mount ()
|
||||
|
||||
{ local cur
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
|
||||
case "$cur" in
|
||||
*:*)
|
||||
COMPREPLY=( $( /usr/sbin/showmount -e --no-headers ${cur%%:*} |\
|
||||
grep ^${cur#*:} | awk '{print $1}'))
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( awk '{if ($2 ~ /\//) print $2}' /etc/fstab | \
|
||||
grep ^$cur ))
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
complete -F _mount mount
|
||||
|
||||
# Linux rmmod(1) completion. This completes on a list of all currently
|
||||
# installed kernel modules.
|
||||
#
|
||||
_rmmod ()
|
||||
{
|
||||
local cur
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
|
||||
COMPREPLY=($( lsmod | awk '{if (NR != 1 && $1 ~ /^'$cur'/) print $1}'))
|
||||
return 0
|
||||
}
|
||||
complete -F _rmmod rmmod
|
||||
|
||||
# Linux insmod(1) completion. This completes on a list of all
|
||||
# available modules for the version of the kernel currently running.
|
||||
#
|
||||
_insmod ()
|
||||
{
|
||||
local cur modpath
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
modpath=/lib/modules/`uname -r`
|
||||
|
||||
COMPREPLY=($( ls -R $modpath | sed -ne 's/^\('$cur'.*\)\.o$/\1/p'))
|
||||
return 0
|
||||
}
|
||||
complete -F _insmod insmod depmod modprobe
|
||||
|
||||
# man(1) completion. This relies on the security enhanced version of
|
||||
# GNU locate(1). UNIX variants having non-numeric man page sections
|
||||
# other than l, m and n should add the appropriate sections to the
|
||||
# first clause of the case statement.
|
||||
#
|
||||
# This is Linux specific, in that 'man <section> <page>' is the
|
||||
# expected syntax. This allows one to do something like
|
||||
# 'man 3 str<tab>' to obtain a list of all string handling syscalls on
|
||||
# the system.
|
||||
#
|
||||
_man ()
|
||||
{
|
||||
local cur prev
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
[0-9lmn])
|
||||
COMPREPLY=($( slocate -ql 0 -r '/man/man'$prev'/'$cur | \
|
||||
sed -ne 's/^.*\/\('$cur'[^.\/]*\)\..*$/\1/p' ))
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=($( slocate -ql 0 -r '/man/man./'$cur | \
|
||||
sed -ne 's/^.*\/\('$cur'[^.\/]*\)\..*$/\1/p' ))
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
complete -F _man man
|
||||
|
||||
# Linux killall(1) completion. This wouldn't be much use on, say,
|
||||
# Solaris, where killall does exactly that: kills ALL processes.
|
||||
#
|
||||
# This could be improved. For example, it currently doesn't take
|
||||
# command line options into account
|
||||
#
|
||||
_killall ()
|
||||
{
|
||||
local cur prev
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
-[A-Z0-9]*)
|
||||
# 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=( $( ps ahx | awk '{if ($5 ~ /^'$cur'/) print $5}' | \
|
||||
sed -e 's#[]\[]##g' -e 's#^.*/##' ))
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# first parameter can be either a signal or a process
|
||||
if [ $COMP_CWORD -eq 1 ]; then
|
||||
# standard signal completion is rather braindead, so we need
|
||||
# to hack around to get what we want here, which is to
|
||||
# complete on a dash, followed by the signal name minus
|
||||
# the SIG prefix
|
||||
COMPREPLY=( $( compgen -A signal SIG${cur#-} ))
|
||||
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
||||
COMPREPLY[i]=-${COMPREPLY[i]#SIG}
|
||||
done
|
||||
fi
|
||||
|
||||
# get processes, adding to signals if applicable
|
||||
COMPREPLY=( ${COMPREPLY[*]} $( ps ahx | \
|
||||
awk '{if ($5 ~ /^'$cur'/) print $5}' | \
|
||||
sed -e 's#[]\[]##g' -e 's#^.*/##' ))
|
||||
return 0
|
||||
}
|
||||
complete -F _killall killall
|
||||
|
||||
# GNU find(1) completion. This makes heavy use of ksh style extended
|
||||
# globs and contains Linux specific code for completing the parameter
|
||||
# to the -fstype option.
|
||||
#
|
||||
_find ()
|
||||
{
|
||||
local cur prev
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]#-}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
-@(max|min)depth)
|
||||
COMPREPLY=( $( compgen -W '0 1 2 3 4 5 6 7 8 9' ) )
|
||||
return 0
|
||||
;;
|
||||
-?(a)newer|-fls|-fprint?(0|f))
|
||||
COMPREPLY=( $( compgen -f $cur ) )
|
||||
return 0
|
||||
;;
|
||||
-fstype)
|
||||
# this is highly non-portable (the option to -d is a tab)
|
||||
COMPREPLY=( $( cut -d' ' -f 2 /proc/filesystems | grep ^$cur ) )
|
||||
return 0
|
||||
;;
|
||||
-gid)
|
||||
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
|
||||
{if ($3 ~ /^'$cur'/) print $3}' /etc/group ) )
|
||||
return 0
|
||||
;;
|
||||
-group)
|
||||
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
|
||||
{if ($1 ~ /^'$cur'/) print $1}' /etc/group ) )
|
||||
return 0
|
||||
;;
|
||||
-?(x)type)
|
||||
COMPREPLY=( $( compgen -W 'b c d p f l s' $cur ) )
|
||||
return 0
|
||||
;;
|
||||
-uid)
|
||||
COMPREPLY=( $( awk 'BEGIN {FS=":"} \
|
||||
{if ($3 ~ /^'$cur'/) print $3}' /etc/passwd ) )
|
||||
return 0
|
||||
;;
|
||||
-user)
|
||||
COMPREPLY=( $( compgen -u $cur ) )
|
||||
return 0
|
||||
;;
|
||||
-[acm]min|-[acm]time|-?(i)?(l)name|-inum|-?(i)path|-?(i)regex| \
|
||||
-links|-perm|-size|-used|-exec|-ok|-printf)
|
||||
# do nothing, just wait for a parameter to be given
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# complete using basic options ($cur has had its dash removed here,
|
||||
# as otherwise compgen will bomb out with an error, since it thinks
|
||||
# the dash is an option to itself)
|
||||
COMPREPLY=( $( compgen -W 'daystart depth follow help maxdepth \
|
||||
mindepth mount noleaf version xdev amin anewer atime \
|
||||
cmin cnewer ctime empty false fstype gid group ilname \
|
||||
iname inum ipath iregex links lname mmin mtime name \
|
||||
newer nouser nogroup perm regex size true type uid \
|
||||
used user xtype exec fls fprint fprint0 fprintf ok \
|
||||
print print0 printf prune ls' $cur ) )
|
||||
|
||||
# this removes any options from the list of completions that have
|
||||
# already been specified somewhere on the command line.
|
||||
COMPREPLY=( $( echo "${COMP_WORDS[@]}-" | \
|
||||
(while read -d '-' i; do
|
||||
[ "$i" == "" ] && continue
|
||||
# flatten array with spaces on either side,
|
||||
# otherwise we cannot grep on word boundaries of
|
||||
# first and last word
|
||||
COMPREPLY=" ${COMPREPLY[@]} "
|
||||
# remove word from list of completions
|
||||
COMPREPLY=( ${COMPREPLY/ ${i%% *} / } )
|
||||
done
|
||||
echo ${COMPREPLY[@]})
|
||||
) )
|
||||
|
||||
# put dashes back
|
||||
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
||||
COMPREPLY[i]=-${COMPREPLY[i]}
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
complete -F _find find
|
||||
|
||||
# Linux ifconfig(8) completion
|
||||
#
|
||||
_ifconfig ()
|
||||
{
|
||||
local cur
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
|
||||
case "${COMP_WORDS[1]}" in
|
||||
-|*[0-9]*)
|
||||
COMPREPLY=( $( compgen -W '-a up down arp promisc allmulti \
|
||||
metric mtu dstaddr netmask add del \
|
||||
tunnel irq io_addr mem_start media \
|
||||
broadcast pointopoint hw multicast \
|
||||
address txqueuelen' $cur ))
|
||||
COMPREPLY=( $( echo " ${COMP_WORDS[@]}" | \
|
||||
(while read -d ' ' i; do
|
||||
[ "$i" == "" ] && continue
|
||||
# flatten array with spaces on either side,
|
||||
# otherwise we cannot grep on word
|
||||
# boundaries of first and last word
|
||||
COMPREPLY=" ${COMPREPLY[@]} "
|
||||
# remove word from list of completions
|
||||
COMPREPLY=( ${COMPREPLY/ $i / } )
|
||||
done
|
||||
echo ${COMPREPLY[@]})
|
||||
) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
COMPREPLY=( $( ifconfig -a | sed -ne 's/^\('$cur'[^ ]*\).*$/\1/p' ))
|
||||
}
|
||||
complete -F _ifconfig ifconfig
|
||||
|
||||
# Linux ipsec(8) completion (for FreeS/WAN). Very basic.
|
||||
#
|
||||
_ipsec ()
|
||||
{
|
||||
local cur
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
|
||||
COMPREPLY=( $( compgen -W 'auto barf eroute klipsdebug look manual \
|
||||
pluto ranbits rsasigkey setup showdefaults \
|
||||
showhostkey spi spigrp tncfg whack' $cur ))
|
||||
}
|
||||
complete -F _ipsec ipsec
|
||||
#########################################################################
|
||||
@@ -1,271 +0,0 @@
|
||||
#####
|
||||
#From: ian@linuxcare.com (Ian Macdonald)
|
||||
#Newsgroups: comp.unix.shell
|
||||
#Subject: More bash 2.04 completions
|
||||
#Date: 12 Aug 2000 09:53:40 GMT
|
||||
#Organization: Linuxcare, Inc.
|
||||
#Lines: 274
|
||||
#Message-ID: <slrn8pa7l2.jgm.ian@lovelorn.linuxcare.com>
|
||||
#Reply-To: ian@linuxcare.com
|
||||
#####
|
||||
|
||||
# Turn on extended globbing
|
||||
shopt -s extglob
|
||||
|
||||
# cvs(1) completion
|
||||
#
|
||||
_cvs ()
|
||||
{
|
||||
local cur prev
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then
|
||||
COMPREPLY=( $( compgen -W 'add admin checkout commit diff \
|
||||
export history import log rdiff release remove rtag status \
|
||||
tag update' $cur ))
|
||||
else
|
||||
COMPREPLY=( $( compgen -f $cur ))
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
complete -F _cvs cvs
|
||||
|
||||
# rpm(8) completion. This isn't exhaustive yet, but still provides
|
||||
# quite a lot of functionality.
|
||||
#
|
||||
_rpm()
|
||||
{
|
||||
dashify()
|
||||
{
|
||||
local i
|
||||
|
||||
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
||||
if [ ${#COMPREPLY[i]} -le 2 ]; then
|
||||
COMPREPLY[i]=-${COMPREPLY[i]}
|
||||
else
|
||||
COMPREPLY[i]=--${COMPREPLY[i]}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
local cur cur_nodash prev
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
cur_nodash=${cur#-}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
if [ $COMP_CWORD = 1 ]; then
|
||||
# first parameter on line
|
||||
case "$cur" in
|
||||
-b*)
|
||||
COMPREPLY=( $( compgen -W 'ba bb bc bi bl bp bs' \
|
||||
$cur_nodash ) )
|
||||
dashify
|
||||
return 0
|
||||
;;
|
||||
-t*)
|
||||
COMPREPLY=( $( compgen -W 'ta tb tc ti tl tp ts' \
|
||||
$cur_nodash ) )
|
||||
dashify
|
||||
return 0
|
||||
;;
|
||||
--*)
|
||||
COMPREPLY=( $( compgen -W 'help version initdb \
|
||||
checksig recompile rebuild resign addsign rebuilddb \
|
||||
showrc setperms setgids' ${cur_nodash#-} ) )
|
||||
dashify;
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( compgen -W 'b e F i q t U V' \
|
||||
$cur_nodash ) )
|
||||
dashify
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case "${COMP_WORDS[1]}" in
|
||||
-[iFU]*)
|
||||
# complete on list of relevant options
|
||||
COMPREPLY=( $( compgen -W 'percent force test replacepkgs \
|
||||
replacefiles root excludedocs includedocs noscripts rcfile \
|
||||
ignorearch dbpath prefix ignoreos nodeps allfiles ftpproxy \
|
||||
ftpport justdb httpproxy httpport noorder relocate badreloc \
|
||||
notriggers excludepath ignoresize oldpackage' ${cur_nodash#-} ))
|
||||
dashify;
|
||||
# return if $cur is an option
|
||||
[ "${cur:0:1}" = "-" ] && return 0
|
||||
# add a list of RPMS to possible completions
|
||||
COMPREPLY=( ${COMPREPLY[@]} $( compgen -G $cur\*.rpm ) )
|
||||
return 0
|
||||
;;
|
||||
-qp*)
|
||||
# complete on list of relevant options
|
||||
COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \
|
||||
whatrequires requires triggeredby ftpport ftpproxy httpproxy \
|
||||
httpport provides triggers dump changelog dbpath filesbypkg' \
|
||||
${cur_nodash#-} ) )
|
||||
dashify;
|
||||
# return if $cur is an option
|
||||
[ "${cur:0:1}" = "-" ] && return 0
|
||||
# add a list of RPMS to possible completions
|
||||
COMPREPLY=( ${COMPREPLY[@]} $( compgen -G $cur\*.rpm ) )
|
||||
return 0
|
||||
;;
|
||||
-*f)
|
||||
# standard filename completion
|
||||
COMPREPLY=( $( compgen -f $cur ) )
|
||||
return 0
|
||||
;;
|
||||
-e)
|
||||
# complete on list of relevant options
|
||||
COMPREPLY=( $( compgen -W 'allmatches noscripts notriggers \
|
||||
nodeps test' ${cur_nodash#-} ) )
|
||||
dashify;
|
||||
# return if $cur is an option
|
||||
[ "${cur:0:1}" = "-" ] && return 0
|
||||
# complete on basename of installed RPMs
|
||||
COMPREPLY=( $( rpm -qa | \
|
||||
sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) )
|
||||
return 0
|
||||
;;
|
||||
-qa*)
|
||||
# complete on list of relevant options
|
||||
COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \
|
||||
whatrequires requires triggeredby ftpport ftpproxy httpproxy \
|
||||
httpport provides triggers dump changelog dbpath specfile \
|
||||
querybynumber last filesbypkg' ${cur_nodash#-} ) )
|
||||
dashify;
|
||||
return 0
|
||||
;;
|
||||
-q*)
|
||||
# complete on list of relevant options
|
||||
COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \
|
||||
whatrequires requires triggeredby ftpport ftpproxy httpproxy \
|
||||
httpport provides triggers dump changelog dbpath specfile \
|
||||
querybynumber last filesbypkg' ${cur_nodash#-} ) )
|
||||
dashify;
|
||||
# return if $cur is an option
|
||||
[ "${cur:0:1}" = "-" ] && return 0
|
||||
# add a list of RPMS to possible completions
|
||||
COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
|
||||
sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) )
|
||||
return 0
|
||||
;;
|
||||
-[Vy]*)
|
||||
# complete on list of relevant options
|
||||
COMPREPLY=( $( compgen -W 'root rcfile dbpath nodeps nofiles \
|
||||
noscripts nomd5 nopgp' ${cur_nodash#-} ) )
|
||||
dashify;
|
||||
# return if $cur is an option
|
||||
[ "${cur:0:1}" = "-" ] && return 0
|
||||
# add a list of RPMS to possible completions
|
||||
COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
|
||||
sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) )
|
||||
return 0
|
||||
;;
|
||||
-b*)
|
||||
# complete on list of relevant options
|
||||
COMPREPLY=( $( compgen -W 'short-circuit timecheck clean \
|
||||
rmsource test sign buildroot target buildarch buildos' \
|
||||
${cur_nodash#-} ) )
|
||||
dashify;
|
||||
# return if $cur is an option
|
||||
[ "${cur:0:1}" = "-" ] && return 0
|
||||
# complete on .spec files
|
||||
COMPREPLY=( $( compgen -G $cur\*.spec ) )
|
||||
return 0
|
||||
;;
|
||||
-t*)
|
||||
# complete on list of relevant options
|
||||
COMPREPLY=( $( compgen -W 'short-circuit timecheck clean \
|
||||
rmsource test sign buildroot target buildarch buildos' \
|
||||
${cur_nodash#-} ) )
|
||||
dashify;
|
||||
# return if $cur is an option
|
||||
[ "${cur:0:1}" = "-" ] && return 0
|
||||
# complete on .tar.gz files
|
||||
COMPREPLY=( $( compgen -G $cur\*.tar.gz ) )
|
||||
return 0
|
||||
;;
|
||||
--re@(build|compile))
|
||||
# complete on source RPMs
|
||||
COMPREPLY=( $( compgen -G $cur\*.src.rpm ) )
|
||||
return 0
|
||||
;;
|
||||
--@(checksig|@(re|add)sign))
|
||||
# complete on RPMs
|
||||
COMPREPLY=( $( compgen -G $cur\*.rpm ) )
|
||||
return 0
|
||||
;;
|
||||
--set@(perms|gids))
|
||||
# complete on installed RPMs
|
||||
COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \
|
||||
sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
complete -F _rpm rpm
|
||||
|
||||
# chsh(1) completion
|
||||
#
|
||||
_chsh()
|
||||
{
|
||||
local cur prev
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
if [ "$prev" = "-s" ]; then
|
||||
COMPREPLY=( $( chsh -l | grep ^$cur ) )
|
||||
else
|
||||
COMPREPLY=( $( compgen -u $cur ) )
|
||||
fi
|
||||
}
|
||||
complete -F _chsh chsh
|
||||
|
||||
# chkconfig(8) completion
|
||||
#
|
||||
_chkconfig()
|
||||
{
|
||||
local cur prev
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
cur_nodash=${cur#--}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
if [ $COMP_CWORD -eq 1 ]; then
|
||||
COMPREPLY=( $( compgen -W 'list add del level' $cur_nodash ) )
|
||||
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
|
||||
COMPREPLY[i]=--${COMPREPLY[i]}
|
||||
done
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ $COMP_CWORD -eq 4 ]; then
|
||||
COMPREPLY=( $( compgen -W 'on off reset' $cur ) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
case "$prev" in
|
||||
@([1-6]|--@(list|add|del)))
|
||||
COMPREPLY=( $( compgen -W "`(cd /etc/rc.d/init.d; echo *)`" \
|
||||
$cur) )
|
||||
return 0
|
||||
;;
|
||||
--level)
|
||||
COMPREPLY=( $( compgen -W '1 2 3 4 5 6' $cur ) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
complete -F _chkconfig chkconfig
|
||||
###
|
||||
@@ -1,43 +0,0 @@
|
||||
#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:-.}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
# 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 $?
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
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.
|
||||
@@ -1,127 +0,0 @@
|
||||
# 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 $?
|
||||
}
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
#
|
||||
# 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
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#! /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
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#
|
||||
# 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 "$@"
|
||||
@@ -1,301 +0,0 @@
|
||||
#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) ***
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#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
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#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
|
||||
@@ -1,12 +0,0 @@
|
||||
jj ()
|
||||
{
|
||||
p=$(jobs $1);
|
||||
echo $p
|
||||
|
||||
case "$p" in
|
||||
[*) echo matches '[*'
|
||||
;;
|
||||
*) echo not a match\?
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
# 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
|
||||
@@ -1,27 +0,0 @@
|
||||
#! /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
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
# 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
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
# 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$$
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
#!/bin/bash
|
||||
# @(#) newdirstack.bsh
|
||||
|
||||
# Date: Tue, 31 Jan 2012 16:28:52 +0100
|
||||
# Subject: A Bash source code example
|
||||
# From: Eric Sanchis <eric.sanchis@iut-rodez.fr>
|
||||
# To: chet.ramey@case.edu
|
||||
#
|
||||
# Using Bash everyday, I developped an enhanced implementation of the
|
||||
# cd/dir functions described in the Bolsky & Korn book, which
|
||||
# illustrates several specific Bash syntax elements.
|
||||
#
|
||||
# It works fine with a non empty CDPATH and cdable variables. In
|
||||
# addition, a directory name is indexed only once into the stack.
|
||||
#
|
||||
# If you find this code snippet useful, would it be possible to include
|
||||
# it into the bash-doc section of future bash packages ?
|
||||
#
|
||||
# Sincerely yours,
|
||||
#
|
||||
# Eric
|
||||
# IUT Rodez
|
||||
# University of Toulouse (France)
|
||||
|
||||
###
|
||||
# Another implementation of the directory manipulation functions
|
||||
# published in the Bolsky & Korn book : "The new Korn shell" :
|
||||
# cd, to change current directory
|
||||
# d, to display the stack content
|
||||
# Eric Sanchis (eric.sanchis@iut-rodez.fr), 2012
|
||||
###
|
||||
|
||||
|
||||
shopt -s expand_aliases
|
||||
shopt -s extglob
|
||||
shopt -s cdable_vars
|
||||
|
||||
alias integer='declare -i'
|
||||
|
||||
integer MAX=32
|
||||
integer INDMAX=MAX-1
|
||||
integer INDTOP=0
|
||||
|
||||
unalias cd 2>/dev/null
|
||||
alias cd=cdir
|
||||
|
||||
unset tab
|
||||
tab[INDTOP]="$(pwd)"
|
||||
|
||||
|
||||
function cdir
|
||||
{
|
||||
local -i ind
|
||||
|
||||
dir="${1:-$HOME}"
|
||||
case "$dir" in
|
||||
- ) # cd - => equivalent to : cd -1
|
||||
ind=INDTOP-1
|
||||
cd_by_number $ind
|
||||
;;
|
||||
-+([[:digit:]]) ) # cd -n
|
||||
ind=$INDTOP-${dir#-}
|
||||
cd_by_number $ind
|
||||
;;
|
||||
*) # cd ~ or cd dir_name
|
||||
cd_by_name "$dir"
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
function cd_by_number
|
||||
{
|
||||
local -i k=$1
|
||||
local -i j
|
||||
local dirtmp
|
||||
|
||||
if (( k < 0 ))
|
||||
then
|
||||
echo Impossible to change directory >&2
|
||||
return 1
|
||||
else
|
||||
dirtmp="${tab[k]}"
|
||||
j=k+1
|
||||
while (( j <= INDTOP ))
|
||||
do
|
||||
tab[j-1]="${tab[j]}"
|
||||
j=j+1
|
||||
done
|
||||
tab[INDTOP]="$dirtmp"
|
||||
\cd "${tab[INDTOP]}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function cd_by_name
|
||||
{
|
||||
local -i i
|
||||
local rep
|
||||
|
||||
rep=$( \cd "$1" &>/dev/null && pwd)
|
||||
if [[ -z "$rep" ]]
|
||||
then
|
||||
echo cd : "$1" unknown >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
i=$INDTOP
|
||||
while (( i >= 0 ))
|
||||
do
|
||||
if [[ "${tab[i]}" == "$rep" ]]
|
||||
then break
|
||||
fi
|
||||
i=i-1
|
||||
done
|
||||
|
||||
if (( i == INDTOP ))
|
||||
then # cd -0 => we do nothing !
|
||||
return 0
|
||||
elif (( i == -1 ))
|
||||
then # the directory isn't in the stack
|
||||
if (( INDTOP == INDMAX ))
|
||||
then # the stack is FULL
|
||||
# the oldest directory is removed
|
||||
local -i m
|
||||
|
||||
m=1
|
||||
while (( m <= INDMAX ))
|
||||
do
|
||||
tab[m-1]="${tab[m]}"
|
||||
m=m+1
|
||||
done
|
||||
else # the new directory is added to the top of the stack
|
||||
INDTOP=INDTOP+1
|
||||
fi
|
||||
tab[INDTOP]="$rep"
|
||||
\cd "${tab[INDTOP]}"
|
||||
return 0
|
||||
|
||||
else # the directory is already in the stack
|
||||
# $i gives its index
|
||||
cd_by_number $i
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function d # display the directory stack
|
||||
{
|
||||
local -i i
|
||||
local rep
|
||||
|
||||
i=0
|
||||
while (( $i <= $INDTOP ))
|
||||
do
|
||||
rep="${tab[INDTOP-i]#$HOME/}"
|
||||
case "$rep" in
|
||||
$HOME) rep="~" ;;
|
||||
/* ) : ;;
|
||||
* ) rep="~/$rep"
|
||||
esac
|
||||
|
||||
echo "$i ) $rep"
|
||||
i=i+1
|
||||
done
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#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;:\$;;"`
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#!/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"'
|
||||
@@ -1,43 +0,0 @@
|
||||
# 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
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
# 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;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#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 "$@"
|
||||
@@ -1,35 +0,0 @@
|
||||
#
|
||||
# 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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# 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
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#! /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 "$@"
|
||||
@@ -1,379 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1989, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static const char sccsid[] = "@(#)cut.c 8.3 (Berkeley) 5/4/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "bashansi.h"
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "builtins.h"
|
||||
#include "shell.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "common.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if !defined (_POSIX2_LINE_MAX)
|
||||
# define _POSIX2_LINE_MAX 2048
|
||||
#endif
|
||||
|
||||
static int cflag;
|
||||
static char dchar;
|
||||
static int dflag;
|
||||
static int fflag;
|
||||
static int sflag;
|
||||
|
||||
static int autostart, autostop, maxval;
|
||||
static char positions[_POSIX2_LINE_MAX + 1];
|
||||
|
||||
static int c_cut __P((FILE *, char *));
|
||||
static int f_cut __P((FILE *, char *));
|
||||
static int get_list __P((char *));
|
||||
static char *_cut_strsep __P((char **, const char *));
|
||||
|
||||
int
|
||||
cut_builtin(list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
FILE *fp;
|
||||
int (*fcn) __P((FILE *, char *)) = NULL;
|
||||
int ch;
|
||||
|
||||
fcn = NULL;
|
||||
dchar = '\t'; /* default delimiter is \t */
|
||||
|
||||
/* Since we don't support multi-byte characters, the -c and -b
|
||||
options are equivalent, and the -n option is meaningless. */
|
||||
reset_internal_getopt ();
|
||||
while ((ch = internal_getopt (list, "b:c:d:f:sn")) != -1)
|
||||
switch(ch) {
|
||||
case 'b':
|
||||
case 'c':
|
||||
fcn = c_cut;
|
||||
if (get_list(list_optarg) < 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
cflag = 1;
|
||||
break;
|
||||
case 'd':
|
||||
dchar = *list_optarg;
|
||||
dflag = 1;
|
||||
break;
|
||||
case 'f':
|
||||
fcn = f_cut;
|
||||
if (get_list(list_optarg) < 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
fflag = 1;
|
||||
break;
|
||||
case 's':
|
||||
sflag = 1;
|
||||
break;
|
||||
case 'n':
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
builtin_usage();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
list = loptend;
|
||||
|
||||
if (fflag) {
|
||||
if (cflag) {
|
||||
builtin_usage();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
} else if (!cflag || dflag || sflag) {
|
||||
builtin_usage();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
|
||||
if (list) {
|
||||
while (list) {
|
||||
fp = fopen(list->word->word, "r");
|
||||
if (fp == 0) {
|
||||
builtin_error("%s", list->word->word);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
ch = (*fcn)(fp, list->word->word);
|
||||
(void)fclose(fp);
|
||||
if (ch < 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
list = list->next;
|
||||
}
|
||||
} else {
|
||||
ch = (*fcn)(stdin, "stdin");
|
||||
if (ch < 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
get_list(list)
|
||||
char *list;
|
||||
{
|
||||
int setautostart, start, stop;
|
||||
char *pos;
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* set a byte in the positions array to indicate if a field or
|
||||
* column is to be selected; use +1, it's 1-based, not 0-based.
|
||||
* This parser is less restrictive than the Draft 9 POSIX spec.
|
||||
* POSIX doesn't allow lists that aren't in increasing order or
|
||||
* overlapping lists. We also handle "-3-5" although there's no
|
||||
* real reason too.
|
||||
*/
|
||||
for (; (p = _cut_strsep(&list, ", \t")) != NULL;) {
|
||||
setautostart = start = stop = 0;
|
||||
if (*p == '-') {
|
||||
++p;
|
||||
setautostart = 1;
|
||||
}
|
||||
if (isdigit((unsigned char)*p)) {
|
||||
start = stop = strtol(p, &p, 10);
|
||||
if (setautostart && start > autostart)
|
||||
autostart = start;
|
||||
}
|
||||
if (*p == '-') {
|
||||
if (isdigit((unsigned char)p[1]))
|
||||
stop = strtol(p + 1, &p, 10);
|
||||
if (*p == '-') {
|
||||
++p;
|
||||
if (!autostop || autostop > stop)
|
||||
autostop = stop;
|
||||
}
|
||||
}
|
||||
if (*p) {
|
||||
builtin_error("[-cf] list: illegal list value");
|
||||
return -1;
|
||||
}
|
||||
if (!stop || !start) {
|
||||
builtin_error("[-cf] list: values may not include zero");
|
||||
return -1;
|
||||
}
|
||||
if (stop > _POSIX2_LINE_MAX) {
|
||||
builtin_error("[-cf] list: %d too large (max %d)",
|
||||
stop, _POSIX2_LINE_MAX);
|
||||
return -1;
|
||||
}
|
||||
if (maxval < stop)
|
||||
maxval = stop;
|
||||
for (pos = positions + start; start++ <= stop; *pos++ = 1);
|
||||
}
|
||||
|
||||
/* overlapping ranges */
|
||||
if (autostop && maxval > autostop)
|
||||
maxval = autostop;
|
||||
|
||||
/* set autostart */
|
||||
if (autostart)
|
||||
memset(positions + 1, '1', autostart);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
c_cut(fp, fname)
|
||||
FILE *fp;
|
||||
char *fname;
|
||||
{
|
||||
int ch, col;
|
||||
char *pos;
|
||||
|
||||
ch = 0;
|
||||
for (;;) {
|
||||
pos = positions + 1;
|
||||
for (col = maxval; col; --col) {
|
||||
if ((ch = getc(fp)) == EOF)
|
||||
return;
|
||||
if (ch == '\n')
|
||||
break;
|
||||
if (*pos++)
|
||||
(void)putchar(ch);
|
||||
}
|
||||
if (ch != '\n') {
|
||||
if (autostop)
|
||||
while ((ch = getc(fp)) != EOF && ch != '\n')
|
||||
(void)putchar(ch);
|
||||
else
|
||||
while ((ch = getc(fp)) != EOF && ch != '\n');
|
||||
}
|
||||
(void)putchar('\n');
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
f_cut(fp, fname)
|
||||
FILE *fp;
|
||||
char *fname;
|
||||
{
|
||||
int ch, field, isdelim;
|
||||
char *pos, *p, sep;
|
||||
int output;
|
||||
char lbuf[_POSIX2_LINE_MAX + 1];
|
||||
|
||||
for (sep = dchar; fgets(lbuf, sizeof(lbuf), fp);) {
|
||||
output = 0;
|
||||
for (isdelim = 0, p = lbuf;; ++p) {
|
||||
if (!(ch = *p)) {
|
||||
builtin_error("%s: line too long.", fname);
|
||||
return -1;
|
||||
}
|
||||
/* this should work if newline is delimiter */
|
||||
if (ch == sep)
|
||||
isdelim = 1;
|
||||
if (ch == '\n') {
|
||||
if (!isdelim && !sflag)
|
||||
(void)printf("%s", lbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isdelim)
|
||||
continue;
|
||||
|
||||
pos = positions + 1;
|
||||
for (field = maxval, p = lbuf; field; --field, ++pos) {
|
||||
if (*pos) {
|
||||
if (output++)
|
||||
(void)putchar(sep);
|
||||
while ((ch = *p++) != '\n' && ch != sep)
|
||||
(void)putchar(ch);
|
||||
} else {
|
||||
while ((ch = *p++) != '\n' && ch != sep)
|
||||
continue;
|
||||
}
|
||||
if (ch == '\n')
|
||||
break;
|
||||
}
|
||||
if (ch != '\n') {
|
||||
if (autostop) {
|
||||
if (output)
|
||||
(void)putchar(sep);
|
||||
for (; (ch = *p) != '\n'; ++p)
|
||||
(void)putchar(ch);
|
||||
} else
|
||||
for (; (ch = *p) != '\n'; ++p);
|
||||
}
|
||||
(void)putchar('\n');
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get next token from string *stringp, where tokens are possibly-empty
|
||||
* strings separated by characters from delim.
|
||||
*
|
||||
* Writes NULs into the string at *stringp to end tokens.
|
||||
* delim need not remain constant from call to call.
|
||||
* On return, *stringp points past the last NUL written (if there might
|
||||
* be further tokens), or is NULL (if there are definitely no more tokens).
|
||||
*
|
||||
* If *stringp is NULL, strsep returns NULL.
|
||||
*/
|
||||
static char *
|
||||
_cut_strsep(stringp, delim)
|
||||
register char **stringp;
|
||||
register const char *delim;
|
||||
{
|
||||
register char *s;
|
||||
register const char *spanp;
|
||||
register int c, sc;
|
||||
char *tok;
|
||||
|
||||
if ((s = *stringp) == NULL)
|
||||
return (NULL);
|
||||
for (tok = s;;) {
|
||||
c = *s++;
|
||||
spanp = delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = 0;
|
||||
*stringp = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static char *cut_doc[] = {
|
||||
"Select portions of lines.",
|
||||
"",
|
||||
"Select portions of each line (as specified by LIST) from each FILE",
|
||||
"(by default, the standard input), and write them to the standard output.",
|
||||
"Items specified by LIST are either column positions or fields delimited",
|
||||
"by a special character. Column numbering starts at 1.",
|
||||
(char *)0
|
||||
};
|
||||
|
||||
struct builtin cut_struct = {
|
||||
"cut",
|
||||
cut_builtin,
|
||||
BUILTIN_ENABLED,
|
||||
cut_doc,
|
||||
"cut -b list [-n] [file ...] OR cut -c list [file ...] OR cut -f list [-s] [-d delim] [file ...]",
|
||||
0
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,214 +0,0 @@
|
||||
/* getconf.h -- replacement definitions for ones the system doesn't provide. */
|
||||
|
||||
#ifndef _GETCONF_H
|
||||
#define _GETCONF_H
|
||||
|
||||
/* Some systems do not define these; use POSIX.2 minimum recommended values. */
|
||||
#ifndef _POSIX2_COLL_WEIGHTS_MAX
|
||||
# define _POSIX2_COLL_WEIGHTS_MAX 2
|
||||
#endif
|
||||
|
||||
/* If we're on a posix system, but the system doesn't define the necessary
|
||||
constants, use posix.1 minimum values. */
|
||||
#if defined (_POSIX_VERSION)
|
||||
|
||||
#ifndef _POSIX_ARG_MAX
|
||||
# define _POSIX_ARG_MAX 4096
|
||||
#endif
|
||||
#ifndef _POSIX_CHILD_MAX
|
||||
# define _POSIX_CHILD_MAX 6
|
||||
#endif
|
||||
#ifndef _POSIX_LINK_MAX
|
||||
# define _POSIX_LINK_MAX 8
|
||||
#endif
|
||||
#ifndef _POSIX_MAX_CANON
|
||||
# define _POSIX_MAX_CANON 255
|
||||
#endif
|
||||
#ifndef _POSIX_MAX_INPUT
|
||||
# define _POSIX_MAX_INPUT 255
|
||||
#endif
|
||||
#ifndef _POSIX_NAME_MAX
|
||||
# define _POSIX_NAME_MAX 14
|
||||
#endif
|
||||
#ifndef _POSIX_NGROUPS_MAX
|
||||
# define _POSIX_NGROUPS_MAX 0
|
||||
#endif
|
||||
#ifndef _POSIX_OPEN_MAX
|
||||
# define _POSIX_OPEN_MAX 16
|
||||
#endif
|
||||
#ifndef _POSIX_PATH_MAX
|
||||
# define _POSIX_PATH_MAX 255
|
||||
#endif
|
||||
#ifndef _POSIX_PIPE_BUF
|
||||
# define _POSIX_PIPE_BUF 512
|
||||
#endif
|
||||
#ifndef _POSIX_SSIZE_MAX
|
||||
# define _POSIX_SSIZE_MAX 32767
|
||||
#endif
|
||||
#ifndef _POSIX_STREAM_MAX
|
||||
# define _POSIX_STREAM_MAX 8
|
||||
#endif
|
||||
#ifndef _POSIX_TZNAME_MAX
|
||||
# define _POSIX_TZNAME_MAX 3
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX2_BC_BASE_MAX
|
||||
# define _POSIX2_BC_BASE_MAX 99
|
||||
#endif
|
||||
#ifndef _POSIX2_BC_DIM_MAX
|
||||
# define _POSIX2_BC_DIM_MAX 2048
|
||||
#endif
|
||||
#ifndef _POSIX2_BC_SCALE_MAX
|
||||
# define _POSIX2_BC_SCALE_MAX 99
|
||||
#endif
|
||||
#ifndef _POSIX2_BC_STRING_MAX
|
||||
# define _POSIX2_BC_STRING_MAX 1000
|
||||
#endif
|
||||
#ifndef _POSIX2_EQUIV_CLASS_MAX
|
||||
# define _POSIX2_EQUIV_CLASS_MAX 2
|
||||
#endif
|
||||
#ifndef _POSIX2_EXPR_NEST_MAX
|
||||
# define _POSIX2_EXPR_NEST_MAX 32
|
||||
#endif
|
||||
#ifndef _POSIX2_LINE_MAX
|
||||
# define _POSIX2_LINE_MAX 2048
|
||||
#endif
|
||||
#ifndef _POSIX2_RE_DUP_MAX
|
||||
# define _POSIX2_RE_DUP_MAX 255
|
||||
#endif
|
||||
|
||||
/* configurable system variables */
|
||||
#if !defined (HAVE_SYSCONF)
|
||||
|
||||
#ifndef _SC_ARG_MAX
|
||||
# define _SC_ARG_MAX 1
|
||||
# define _SC_CHILD_MAX 2
|
||||
# define _SC_CLK_TCK 3
|
||||
# define _SC_NGROUPS_MAX 4
|
||||
# define _SC_OPEN_MAX 5
|
||||
# define _SC_JOB_CONTROL 6
|
||||
# define _SC_SAVED_IDS 7
|
||||
# define _SC_VERSION 8
|
||||
# define _SC_BC_BASE_MAX 9
|
||||
# define _SC_BC_DIM_MAX 10
|
||||
# define _SC_BC_SCALE_MAX 11
|
||||
# define _SC_BC_STRING_MAX 12
|
||||
# define _SC_COLL_WEIGHTS_MAX 13
|
||||
# define _SC_EXPR_NEST_MAX 14
|
||||
# define _SC_LINE_MAX 15
|
||||
# define _SC_RE_DUP_MAX 16
|
||||
#if 0
|
||||
# define _SC_2_VERSION 17
|
||||
# define _SC_2_C_BIND 18
|
||||
# define _SC_2_C_DEV 19
|
||||
# define _SC_2_CHAR_TERM 20
|
||||
# define _SC_2_FORT_DEV 21
|
||||
# define _SC_2_FORT_RUN 22
|
||||
# define _SC_2_LOCALEDEF 23
|
||||
# define _SC_2_SW_DEV 24
|
||||
# define _SC_2_UPE 25
|
||||
#endif /* 0 */
|
||||
|
||||
# define _SC_STREAM_MAX 26
|
||||
# define _SC_TZNAME_MAX 27
|
||||
#endif /* !_SC_ARG_MAX */
|
||||
|
||||
#endif /* !HAVE_SYSCONF */
|
||||
|
||||
/* configurable pathname variables */
|
||||
#if !defined (HAVE_PATHCONF)
|
||||
|
||||
#ifndef _PC_LINK_MAX
|
||||
#define _PC_LINK_MAX 1
|
||||
#define _PC_MAX_CANON 2
|
||||
#define _PC_MAX_INPUT 3
|
||||
#define _PC_NAME_MAX 4
|
||||
#define _PC_PATH_MAX 5
|
||||
#define _PC_PIPE_BUF 6
|
||||
#define _PC_CHOWN_RESTRICTED 7
|
||||
#define _PC_NO_TRUNC 8
|
||||
#define _PC_VDISABLE 9
|
||||
#endif /* !_PC_LINK_MAX */
|
||||
|
||||
#endif /* !HAVE_PATHCONF */
|
||||
|
||||
#endif /* _POSIX_VERSION */
|
||||
|
||||
#ifndef _CS_PATH
|
||||
# define _CS_PATH 1
|
||||
#endif
|
||||
|
||||
/* ANSI/ISO C, POSIX.1-200x, XPG 4.2 (and later) C language type limits.
|
||||
Defined only if the system include files don't. Assume a 32-bit
|
||||
environment with signed 8-bit characters. */
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
# define CHAR_BIT 8
|
||||
#endif
|
||||
#ifndef CHAR_MAX
|
||||
# define CHAR_MAX 127
|
||||
#endif
|
||||
#ifndef CHAR_MIN
|
||||
# define CHAR_MIN -128
|
||||
#endif
|
||||
|
||||
#ifndef INT_BIT
|
||||
# define INT_BIT (sizeof (int) * CHAR_BIT)
|
||||
#endif
|
||||
#ifndef INT_MAX
|
||||
# define INT_MAX 2147483647
|
||||
#endif
|
||||
#ifndef INT_MIN
|
||||
# define INT_MIN (-2147483647-1)
|
||||
#endif
|
||||
|
||||
#ifndef LONG_BIT
|
||||
# define LONG_BIT (sizeof (long int) * CHAR_BIT)
|
||||
#endif
|
||||
#ifndef LONG_MAX
|
||||
# define LONG_MAX 2147483647L
|
||||
#endif
|
||||
#ifndef LONG_MIN
|
||||
# define LONG_MIN (-2147483647L-1L)
|
||||
#endif
|
||||
|
||||
#ifndef SCHAR_MAX
|
||||
# define SCHAR_MAX CHAR_MAX
|
||||
#endif
|
||||
#ifndef SCHAR_MIN
|
||||
# define SCHAR_MIN CHAR_MIN
|
||||
#endif
|
||||
|
||||
#ifndef SHRT_MAX
|
||||
# define SHRT_MAX 32767
|
||||
#endif
|
||||
#ifndef SHRT_MIN
|
||||
# define SHRT_MIN (-32768)
|
||||
#endif
|
||||
|
||||
#ifndef UCHAR_MAX
|
||||
# define UCHAR_MAX 255
|
||||
#endif
|
||||
#ifndef UINT_MAX
|
||||
# define UINT_MAX 4294967295U
|
||||
#endif
|
||||
#ifndef ULONG_MAX
|
||||
# define ULONG_MAX 4294967295UL
|
||||
#endif
|
||||
#ifndef USHRT_MAX
|
||||
# define UCHAR_MAX 65535
|
||||
#endif
|
||||
|
||||
/* assume size_t is `unsigned int'; ssize_t is `int' */
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX UINT_MAX
|
||||
#endif
|
||||
#ifndef SSIZE_MAX
|
||||
# define SSIZE_MAX INT_MAX
|
||||
#endif
|
||||
|
||||
#ifndef WORD_BIT
|
||||
# define WORD_BIT (sizeof (int) * CHAR_BIT)
|
||||
#endif
|
||||
|
||||
#endif /* _GETCONF_H */
|
||||
@@ -1,516 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(BUILTIN) && !defined(SHELL)
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1989, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 7/20/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bashansi.h"
|
||||
#include "shell.h"
|
||||
#include "builtins.h"
|
||||
#include "stdc.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
static char sbuf[1024];
|
||||
static int sblen;
|
||||
|
||||
/* Gee, I wish sprintf could be reliably counted upon to return the
|
||||
number of characters written :-( */
|
||||
#define PF(f, func) \
|
||||
do { \
|
||||
if (fieldwidth) \
|
||||
if (precision) \
|
||||
sprintf(sbuf, f, fieldwidth, precision, func); \
|
||||
else \
|
||||
sprintf(sbuf, f, fieldwidth, func); \
|
||||
else if (precision) \
|
||||
sprintf(sbuf, f, precision, func); \
|
||||
else \
|
||||
sprintf(sbuf, f, func); \
|
||||
spaddstr (sbuf, strlen (sbuf)); \
|
||||
} while (0)
|
||||
|
||||
static int asciicode __P((void));
|
||||
static void escape __P((char *));
|
||||
static int getchr __P((void));
|
||||
static double getdouble __P((void));
|
||||
static int getint __P((int *));
|
||||
static int getlong __P((long *));
|
||||
static char *getstr __P((void));
|
||||
static char *mklong __P((char *, int));
|
||||
static void usage __P((void));
|
||||
|
||||
static char **gargv;
|
||||
|
||||
static char *outstr;
|
||||
static int outsize;
|
||||
static int outind;
|
||||
|
||||
int sprintf_builtin ();
|
||||
static int sprintf_main ();
|
||||
static void spaddstr ();
|
||||
|
||||
extern char *this_command_name;
|
||||
extern char *single_quote ();
|
||||
extern char **make_builtin_argv ();
|
||||
|
||||
static char *sprintf_doc[] = {
|
||||
"Format arguments and assign result to variable.",
|
||||
"",
|
||||
"sprintf formats and outputs its arguments, after the second, under control",
|
||||
"of the format and assigns the result to the variable named by its first",
|
||||
"argument. The format is a character string which contains three types",
|
||||
"of objects: plain characters, which are simply copied to the output string,",
|
||||
"character escape sequences which are converted and copied to the output",
|
||||
"string, and format specifications, each of which causes printing of the",
|
||||
"next successive argument. In addition to the standard sprintf(3) formats,",
|
||||
"%b means to expand escapes in the corresponding argument, and %q means",
|
||||
"to quote the argument in a way that can be reused as shell input. Each",
|
||||
"one of the format specifications must not expand to more than 1024",
|
||||
"characters, though there is no limit on the total size of the output",
|
||||
"string.",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
struct builtin sprintf_struct = {
|
||||
"sprintf",
|
||||
sprintf_builtin,
|
||||
BUILTIN_ENABLED,
|
||||
sprintf_doc,
|
||||
"sprintf var format [arguments]",
|
||||
(char *)0
|
||||
};
|
||||
|
||||
int
|
||||
sprintf_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int c, r;
|
||||
char **v, *varname;
|
||||
WORD_LIST *l;
|
||||
SHELL_VAR *var;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
varname = list->word->word;
|
||||
list = list->next;
|
||||
|
||||
if (legal_identifier (varname) == 0)
|
||||
{
|
||||
builtin_error ("%s: not a legal variable name", varname);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
outind = 0;
|
||||
if (outstr == 0)
|
||||
outstr = xmalloc (outsize = 64);
|
||||
outstr[0] = '\0';
|
||||
|
||||
v = make_builtin_argv (list, &c);
|
||||
r = sprintf_main (c, v);
|
||||
free (v);
|
||||
|
||||
var = bind_variable (varname, outstr, 0);
|
||||
if (readonly_p (var))
|
||||
{
|
||||
builtin_error ("%s: readonly variable", varname);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
spaddstr(str, len)
|
||||
char *str;
|
||||
int len;
|
||||
{
|
||||
RESIZE_MALLOCED_BUFFER (outstr, outind, len, outsize, 64);
|
||||
strcpy (outstr + outind, str);
|
||||
outind += len;
|
||||
}
|
||||
|
||||
static int
|
||||
sprintf_main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
extern int optind;
|
||||
static char *skip1, *skip2;
|
||||
int ch, end, fieldwidth, precision;
|
||||
char convch, nextch, *format, *fmt, *start;
|
||||
|
||||
while ((ch = getopt(argc, argv, "")) != EOF)
|
||||
switch (ch) {
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
return (1);
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1) {
|
||||
usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic algorithm is to scan the format string for conversion
|
||||
* specifications -- once one is found, find out if the field
|
||||
* width or precision is a '*'; if it is, gather up value. Note,
|
||||
* format strings are reused as necessary to use up the provided
|
||||
* arguments, arguments of zero/null string are provided to use
|
||||
* up the format string.
|
||||
*/
|
||||
skip1 = "#-+ 0";
|
||||
skip2 = "*0123456789";
|
||||
|
||||
escape(fmt = format = *argv); /* backslash interpretation */
|
||||
gargv = ++argv;
|
||||
for (;;) {
|
||||
end = 0;
|
||||
/* find next format specification */
|
||||
next: for (start = fmt;; ++fmt) {
|
||||
if (!*fmt) {
|
||||
/* avoid infinite loop */
|
||||
if (end == 1) {
|
||||
warnx("missing format character",
|
||||
NULL, NULL);
|
||||
return (1);
|
||||
}
|
||||
end = 1;
|
||||
if (fmt > start)
|
||||
(void)printf("%s", start);
|
||||
if (!*gargv)
|
||||
return (0);
|
||||
fmt = format;
|
||||
goto next;
|
||||
}
|
||||
/* %% prints a % */
|
||||
if (*fmt == '%') {
|
||||
if (*++fmt != '%')
|
||||
break;
|
||||
*fmt++ = '\0';
|
||||
(void)printf("%s", start);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip to field width */
|
||||
for (; strchr(skip1, *fmt); ++fmt);
|
||||
if (*fmt == '*') {
|
||||
if (getint(&fieldwidth))
|
||||
return (1);
|
||||
} else
|
||||
fieldwidth = 0;
|
||||
|
||||
/* skip to possible '.', get following precision */
|
||||
for (; strchr(skip2, *fmt); ++fmt);
|
||||
if (*fmt == '.')
|
||||
++fmt;
|
||||
if (*fmt == '*') {
|
||||
if (getint(&precision))
|
||||
return (1);
|
||||
} else
|
||||
precision = 0;
|
||||
|
||||
/* skip to conversion char */
|
||||
for (; strchr(skip2, *fmt); ++fmt);
|
||||
if (!*fmt) {
|
||||
warnx("missing format character", NULL, NULL);
|
||||
return (1);
|
||||
}
|
||||
|
||||
convch = *fmt;
|
||||
nextch = *++fmt;
|
||||
*fmt = '\0';
|
||||
switch(convch) {
|
||||
case 'c': {
|
||||
char p;
|
||||
|
||||
p = getchr();
|
||||
PF(start, p);
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
char *p;
|
||||
|
||||
p = getstr();
|
||||
PF(start, p);
|
||||
break;
|
||||
}
|
||||
case 'b': { /* expand escapes in argument */
|
||||
char *p;
|
||||
|
||||
p = getstr();
|
||||
escape(p);
|
||||
PF("%s", p);
|
||||
break;
|
||||
}
|
||||
case 'q': { /* print with shell single quoting */
|
||||
char *p, *p2;
|
||||
|
||||
p = getstr();
|
||||
p2 = single_quote(p);
|
||||
PF("%s", p2);
|
||||
free(p2);
|
||||
break;
|
||||
}
|
||||
case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': {
|
||||
long p;
|
||||
char *f;
|
||||
|
||||
if ((f = mklong(start, convch)) == NULL)
|
||||
return (1);
|
||||
if (getlong(&p))
|
||||
return (1);
|
||||
PF(f, p);
|
||||
break;
|
||||
}
|
||||
case 'e': case 'E': case 'f': case 'g': case 'G': {
|
||||
double p;
|
||||
|
||||
p = getdouble();
|
||||
PF(start, p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
warnx("illegal format character", NULL, NULL);
|
||||
return (1);
|
||||
}
|
||||
*fmt = nextch;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static char *
|
||||
mklong(str, ch)
|
||||
char *str;
|
||||
int ch;
|
||||
{
|
||||
static char copy[64];
|
||||
int len;
|
||||
|
||||
len = strlen(str) + 2;
|
||||
memmove(copy, str, len - 3);
|
||||
copy[len - 3] = 'l';
|
||||
copy[len - 2] = ch;
|
||||
copy[len - 1] = '\0';
|
||||
return (copy);
|
||||
}
|
||||
|
||||
static void
|
||||
escape(fmt)
|
||||
register char *fmt;
|
||||
{
|
||||
register char *store;
|
||||
register int value, c;
|
||||
|
||||
for (store = fmt; c = *fmt; ++fmt, ++store) {
|
||||
if (c != '\\') {
|
||||
*store = c;
|
||||
continue;
|
||||
}
|
||||
switch (*++fmt) {
|
||||
case '\0': /* EOS, user error */
|
||||
*store = '\\';
|
||||
*++store = '\0';
|
||||
return;
|
||||
case '\\': /* backslash */
|
||||
case '\'': /* single quote */
|
||||
*store = *fmt;
|
||||
break;
|
||||
case 'a': /* bell/alert */
|
||||
*store = '\7';
|
||||
break;
|
||||
case 'b': /* backspace */
|
||||
*store = '\b';
|
||||
break;
|
||||
case 'c':
|
||||
return;
|
||||
case 'e':
|
||||
case 'E':
|
||||
*store = '\033';
|
||||
break;
|
||||
case 'f': /* form-feed */
|
||||
*store = '\f';
|
||||
break;
|
||||
case 'n': /* newline */
|
||||
*store = '\n';
|
||||
break;
|
||||
case 'r': /* carriage-return */
|
||||
*store = '\r';
|
||||
break;
|
||||
case 't': /* horizontal tab */
|
||||
*store = '\t';
|
||||
break;
|
||||
case 'v': /* vertical tab */
|
||||
*store = '\13';
|
||||
break;
|
||||
/* octal constant */
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
for (c = 3, value = 0;
|
||||
c-- && *fmt >= '0' && *fmt <= '7'; ++fmt) {
|
||||
value <<= 3;
|
||||
value += *fmt - '0';
|
||||
}
|
||||
--fmt;
|
||||
*store = value;
|
||||
break;
|
||||
default:
|
||||
*store = *fmt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*store = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
getchr()
|
||||
{
|
||||
if (!*gargv)
|
||||
return ('\0');
|
||||
return ((int)**gargv++);
|
||||
}
|
||||
|
||||
static char *
|
||||
getstr()
|
||||
{
|
||||
if (!*gargv)
|
||||
return ("");
|
||||
return (*gargv++);
|
||||
}
|
||||
|
||||
static char *Number = "+-.0123456789";
|
||||
static int
|
||||
getint(ip)
|
||||
int *ip;
|
||||
{
|
||||
long val;
|
||||
|
||||
if (getlong(&val))
|
||||
return (1);
|
||||
if (val > INT_MAX) {
|
||||
warnx("%s: %s", *gargv, strerror(ERANGE));
|
||||
return (1);
|
||||
}
|
||||
*ip = val;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
getlong(lp)
|
||||
long *lp;
|
||||
{
|
||||
long val;
|
||||
char *ep;
|
||||
|
||||
if (!*gargv) {
|
||||
*lp = 0;
|
||||
return (0);
|
||||
}
|
||||
if (strchr(Number, **gargv)) {
|
||||
errno = 0;
|
||||
val = strtol(*gargv, &ep, 0);
|
||||
if (*ep != '\0') {
|
||||
warnx("%s: illegal number", *gargv, NULL);
|
||||
return (1);
|
||||
}
|
||||
if (errno == ERANGE)
|
||||
if (val == LONG_MAX) {
|
||||
warnx("%s: %s", *gargv, strerror(ERANGE));
|
||||
return (1);
|
||||
}
|
||||
if (val == LONG_MIN) {
|
||||
warnx("%s: %s", *gargv, strerror(ERANGE));
|
||||
return (1);
|
||||
}
|
||||
|
||||
*lp = val;
|
||||
++gargv;
|
||||
return (0);
|
||||
}
|
||||
*lp = (long)asciicode();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static double
|
||||
getdouble()
|
||||
{
|
||||
if (!*gargv)
|
||||
return ((double)0);
|
||||
if (strchr(Number, **gargv))
|
||||
return (atof(*gargv++));
|
||||
return ((double)asciicode());
|
||||
}
|
||||
|
||||
static int
|
||||
asciicode()
|
||||
{
|
||||
register int ch;
|
||||
|
||||
ch = **gargv;
|
||||
if (ch == '\'' || ch == '"')
|
||||
ch = (*gargv)[1];
|
||||
++gargv;
|
||||
return (ch);
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: printf format [arg ...]\n");
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Originally from
|
||||
* http://www.excessus.demon.co.uk/misc-hacks/index.html#xtitle
|
||||
*/
|
||||
|
||||
/*
|
||||
* Made into a loadable builtin by chet@po.cwru.edu.
|
||||
*/
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#ifdef BASH_BUILTIN
|
||||
#include "shell.h"
|
||||
#include "builtins.h"
|
||||
#include "bashgetopt.h"
|
||||
#endif
|
||||
|
||||
#ifdef BASH_BUILTIN
|
||||
int xtitle_builtin(WORD_LIST *list)
|
||||
#else
|
||||
int main(int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
int query = 0;
|
||||
int fd;
|
||||
int openned = 0;
|
||||
|
||||
#ifdef BASH_BUILTIN
|
||||
reset_internal_getopt();
|
||||
#endif
|
||||
for (;;) {
|
||||
#ifdef BASH_BUILTIN
|
||||
int i;
|
||||
i = internal_getopt(list, "q");
|
||||
#else
|
||||
int i = getopt(argc, argv, "q");
|
||||
#endif
|
||||
if (i < 0)
|
||||
break;
|
||||
switch (i) {
|
||||
case 'q':
|
||||
query = 1;
|
||||
break;
|
||||
default:
|
||||
#ifdef BASH_BUILTIN
|
||||
builtin_usage();
|
||||
#else
|
||||
fprintf(stderr, "usage: xtitle [-q] [string]\n");
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BASH_BUILTIN
|
||||
if (!query && loptend == 0) {
|
||||
#else
|
||||
if (!query && optind == argc) {
|
||||
#endif
|
||||
fprintf(stderr, "xtitle: no string to set\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
{
|
||||
char *t = getenv("TERM");
|
||||
if (!t || strncmp(t, "xterm", 5))
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (isatty(0))
|
||||
fd = 0;
|
||||
else {
|
||||
fd = open("/dev/tty", O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "xtitle: couldn't open terminal: %s", strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
openned = 1;
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
#ifdef BASH_BUILTIN
|
||||
WORD_LIST *l = loptend;
|
||||
char sp = ' ';
|
||||
write(fd, "\33]0;", 4);
|
||||
while (l) {
|
||||
write(fd, l->word->word, strlen(l->word->word));
|
||||
if (l->next)
|
||||
write(fd, &sp, 1);
|
||||
l = l->next;
|
||||
}
|
||||
write(fd, "\33\\", 2);
|
||||
#else
|
||||
int i;
|
||||
char sp = ' ';
|
||||
write(fd, "\33]0;", 4);
|
||||
for (i = optind; i < argc; i++) {
|
||||
write(fd, argv[i], strlen(argv[i]));
|
||||
if (i < argc - 1)
|
||||
write(fd, &sp, 1);
|
||||
}
|
||||
write(fd, "\33\\", 2);
|
||||
#endif
|
||||
} else {
|
||||
struct termios o, n;
|
||||
char hack;
|
||||
int state = 0;
|
||||
|
||||
tcgetattr(fd, &o);
|
||||
n = o;
|
||||
n.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|
||||
|INLCR|IGNCR|ICRNL|IXON);
|
||||
n.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||
n.c_cflag &= ~(CSIZE|PARENB);
|
||||
n.c_cflag |= CS8;
|
||||
tcsetattr(fd, TCSAFLUSH, &n);
|
||||
write(fd, "\33[21t", 5);
|
||||
|
||||
while (state != -1) {
|
||||
if (read(fd, &hack, 1) < 1)
|
||||
break;
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (hack == '\33') state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (hack == ']') state = 2; else state = 0;
|
||||
break;
|
||||
case 2:
|
||||
if (hack == 'l') state = 3; else state = 0;
|
||||
break;
|
||||
case 3:
|
||||
if (hack == '\33') state = 4; else putchar(hack);
|
||||
break;
|
||||
case 4:
|
||||
if (hack == '\\') { state = -1; putchar('\n'); }
|
||||
else { putchar('\33'); putchar(hack); state = 3; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tcsetattr(fd, TCSAFLUSH, &o);
|
||||
}
|
||||
|
||||
if (openned)
|
||||
close(fd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef BASH_BUILTIN
|
||||
|
||||
static char *xtitle_doc[] = {
|
||||
"Set xterm window title.",
|
||||
"",
|
||||
"Either set or read the title of the current xterm window. With the",
|
||||
"-q option, writes the current xterm title to standard output. Without",
|
||||
"the -q option, sets the xterm title to be the arguments given,",
|
||||
"separated by space characters. [By Mark Wooding, mdw@nsict.org]",
|
||||
0
|
||||
};
|
||||
|
||||
struct builtin xtitle_struct = {
|
||||
"xtitle",
|
||||
xtitle_builtin,
|
||||
BUILTIN_ENABLED,
|
||||
xtitle_doc,
|
||||
"xtitle [-q] [arguments]",
|
||||
0
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
#Posted-Date: Fri, 9 Mar 90 18:34:29 EST
|
||||
#Date: Fri, 9 Mar 90 18:34:29 EST
|
||||
#From: "Eirik Fuller" <wonton.tn.cornell.edu!eirik@ucsbcsl.UUCP>
|
||||
#To: bfox@ai.mit.edu (Brian Fox)
|
||||
#Subject: Patch to bash 1.05 for SunView
|
||||
#
|
||||
#I think this works:
|
||||
#
|
||||
Mu|sun-cmd:am:bs:km:pt:li#34:co#80:cl=^L:ce=\E[K:cd=\E[J:rs=\E[s:
|
||||
#
|
||||
#Another alternative is to send the ti string at startup time (and, I
|
||||
#guess, the te string at exit time); that is how vi works in a cmdtool.
|
||||
#The best reason to not do this is that this also disables scrolling
|
||||
#which, as I understand it, is why anyone would use cmdtool in the
|
||||
#first place. Sending the ti string at startup time would do strange
|
||||
#things on other systems too; in xterm it would use the alternate
|
||||
#screen.
|
||||
#
|
||||
#The problem with cmdtool, in case that is less than obvious, is that
|
||||
#almost none of the capabilities advertised in /etc/termcap are enabled
|
||||
#while scrolling is enabled. It has other problems too, like being
|
||||
#part of an outdated proprietary windowing system, but there's probably
|
||||
#no need to dwell on that. In a sense, though, the sun-cmd termcap
|
||||
#entry doesn't lie about the capabilities; I think the termcap man page
|
||||
#does warn about some terminals having cursor motion capabilities only
|
||||
#in the "ti/te window".
|
||||
#
|
||||
#A general solution to this problem would require a termcap capability
|
||||
#which somehow tells which features are available outside of the ti/te
|
||||
#window. There is no such capability in termcap now, of course.
|
||||
@@ -1,27 +0,0 @@
|
||||
From mikel@ora.com Tue Aug 1 12:13:20 1995
|
||||
Flags: 10
|
||||
Return-Path: mikel@ora.com
|
||||
Received: from ruby.ora.com (ruby.ora.com [198.112.208.25]) by odin.INS.CWRU.Edu with ESMTP (8.6.12+cwru/CWRU-2.1-ins)
|
||||
id MAA01565; Tue, 1 Aug 1995 12:13:18 -0400 (from mikel@ora.com for <chet@odin.INS.CWRU.Edu>)
|
||||
Received: (from fax@localhost) by ruby.ora.com (8.6.12/8.6.11) with UUCP id MAA23251; Tue, 1 Aug 1995 12:07:51 -0400
|
||||
Received: by los.ora.com (4.1/Spike-2.1)
|
||||
id AA00672; Tue, 1 Aug 95 08:57:32 EDT
|
||||
Date: Tue, 1 Aug 95 08:57:32 EDT
|
||||
From: mikel@ora.com (Michael Loukides)
|
||||
Message-Id: <9508011257.AA00672@los.ora.com>
|
||||
Subject: Re: Ksh debugger from Rosenblatt's book [for bash]
|
||||
To: Chet Ramey <chet@odin.INS.CWRU.Edu>
|
||||
Cc: cmarie@ora.com, cam@iinet.com.au, brosenblatt@tm.com
|
||||
In-Reply-To: Chet Ramey <chet@odin.INS.CWRU.Edu>, Mon, 31 Jul 1995 16:22:48 -0400
|
||||
|
||||
I've modified a (modified) version of Bill Rosenblatt's ksh debugger
|
||||
to work with bash-2.0. Does ORA have any problem with me distributing
|
||||
it with bash-2.0?
|
||||
|
||||
That's great!
|
||||
|
||||
Go ahead and circulate it; in fact, we should probably grab it and
|
||||
stick it in our ftp archive, and put a reference to it in the book.
|
||||
(Too late to actually discuss the thing, at least for this edition).
|
||||
-------
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
This is a sample implementation of a bash debugger. It is not the same
|
||||
as the project available from http://bashdb.sourceforge.net, and has been
|
||||
deprecated in favor of that implementation.
|
||||
@@ -1,581 +0,0 @@
|
||||
#! /bin/bash
|
||||
# bashdb - Bash shell debugger
|
||||
#
|
||||
# Adapted from an idea in O'Reilly's `Learning the Korn Shell'
|
||||
# Copyright (C) 1993-1994 O'Reilly and Associates, Inc.
|
||||
# Copyright (C) 1998, 1999, 2001 Gary V. Vaughan <gvv@techie.com>>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# NOTE:
|
||||
#
|
||||
# This program requires bash 2.x.
|
||||
# If bash 2.x is installed as "bash2", you can invoke bashdb like this:
|
||||
#
|
||||
# DEBUG_SHELL=/bin/bash2 /bin/bash2 bashdb script.sh
|
||||
|
||||
# TODO:
|
||||
#
|
||||
# break [regexp]
|
||||
# cond [break] [condition]
|
||||
# tbreak [regexp|+lines]
|
||||
# restart
|
||||
# Variable watchpoints
|
||||
# Instrument `source' and `.' files in $_potbelliedpig
|
||||
# be cleverer about lines we allow breakpoints to be set on
|
||||
# break [function_name]
|
||||
|
||||
echo 'Bash Debugger version 1.2.4'
|
||||
|
||||
export _dbname=${0##*/}
|
||||
|
||||
if test $# -lt 1; then
|
||||
echo "$_dbname: Usage: $_dbname filename" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_guineapig=$1
|
||||
|
||||
if test ! -r $1; then
|
||||
echo "$_dbname: Cannot read file '$_guineapig'." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
|
||||
__debug=${TMPDIR-/tmp}/bashdb.$$
|
||||
sed -e '/^# bashdb - Bash shell debugger/,/^# -- DO NOT DELETE THIS LINE -- /d' "$0" > $__debug
|
||||
cat $_guineapig >> $__debug
|
||||
exec ${DEBUG_SHELL-bash} $__debug $_guineapig "$@"
|
||||
|
||||
exit 1
|
||||
|
||||
# -- DO NOT DELETE THIS LINE -- The program depends on it
|
||||
|
||||
#bashdb preamble
|
||||
# $1 name of the original guinea pig script
|
||||
|
||||
__debug=$0
|
||||
_guineapig=$1
|
||||
__steptrap_calls=0
|
||||
|
||||
shift
|
||||
|
||||
shopt -s extglob # turn on extglob so we can parse the debugger funcs
|
||||
|
||||
function _steptrap
|
||||
{
|
||||
local i=0
|
||||
|
||||
_curline=$1
|
||||
|
||||
if (( ++__steptrap_calls > 1 && $_curline == 1 )); then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$_disps" ]; then
|
||||
while (( $i < ${#_disps[@]} ))
|
||||
do
|
||||
if [ -n "${_disps[$i]}" ]; then
|
||||
_msg "${_disps[$i]}: \c"
|
||||
eval _msg ${_disps[$i]}
|
||||
fi
|
||||
let i=$i+1
|
||||
done
|
||||
fi
|
||||
|
||||
if (( $_trace )); then
|
||||
_showline $_curline
|
||||
fi
|
||||
|
||||
if (( $_steps >= 0 )); then
|
||||
let _steps="$_steps - 1"
|
||||
fi
|
||||
|
||||
if _at_linenumbp ; then
|
||||
_msg "Reached breakpoint at line $_curline"
|
||||
_showline $_curline
|
||||
_cmdloop
|
||||
elif [ -n "$_brcond" ] && eval $_brcond; then
|
||||
_msg "Break condition $_brcond true at line $_curline"
|
||||
_showline $_curline
|
||||
_cmdloop
|
||||
elif (( $_steps == 0 )); then
|
||||
# Assuming a real script will have the "#! /bin/sh" at line 1,
|
||||
# assume that when $_curline == 1 we are inside backticks.
|
||||
if (( ! $_trace )); then
|
||||
_msg "Stopped at line $_curline"
|
||||
_showline $_curline
|
||||
fi
|
||||
_cmdloop
|
||||
fi
|
||||
}
|
||||
|
||||
function _setbp
|
||||
{
|
||||
local i f line _x
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
_listbp
|
||||
return
|
||||
fi
|
||||
|
||||
eval "$_seteglob"
|
||||
|
||||
if [[ $1 == *(\+)[1-9]*([0-9]) ]]; then
|
||||
case $1 in
|
||||
+*)
|
||||
# normalize argument, then double it (+2 -> +2 + 2 = 4)
|
||||
_x=${1##*([!1-9])} # cut off non-numeric prefix
|
||||
_x=${x%%*([!0-9])} # cut off non-numeric suffix
|
||||
f=$(( $1 + $_x ))
|
||||
;;
|
||||
*)
|
||||
f=$(( $1 ))
|
||||
;;
|
||||
esac
|
||||
|
||||
# find the next valid line
|
||||
line="${_lines[$f]}"
|
||||
while _invalidbreakp $f
|
||||
do
|
||||
(( f++ ))
|
||||
line="${_lines[$f]}"
|
||||
done
|
||||
|
||||
if (( $f != $1 ))
|
||||
then
|
||||
_msg "Line $1 is not a valid breakpoint"
|
||||
fi
|
||||
|
||||
if [ -n "${_lines[$f]}" ]; then
|
||||
_linebp[$1]=$1;
|
||||
_msg "Breakpoint set at line $f"
|
||||
else
|
||||
_msg "Breakpoints can only be set on executable lines"
|
||||
fi
|
||||
else
|
||||
_msg "Please specify a numeric line number"
|
||||
fi
|
||||
|
||||
eval "$_resteglob"
|
||||
}
|
||||
|
||||
function _listbp
|
||||
{
|
||||
local i
|
||||
|
||||
if [ -n "$_linebp" ]; then
|
||||
_msg "Breakpoints:"
|
||||
for i in ${_linebp[*]}; do
|
||||
_showline $i
|
||||
done
|
||||
else
|
||||
_msg "No breakpoints have been set"
|
||||
fi
|
||||
}
|
||||
|
||||
function _clearbp
|
||||
{
|
||||
local i
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
read -e -p "Delete all breakpoints? "
|
||||
case $REPLY in
|
||||
[yY]*)
|
||||
unset _linebp[*]
|
||||
_msg "All breakpoints have been cleared"
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
fi
|
||||
|
||||
eval "$_seteglob"
|
||||
|
||||
if [[ $1 == [1-9]*([0-9]) ]]; then
|
||||
unset _linebp[$1]
|
||||
_msg "Breakpoint cleared at line $1"
|
||||
else
|
||||
_msg "Please specify a numeric line number"
|
||||
fi
|
||||
|
||||
eval "$_resteglob"
|
||||
}
|
||||
|
||||
function _setbc
|
||||
{
|
||||
if (( $# > 0 )); then
|
||||
_brcond=$@
|
||||
_msg "Break when true: $_brcond"
|
||||
else
|
||||
_brcond=
|
||||
_msg "Break condition cleared"
|
||||
fi
|
||||
}
|
||||
|
||||
function _setdisp
|
||||
{
|
||||
if [ -z "$1" ]; then
|
||||
_listdisp
|
||||
else
|
||||
_disps[${#_disps[@]}]="$1"
|
||||
if (( ${#_disps[@]} < 10 ))
|
||||
then
|
||||
_msg " ${#_disps[@]}: $1"
|
||||
else
|
||||
_msg "${#_disps[@]}: $1"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function _listdisp
|
||||
{
|
||||
local i=0 j
|
||||
|
||||
if [ -n "$_disps" ]; then
|
||||
while (( $i < ${#_disps[@]} ))
|
||||
do
|
||||
let j=$i+1
|
||||
if (( ${#_disps[@]} < 10 ))
|
||||
then
|
||||
_msg " $j: ${_disps[$i]}"
|
||||
else
|
||||
_msg "$j: ${_disps[$i]}"
|
||||
fi
|
||||
let i=$j
|
||||
done
|
||||
else
|
||||
_msg "No displays have been set"
|
||||
fi
|
||||
}
|
||||
|
||||
function _cleardisp
|
||||
{
|
||||
if (( $# < 1 )) ; then
|
||||
read -e -p "Delete all display expressions? "
|
||||
case $REPLY in
|
||||
[Yy]*)
|
||||
unset _disps[*]
|
||||
_msg "All breakpoints have been cleared"
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
fi
|
||||
|
||||
eval "$_seteglob"
|
||||
|
||||
if [[ $1 == [1-9]*([0-9]) ]]; then
|
||||
unset _disps[$1]
|
||||
_msg "Display $i has been cleared"
|
||||
else
|
||||
_listdisp
|
||||
_msg "Please specify a numeric display number"
|
||||
fi
|
||||
|
||||
eval "$_resteglob"
|
||||
}
|
||||
|
||||
# usage _ftrace -u funcname [funcname...]
|
||||
function _ftrace
|
||||
{
|
||||
local _opt=-t _tmsg="enabled" _func
|
||||
if [[ $1 == -u ]]; then
|
||||
_opt=+t
|
||||
_tmsg="disabled"
|
||||
shift
|
||||
fi
|
||||
for _func; do
|
||||
declare -f $_opt $_func
|
||||
_msg "Tracing $_tmsg for function $_func"
|
||||
done
|
||||
}
|
||||
|
||||
function _cmdloop
|
||||
{
|
||||
local cmd args
|
||||
|
||||
while read -e -p "bashdb> " cmd args; do
|
||||
test -n "$cmd" && history -s "$cmd $args" # save on history list
|
||||
test -n "$cmd" || { set $_lastcmd; cmd=$1; shift; args=$*; }
|
||||
if [ -n "$cmd" ]
|
||||
then
|
||||
case $cmd in
|
||||
b|br|bre|brea|break)
|
||||
_setbp $args
|
||||
_lastcmd="break $args"
|
||||
;;
|
||||
co|con)
|
||||
_msg "ambiguous command: '$cmd', condition, continue?"
|
||||
;;
|
||||
cond|condi|condit|conditi|conditio|condition)
|
||||
_setbc $args
|
||||
_lastcmd="condition $args"
|
||||
;;
|
||||
c|cont|conti|contin|continu|continue)
|
||||
_lastcmd="continue"
|
||||
return
|
||||
;;
|
||||
d)
|
||||
_msg "ambiguous command: '$cmd', delete, display?"
|
||||
;;
|
||||
de|del|dele|delet|delete)
|
||||
_clearbp $args
|
||||
_lastcmd="delete $args"
|
||||
;;
|
||||
di|dis|disp|displ|displa|display)
|
||||
_setdisp $args
|
||||
_lastcmd="display $args"
|
||||
;;
|
||||
f|ft|ftr|ftra|ftrace)
|
||||
_ftrace $args
|
||||
_lastcmd="ftrace $args"
|
||||
;;
|
||||
\?|h|he|hel|help)
|
||||
_menu
|
||||
_lastcmd="help"
|
||||
;;
|
||||
l|li|lis|list)
|
||||
_displayscript $args
|
||||
# _lastcmd is set in the _displayscript function
|
||||
;;
|
||||
p|pr|pri|prin|print)
|
||||
_examine $args
|
||||
_lastcmd="print $args"
|
||||
;;
|
||||
q|qu|qui|quit)
|
||||
exit
|
||||
;;
|
||||
s|st|ste|step|n|ne|nex|next)
|
||||
let _steps=${args:-1}
|
||||
_lastcmd="next $args"
|
||||
return
|
||||
;;
|
||||
t|tr|tra|trac|trace)
|
||||
_xtrace
|
||||
;;
|
||||
u|un|und|undi|undis|undisp|undispl|undispla|undisplay)
|
||||
_cleardisp $args
|
||||
_lastcmd="undisplay $args"
|
||||
;;
|
||||
!*)
|
||||
eval ${cmd#!} $args
|
||||
_lastcmd="$cmd $args"
|
||||
;;
|
||||
*)
|
||||
_msg "Invalid command: '$cmd'"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function _at_linenumbp
|
||||
{
|
||||
[[ -n ${_linebp[$_curline]} ]]
|
||||
}
|
||||
|
||||
function _invalidbreakp
|
||||
{
|
||||
local line=${_lines[$1]}
|
||||
|
||||
# XXX - should use shell patterns
|
||||
if test -z "$line" \
|
||||
|| expr "$line" : '[ \t]*#.*' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*;;[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*;;[ \t]*#.**$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*;;[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*;;*[ \t]*#.*$' > /dev/null
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function _examine
|
||||
{
|
||||
if [ -n "$*" ]; then
|
||||
_msg "$args: \c"
|
||||
eval _msg $args
|
||||
else
|
||||
_msg "Nothing to print"
|
||||
fi
|
||||
}
|
||||
|
||||
function _displayscript
|
||||
{
|
||||
local i j start end bp cl
|
||||
|
||||
if (( $# == 1 )); then # list 5 lines on either side of $1
|
||||
if [ $1 = "%" ]; then
|
||||
let start=1
|
||||
let end=${#_lines[@]}
|
||||
else
|
||||
let start=$1-5
|
||||
let end=$1+5
|
||||
fi
|
||||
elif (( $# > 1 )); then # list between start and end
|
||||
if [ $1 = "^" ]; then
|
||||
let start=1
|
||||
else
|
||||
let start=$1
|
||||
fi
|
||||
|
||||
if [ $2 = "\$" ]; then
|
||||
let end=${#_lines[@]}
|
||||
else
|
||||
let end=$2
|
||||
fi
|
||||
else # list 5 lines on either side of current line
|
||||
let start=$_curline-5
|
||||
let end=$_curline+5
|
||||
fi
|
||||
|
||||
# normalize start and end
|
||||
if (( $start < 1 )); then
|
||||
start=1
|
||||
fi
|
||||
if (( $end > ${#_lines[@]} )); then
|
||||
end=${#_lines[@]}
|
||||
fi
|
||||
|
||||
cl=$(( $end - $start ))
|
||||
if (( $cl > ${LINES-24} )); then
|
||||
pager=${PAGER-more}
|
||||
else
|
||||
pager=cat
|
||||
fi
|
||||
|
||||
i=$start
|
||||
( while (( $i <= $end )); do
|
||||
_showline $i
|
||||
let i=$i+1
|
||||
done ) 2>&1 | $pager
|
||||
|
||||
# calculate the next block of lines
|
||||
start=$(( $end + 1 ))
|
||||
end=$(( $start + 11 ))
|
||||
if (( $end > ${#_lines[@]} ))
|
||||
then
|
||||
end=${#_lines[@]}
|
||||
fi
|
||||
|
||||
_lastcmd="list $start $end"
|
||||
}
|
||||
|
||||
function _xtrace
|
||||
{
|
||||
let _trace="! $_trace"
|
||||
if (( $_trace )); then
|
||||
_msg "Execution trace on"
|
||||
else
|
||||
_msg "Execution trace off"
|
||||
fi
|
||||
}
|
||||
|
||||
function _msg
|
||||
{
|
||||
echo -e "$@" >&2
|
||||
}
|
||||
|
||||
function _showline
|
||||
{
|
||||
local i=0 bp=' ' line=$1 cl=' '
|
||||
|
||||
if [[ -n ${_linebp[$line]} ]]; then
|
||||
bp='*'
|
||||
fi
|
||||
|
||||
if (( $_curline == $line )); then
|
||||
cl=">"
|
||||
fi
|
||||
|
||||
if (( $line < 100 )); then
|
||||
_msg "${_guineapig/*\//}:$line $bp $cl${_lines[$line]}"
|
||||
elif (( $line < 10 )); then
|
||||
_msg "${_guineapig/*\//}:$line $bp $cl${_lines[$line]}"
|
||||
elif (( $line > 0 )); then
|
||||
_msg "${_guineapig/*\//}:$line $bp $cl${_lines[$line]}"
|
||||
fi
|
||||
}
|
||||
|
||||
function _cleanup
|
||||
{
|
||||
rm -f $__debug $_potbelliedpig 2> /dev/null
|
||||
}
|
||||
|
||||
function _menu
|
||||
{
|
||||
_msg 'bashdb commands:
|
||||
break N set breakpoint at line N
|
||||
break list breakpoints & break condition
|
||||
condition foo set break condition to foo
|
||||
condition clear break condition
|
||||
delete N clear breakpoint at line N
|
||||
delete clear all breakpoints
|
||||
display EXP evaluate and display EXP for each debug step
|
||||
display show a list of display expressions
|
||||
undisplay N remove display expression N
|
||||
list N M display all lines of script between N and M
|
||||
list N display 5 lines of script either side of line N
|
||||
list display 5 lines if script either side of current line
|
||||
continue continue execution upto next breakpoint
|
||||
next [N] execute [N] statements (default 1)
|
||||
print expr prints the value of an expression
|
||||
trace toggle execution trace on/off
|
||||
ftrace [-u] func make the debugger step into function FUNC
|
||||
(-u turns off tracing FUNC)
|
||||
help print this menu
|
||||
! string passes string to a shell
|
||||
quit quit'
|
||||
}
|
||||
|
||||
shopt -u extglob
|
||||
|
||||
HISTFILE=~/.bashdb_history
|
||||
set -o history
|
||||
set +H
|
||||
|
||||
# strings to save and restore the setting of `extglob' in debugger functions
|
||||
# that need it
|
||||
_seteglob='local __eopt=-u ; shopt -q extglob && __eopt=-s ; shopt -s extglob'
|
||||
_resteglob='shopt $__eopt extglob'
|
||||
|
||||
_linebp=()
|
||||
let _trace=0
|
||||
let _i=1
|
||||
|
||||
# Be careful about quoted newlines
|
||||
_potbelliedpig=${TMPDIR-/tmp}/${_guineapig/*\//}.$$
|
||||
sed 's,\\$,\\\\,' $_guineapig > $_potbelliedpig
|
||||
|
||||
_msg "Reading source from file: $_guineapig"
|
||||
while read; do
|
||||
_lines[$_i]=$REPLY
|
||||
let _i=$_i+1
|
||||
done < $_potbelliedpig
|
||||
|
||||
trap _cleanup EXIT
|
||||
# Assuming a real script will have the "#! /bin/sh" at line 1,
|
||||
# don't stop at line 1 on the first run
|
||||
let _steps=1
|
||||
LINENO=-1
|
||||
trap '_steptrap $LINENO' DEBUG
|
||||
@@ -1,177 +0,0 @@
|
||||
;;; bashdb.el --- Grand Unified Debugger mode for running bashdb
|
||||
;; Copyright (C) 2000, 2001 Masatake YAMATO
|
||||
|
||||
;; Author: Masatake YAMATO <jet@gyve.org>
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 2 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful, but
|
||||
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program; if not, write to the Free Software Foundation,
|
||||
;; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
;; Commentary:
|
||||
;; This program may run on Emacs 21.0.91 and XEmacs 21.1.
|
||||
;;
|
||||
;; Put
|
||||
;; (autoload 'bashdb "bashdb" "Run bashdb" t nil)
|
||||
;; to your .emacs.
|
||||
;; M-x bashdb
|
||||
;; Run bashdb (like this): bashdb target.sh
|
||||
;;
|
||||
;; About bashdb:
|
||||
;; You can get bashdb from
|
||||
;; http://www.oranda.demon.co.uk/development.html
|
||||
;;
|
||||
;; bashdb.el is based on perldb in gud.el in XEmacs 21.1.
|
||||
|
||||
;; Revision:
|
||||
;; $Revision: 1.6 $
|
||||
;; $Log: bashdb.el,v $
|
||||
;; Revision 1.6 2001/01/06 12:18:06 masata-y
|
||||
;; Write note about XEmacs.
|
||||
;;
|
||||
;;
|
||||
|
||||
|
||||
;;; Code:
|
||||
(require 'gud)
|
||||
|
||||
;; User customizable variable
|
||||
(defcustom gud-bashdb-command-name "bashdb"
|
||||
"File name for executing Bashdb."
|
||||
:type 'string
|
||||
:group 'gud)
|
||||
|
||||
;; History of argument lists passed to bashdb.
|
||||
(defvar gud-bashdb-history nil)
|
||||
|
||||
(defun gud-bashdb-massage-args (file args)
|
||||
(if xemacsp
|
||||
(cons (file-name-nondirectory file) args)
|
||||
args))
|
||||
|
||||
;; There's no guarantee that Emacs will hand the filter the entire
|
||||
;; marker at once; it could be broken up across several strings. We
|
||||
;; might even receive a big chunk with several markers in it. If we
|
||||
;; receive a chunk of text which looks like it might contain the
|
||||
;; beginning of a marker, we save it here between calls to the
|
||||
;; filter.
|
||||
(if xemacsp
|
||||
(defvar gud-bashdb-marker-acc ""))
|
||||
(defun gud-bashdb-marker-acc ()
|
||||
(if xemacsp
|
||||
gud-bashdb-marker-acc
|
||||
gud-marker-acc))
|
||||
(defun gud-bashdb-marker-acc-quote ()
|
||||
(if xemacsp
|
||||
'gud-bashdb-marker-acc
|
||||
'gud-marker-acc))
|
||||
|
||||
(defun gud-bashdb-marker-filter (string)
|
||||
(save-match-data
|
||||
(set (gud-bashdb-marker-acc-quote)
|
||||
(concat (gud-bashdb-marker-acc) string))
|
||||
(let ((output ""))
|
||||
;; Process all the complete markers in this chunk.
|
||||
(while (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>.*\n"
|
||||
(gud-bashdb-marker-acc))
|
||||
(setq
|
||||
;; Extract the frame position from the marker.
|
||||
gud-last-frame (cons
|
||||
(substring (gud-bashdb-marker-acc)
|
||||
(match-beginning 1)
|
||||
(match-end 1))
|
||||
(string-to-int
|
||||
(substring (gud-bashdb-marker-acc)
|
||||
(match-beginning 2)
|
||||
(match-end 2))))
|
||||
;; Append any text before the marker to the output we're going
|
||||
;; to return - we don't include the marker in this text.
|
||||
output (concat output
|
||||
(substring (gud-bashdb-marker-acc) 0 (match-beginning 0))))
|
||||
;; Set the accumulator to the remaining text.
|
||||
(set
|
||||
(gud-bashdb-marker-acc-quote) (substring
|
||||
(gud-bashdb-marker-acc) (match-end 0))))
|
||||
|
||||
;; Does the remaining text look like it might end with the
|
||||
;; beginning of another marker? If it does, then keep it in
|
||||
;; (gud-bashdb-marker-acc) until we receive the rest of it. Since we
|
||||
;; know the full marker regexp above failed, it's pretty simple to
|
||||
;; test for marker starts.
|
||||
(if (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>" (gud-bashdb-marker-acc))
|
||||
(progn
|
||||
;; Everything before the potential marker start can be output.
|
||||
(setq output (concat output (substring (gud-bashdb-marker-acc)
|
||||
0 (match-beginning 0))))
|
||||
;; Everything after, we save, to combine with later input.
|
||||
(set (gud-bashdb-marker-acc-quote)
|
||||
(substring (gud-bashdb-marker-acc) (match-beginning 0))))
|
||||
|
||||
(setq output (concat output (gud-bashdb-marker-acc)))
|
||||
(set (gud-bashdb-marker-acc-quote) ""))
|
||||
|
||||
output)))
|
||||
|
||||
(defun gud-bashdb-find-file (f)
|
||||
(find-file-noselect f))
|
||||
|
||||
;;;###autoload
|
||||
(defun bashdb (command-line)
|
||||
"Run bashdb on program FILE in buffer *gud-FILE*.
|
||||
The directory containing FILE becomes the initial working directory
|
||||
and source-file directory for your debugger."
|
||||
(interactive
|
||||
(if xemacsp
|
||||
(list (read-from-minibuffer "Run bashdb (like this): "
|
||||
(if (consp gud-bashdb-history)
|
||||
(car gud-bashdb-history)
|
||||
(format "%s " gud-bashdb-command-name))
|
||||
nil nil
|
||||
'(gud-bashdb-history . 1)))
|
||||
(list (gud-query-cmdline 'bashdb))
|
||||
))
|
||||
|
||||
(if xemacsp
|
||||
(progn
|
||||
(gud-overload-functions '((gud-massage-args . gud-bashdb-massage-args)
|
||||
(gud-marker-filter . gud-bashdb-marker-filter)
|
||||
(gud-find-file . gud-bashdb-find-file)))
|
||||
(gud-common-init command-line gud-bashdb-command-name))
|
||||
(gud-common-init command-line 'gud-bashdb-massage-args
|
||||
'gud-bashdb-marker-filter 'gud-bashdb-find-file)
|
||||
(set (make-local-variable 'gud-minor-mode) 'bashdb))
|
||||
|
||||
;; Unsupported commands
|
||||
;; condition foo set break condition to foo
|
||||
;; condition clear break condition
|
||||
;; display EXP evaluate and display EXP for each debug step
|
||||
;; display show a list of display expressions
|
||||
;; undisplay N remove display expression N
|
||||
;; ! string passes string to a shell
|
||||
;; quit quit
|
||||
|
||||
(gud-def gud-break "break %l" "\C-b" "Set breakpoint at current line.")
|
||||
(gud-def gud-list-break "break" "b" "List breakpoints & break condition.")
|
||||
(gud-def gud-remove "delete %l" "\C-d" "Remove breakpoint at current line")
|
||||
(gud-def gud-remove-all "delete" "d" "Clear all breakpoints")
|
||||
(gud-def gud-cont "continue" "\C-r" "Continue with display.")
|
||||
(gud-def gud-next "next" "\C-n" "Step one line (skip functions).")
|
||||
(gud-def gud-print "print %e" "\C-p" "Evaluate bash expression at point.")
|
||||
(gud-def gud-help "help" "h" "Show all commands.")
|
||||
(gud-def gud-trace "trace" "t" "Toggle execution trace on/off")
|
||||
|
||||
(setq comint-prompt-regexp "^bashdb> ")
|
||||
(setq paragraph-start comint-prompt-regexp)
|
||||
(run-hooks 'bashdb-mode-hook))
|
||||
|
||||
(provide 'bashdb)
|
||||
;; bashdb.el ends here
|
||||
@@ -1,561 +0,0 @@
|
||||
#! /bin/bash
|
||||
# bashdb - Bash shell debugger
|
||||
#
|
||||
# Adapted from an idea in O'Reilly's `Learning the Korn Shell'
|
||||
# Copyright (C) 1993-1994 O'Reilly and Associates, Inc.
|
||||
# Copyright (C) 1998, 1999, 2001 Gary V. Vaughan <gvv@techie.com>>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# NOTE:
|
||||
#
|
||||
# This program requires bash 2.x.
|
||||
# If bash 2.x is installed as "bash2", you can invoke bashdb like this:
|
||||
#
|
||||
# DEBUG_SHELL=/bin/bash2 /bin/bash2 bashdb script.sh
|
||||
|
||||
# TODO:
|
||||
#
|
||||
# break [regexp]
|
||||
# cond [break] [condition]
|
||||
# tbreak [regexp|+lines]
|
||||
# restart
|
||||
# Variable watchpoints
|
||||
# Output colourization
|
||||
# History with csh ^ substitution? Or write a readline frontend?
|
||||
# Instrument shell functions with the _steptrap in $_potbelliedpig
|
||||
# Instrument `source' and `.' files in $_potbelliedpig
|
||||
# be cleverer about lines we allow breakpoints to be set on
|
||||
# break [function_name]
|
||||
|
||||
|
||||
echo 'Bash Debugger version 1.2.4'
|
||||
|
||||
export _dbname=$(echo "X$0"|sed -e 's,^X,,' -e 's,^.*/,,')
|
||||
|
||||
if test $# -lt 1; then
|
||||
echo "$_dbname: Usage: $_dbname <filename>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_guineapig=$1
|
||||
|
||||
if test ! -r $1; then
|
||||
echo "$_dbname: Cannot read file '$_guineapig'." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
|
||||
__debug=${TMPDIR-/tmp}/bashdb.$$
|
||||
sed -e '/^# bashdb - Bash shell debugger/,/^# -- DO NOT DELETE THIS LINE -- /d' "$0" > $__debug
|
||||
cat $_guineapig >> $__debug
|
||||
exec ${DEBUG_SHELL-bash} $__debug $_guineapig "$@"
|
||||
|
||||
exit 1
|
||||
|
||||
# -- DO NOT DELETE THIS LINE -- The program depends on it
|
||||
|
||||
#bashdb preamble
|
||||
# $1 name of the original guinea pig script
|
||||
|
||||
__debug=$0
|
||||
_guineapig=$1
|
||||
|
||||
shift
|
||||
|
||||
function _steptrap
|
||||
{
|
||||
local i=0
|
||||
|
||||
_curline=$1
|
||||
|
||||
if [ -n "$_disps" ]
|
||||
then
|
||||
while (( $i < ${#_disps[@]} ))
|
||||
do
|
||||
if [ -n "${_disps[$i]}" ]
|
||||
then
|
||||
_msg "${_disps[$i]}: \c"
|
||||
eval _msg ${_disps[$i]}
|
||||
fi
|
||||
let i=$i+1
|
||||
done
|
||||
fi
|
||||
|
||||
if (( $_trace )); then
|
||||
_showline $_curline
|
||||
fi
|
||||
|
||||
if (( $_steps >= 0 )); then
|
||||
let _steps="$_steps - 1"
|
||||
fi
|
||||
|
||||
if _at_linenumbp ; then
|
||||
_msg "Reached breakpoint at line $_curline"
|
||||
_showline $_curline
|
||||
_cmdloop
|
||||
elif [ -n "$_brcond" ] && eval $_brcond; then
|
||||
_msg "Break condition $_brcond true at line $_curline"
|
||||
_showline $_curline
|
||||
_cmdloop
|
||||
elif (( $_steps == 0 && $_curline > 1)); then
|
||||
# Assuming a real script will have the "#! /bin/sh" at line 1,
|
||||
# assume that when $_curline == 1 we are inside backticks.
|
||||
if (( ! $_trace )); then
|
||||
_msg "Stopped at line $_curline"
|
||||
_showline $_curline
|
||||
fi
|
||||
_cmdloop
|
||||
fi
|
||||
}
|
||||
|
||||
function _setbp
|
||||
{
|
||||
local i f line
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
_listbp
|
||||
elif [ $(echo $1 | grep '^\+*[1-9][0-9]*') ]
|
||||
then
|
||||
case $1 in
|
||||
+*)
|
||||
let f="$1 + `expr $1 : '+*\([1-9][0-9]*\)'`"
|
||||
;;
|
||||
*)
|
||||
let f=$1
|
||||
;;
|
||||
esac
|
||||
|
||||
# find the next valid line
|
||||
line="${_lines[$f]}"
|
||||
while _invalidbreakp $f
|
||||
do
|
||||
let f="$f + 1"
|
||||
line="${_lines[$f]}"
|
||||
done
|
||||
|
||||
if (( $f != $1 ))
|
||||
then
|
||||
_msg "Line $1 is not a valid breakpoint"
|
||||
fi
|
||||
|
||||
if [ -n "${_lines[$f]}" ]
|
||||
then
|
||||
_linebp=($(echo $( (for i in ${_linebp[*]} $1; do
|
||||
echo $i; done) | sort -n) ))
|
||||
_msg "Breakpoint set at line $f"
|
||||
else
|
||||
_msg "Breakpoints can only be set on executable lines"
|
||||
fi
|
||||
else
|
||||
_msg "Please specify a numeric line number"
|
||||
fi
|
||||
}
|
||||
|
||||
function _listbp
|
||||
{
|
||||
local i
|
||||
|
||||
if [ -n "$_linebp" ]
|
||||
then
|
||||
_msg "Breakpoints:"
|
||||
for i in ${_linebp[*]}; do
|
||||
_showline $i
|
||||
done
|
||||
else
|
||||
_msg "No breakpoints have been set"
|
||||
fi
|
||||
}
|
||||
|
||||
function _clearbp
|
||||
{
|
||||
local i
|
||||
if [ -z "$1" ]; then
|
||||
read -e -p "Delete all breakpoints? "
|
||||
case $REPLY in
|
||||
y*)
|
||||
unset _linebp[*]
|
||||
_msg "All breakpoints have been cleared"
|
||||
;;
|
||||
esac
|
||||
elif [ $(echo $1 | grep '^[0-9]*') ]; then
|
||||
_linebp=($(echo $(for i in ${_linebp[*]}; do
|
||||
if (( $1 != $i )); then echo $1; fi; done) ))
|
||||
_msg "Breakpoint cleared at line $1"
|
||||
else
|
||||
_msg "Please specify a numeric line number"
|
||||
fi
|
||||
}
|
||||
|
||||
function _setbc
|
||||
{
|
||||
if [ -n "$*" ]
|
||||
then
|
||||
_brcond=$args
|
||||
_msg "Break when true: $_brcond"
|
||||
else
|
||||
_brcond=
|
||||
_msg "Break condition cleared"
|
||||
fi
|
||||
}
|
||||
|
||||
function _setdisp
|
||||
{
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
_listdisp
|
||||
else
|
||||
_disps[${#_disps[@]}]="$1"
|
||||
if (( ${#_disps[@]} < 10 ))
|
||||
then
|
||||
_msg " ${#_disps[@]}: $1"
|
||||
else
|
||||
_msg "${#_disps[@]}: $1"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function _listdisp
|
||||
{
|
||||
local i=0 j
|
||||
|
||||
if [ -n "$_disps" ]
|
||||
then
|
||||
while (( $i < ${#_disps[@]} ))
|
||||
do
|
||||
let j=$i+1
|
||||
if (( ${#_disps[@]} < 10 ))
|
||||
then
|
||||
_msg " $j: ${_disps[$i]}"
|
||||
else
|
||||
_msg "$j: ${_disps[$i]}"
|
||||
fi
|
||||
let i=$j
|
||||
done
|
||||
else
|
||||
_msg "No displays have been set"
|
||||
fi
|
||||
}
|
||||
|
||||
function _cleardisp
|
||||
{
|
||||
if (( $# < 1 ))
|
||||
then
|
||||
read -e -p "Delete all display expressions? "
|
||||
case $REPLY in
|
||||
y*)
|
||||
unset _disps[*]
|
||||
_msg "All breakpoints have been cleared"
|
||||
;;
|
||||
esac
|
||||
elif [ $(echo $1 | grep '^[0-9]*') ]
|
||||
then
|
||||
unset _disps[$1]
|
||||
_msg "Display $i has been cleared"
|
||||
else
|
||||
_listdisp
|
||||
_msg "Please specify a numeric display number"
|
||||
fi
|
||||
}
|
||||
|
||||
function _cmdloop
|
||||
{
|
||||
local cmd args
|
||||
|
||||
while read -e -p "bashdb> " cmd args; do
|
||||
test -n "$cmd" || { set $_lastcmd; cmd=$1; shift; args=$*; }
|
||||
if [ -n "$cmd" ]
|
||||
then
|
||||
case $cmd in
|
||||
b|br|bre|brea|break)
|
||||
_setbp $args
|
||||
_lastcmd="break $args"
|
||||
;;
|
||||
co|con)
|
||||
_msg "ambiguous command: '$cmd', condition, continue?"
|
||||
;;
|
||||
cond|condi|condit|conditi|conditio|condition)
|
||||
_setbc $args
|
||||
_lastcmd="condition $args"
|
||||
;;
|
||||
c|cont|conti|contin|continu|continue)
|
||||
_lastcmd="continue"
|
||||
return
|
||||
;;
|
||||
d)
|
||||
_msg "ambiguous command: '$cmd', delete, display?"
|
||||
;;
|
||||
de|del|dele|delet|delete)
|
||||
_clearbp $args
|
||||
_lastcmd="delete $args"
|
||||
;;
|
||||
di|dis|disp|displ|displa|display)
|
||||
_setdisp $args
|
||||
_lastcmd="display $args"
|
||||
;;
|
||||
\?|h|he|hel|help)
|
||||
_menu
|
||||
_lastcmd="help"
|
||||
;;
|
||||
l|li|lis|list)
|
||||
_displayscript $args
|
||||
# _lastcmd is set in the _displayscript function
|
||||
;;
|
||||
p|pr|pri|prin|print)
|
||||
_examine $args
|
||||
_lastcmd="print $args"
|
||||
;;
|
||||
q|qu|qui|quit)
|
||||
exit
|
||||
;;
|
||||
s|st|ste|step|n|ne|nex|next)
|
||||
let _steps=${args:-1}
|
||||
_lastcmd="next $args"
|
||||
return
|
||||
;;
|
||||
t|tr|tra|trac|trace)
|
||||
_xtrace
|
||||
;;
|
||||
u|un|und|undi|undis|undisp|undispl|undispla|undisplay)
|
||||
_cleardisp $args
|
||||
_lastcmd="undisplay $args"
|
||||
;;
|
||||
!*)
|
||||
eval ${cmd#!} $args
|
||||
_lastcmd="$cmd $args"
|
||||
;;
|
||||
*)
|
||||
_msg "Invalid command: '$cmd'"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function _at_linenumbp
|
||||
{
|
||||
local i=0
|
||||
|
||||
if [ "$_linebp" ]
|
||||
then
|
||||
while (( $i < ${#_linebp[@]} )); do
|
||||
if (( ${_linebp[$i]} == $_curline )); then
|
||||
return 0
|
||||
fi
|
||||
let i=$i+1
|
||||
done
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function _invalidbreakp
|
||||
{
|
||||
local line=${_lines[$1]}
|
||||
|
||||
if test -z "$line" \
|
||||
|| expr "$line" : '[ \t]*#.*' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*;;[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*;;[ \t]*#.**$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*;;[ \t]*$' > /dev/null \
|
||||
|| expr "$line" : '[ \t]*[^)]*)[ \t]*;;*[ \t]*#.*$' > /dev/null
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function _examine
|
||||
{
|
||||
if [ -n "$*" ]
|
||||
then
|
||||
_msg "$args: \c"
|
||||
eval _msg $args
|
||||
else
|
||||
_msg "Nothing to print"
|
||||
fi
|
||||
}
|
||||
|
||||
function _displayscript
|
||||
{
|
||||
local i j start end bp cl
|
||||
|
||||
if (( $# == 1 ))
|
||||
then
|
||||
if test $1 = "%"
|
||||
then
|
||||
let start=1
|
||||
let end=${#_lines[@]}
|
||||
else
|
||||
let start=$1-5
|
||||
let end=$1+5
|
||||
fi
|
||||
elif (( $# > 1 ))
|
||||
then
|
||||
if test $1 = "^"
|
||||
then
|
||||
let start=1
|
||||
else
|
||||
let start=$1
|
||||
fi
|
||||
|
||||
if test $2 = "\$"
|
||||
then
|
||||
let end=${#_lines[@]}
|
||||
else
|
||||
let end=$2
|
||||
fi
|
||||
else
|
||||
let start=$_curline-5
|
||||
let end=$_curline+5
|
||||
fi
|
||||
|
||||
if (( $start < 1 ))
|
||||
then
|
||||
start=1
|
||||
fi
|
||||
if (( $end > ${#_lines[@]} ))
|
||||
then
|
||||
end=${#_lines[@]}
|
||||
fi
|
||||
|
||||
let cl=$end-$start
|
||||
if (( $cl > ${LINES-24} ))
|
||||
then
|
||||
pager=${PAGER-more}
|
||||
else
|
||||
pager=cat
|
||||
fi
|
||||
|
||||
i=$start
|
||||
( while (( $i <= $end )); do
|
||||
_showline $i
|
||||
let i=$i+1
|
||||
done ) 2>&1 | $pager
|
||||
|
||||
# calculate the next block of lines
|
||||
let start=$end+1
|
||||
let end=$start+11
|
||||
if (( $end > ${#_lines[@]} ))
|
||||
then
|
||||
end=${#_lines[@]}
|
||||
fi
|
||||
|
||||
_lastcmd="list $start $end"
|
||||
}
|
||||
|
||||
function _xtrace
|
||||
{
|
||||
let _trace="! $_trace"
|
||||
if (( $_trace )); then
|
||||
_msg "Execution trace on"
|
||||
else
|
||||
_msg "Execution trace off"
|
||||
fi
|
||||
}
|
||||
|
||||
function _msg
|
||||
{
|
||||
echo -e "$@" >&2
|
||||
}
|
||||
|
||||
function _showline
|
||||
{
|
||||
local i=0 bp=' ' line=$1
|
||||
|
||||
while (( $i < ${#_linebp[@]} ))
|
||||
do
|
||||
if [ ${_linebp[$i]} ] && (( ${_linebp[$i]} == $line ))
|
||||
then
|
||||
bp='*'
|
||||
fi
|
||||
let i=$i+1
|
||||
done
|
||||
|
||||
if (( $_curline == $line )); then
|
||||
cl=">"
|
||||
else
|
||||
cl=" "
|
||||
fi
|
||||
|
||||
if (( $line < 100 )); then
|
||||
_msg "$_guineapig:$line $bp $cl${_lines[$line]}"
|
||||
elif (( $line < 10 )); then
|
||||
_msg "$_guineapig:$line $bp $cl${_lines[$line]}"
|
||||
elif (( $line > 0 )); then
|
||||
_msg "$_guineapig:$line $bp $cl${_lines[$line]}"
|
||||
fi
|
||||
}
|
||||
|
||||
function _cleanup
|
||||
{
|
||||
rm -f $__debug $_potbelliedpig 2> /dev/null
|
||||
}
|
||||
|
||||
function _menu
|
||||
{
|
||||
_msg 'bashdb commands:
|
||||
break N set breakpoint at line N
|
||||
break list breakpoints & break condition
|
||||
condition foo set break condition to foo
|
||||
condition clear break condition
|
||||
delete N clear breakpoint at line N
|
||||
delete clear all breakpoints
|
||||
display EXP evaluate and display EXP for each debug step
|
||||
display show a list of display expressions
|
||||
undisplay N remove display expression N
|
||||
list N M display all lines of script between N and M
|
||||
list N display 5 lines of script either side of line N
|
||||
list display 5 lines if script either side of current line
|
||||
continue continue execution upto next breakpoint
|
||||
next [N] execute [N] statements (default 1)
|
||||
print expr prints the value of an expression
|
||||
trace toggle execution trace on/off
|
||||
help print this menu
|
||||
! string passes string to a shell
|
||||
quit quit'
|
||||
}
|
||||
|
||||
|
||||
_linebp=
|
||||
let _trace=0
|
||||
let _i=1
|
||||
|
||||
# Be careful about quoted newlines
|
||||
_potbelliedpig=${TMPDIR-/tmp}/$_guineapig.$$
|
||||
sed 's,\\$,\\\\,' $_guineapig > $_potbelliedpig
|
||||
|
||||
_msg "Reading source from file: $_guineapig"
|
||||
while read; do
|
||||
_lines[$_i]=$REPLY
|
||||
let _i=$_i+1
|
||||
done < $_potbelliedpig
|
||||
|
||||
trap _cleanup EXIT
|
||||
# Assuming a real script will have the "#! /bin/sh" at line 1,
|
||||
# don't stop at line 1 on the first run
|
||||
let _steps=2
|
||||
LINENO=-2
|
||||
trap '_steptrap $LINENO' DEBUG
|
||||
:
|
||||
@@ -1,29 +0,0 @@
|
||||
From friedman@cli.com Thu May 25 12:19:06 1995
|
||||
Flags: 10
|
||||
Return-Path: friedman@cli.com
|
||||
Received: from po.cwru.edu (root@po.CWRU.Edu [129.22.4.2]) by odin.INS.CWRU.Edu with ESMTP (8.6.10+cwru/CWRU-2.1-ins)
|
||||
id MAA08685; Thu, 25 May 1995 12:19:05 -0400 (from friedman@cli.com for <chet@odin.INS.CWRU.Edu>)
|
||||
Received: from cli.com (cli.com [192.31.85.1]) by po.cwru.edu with SMTP (8.6.10+cwru/CWRU-2.3)
|
||||
id MAA11299; Thu, 25 May 1995 12:19:00 -0400 (from friedman@cli.com for <chet@po.cwru.edu>)
|
||||
Received: from tepui.cli.com by cli.com (4.1/SMI-4.1)
|
||||
id AA27213; Thu, 25 May 95 11:18:25 CDT
|
||||
Received: by tepui.cli.com (4.1) id AA16031; Thu, 25 May 95 11:18:23 CDT
|
||||
Message-Id: <9505251618.AA16031@tepui.cli.com>
|
||||
From: friedman@gnu.ai.mit.edu (Noah Friedman)
|
||||
To: chet@po.cwru.edu
|
||||
Subject: Bash scripts
|
||||
Reply-To: friedman@gnu.ai.mit.edu
|
||||
In-Reply-To: <chet@odin.ins.cwru.edu> Thu, 25 May 1995 11:19:59 -0400
|
||||
References: <9505251519.AA06424.SM@odin.INS.CWRU.Edu>
|
||||
Date: Thu, 25 May 95 11:18:21 CST
|
||||
|
||||
>Hi. I snagged some of your bash functions from your home directory on
|
||||
>the FSF machines (naughty, I know), and I was wondering if you'd let
|
||||
>me distribute them with bash-2.0. Thanks.
|
||||
|
||||
Sure. I think there's a later copy in
|
||||
~ftp/friedman/shell-inits/init-4.89.tar.gz. There are also some elisp and
|
||||
es frobs in that file.
|
||||
|
||||
It should serve as a pretty good example of how to get carried away. :-)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
This collection of scripts was originally written for older versions
|
||||
of bash by Noah Friedman (friedman@gnu.ai.mit.edu). The conversion
|
||||
to bash v2 syntax was done by Chet Ramey.
|
||||
|
||||
These scripts are as-is; there is no copyright associated with
|
||||
any of them. They exist simply as examples of bash scripting.
|
||||
|
||||
Here's a description of what's in this directory:
|
||||
|
||||
aref.bash Pseudo-arrays and substring indexing examples.
|
||||
bash.sub.bash Library functions used by require.bash.
|
||||
bash_version.bash A function to slice up $BASH_VERSION.
|
||||
meta.bash Enable and disable eight-bit readline input.
|
||||
mktmp.bash Make a temporary file with a unique name.
|
||||
number.bash A fun hack to translate numerals into English.
|
||||
PERMISSION Permissions to use the scripts in this directory.
|
||||
prompt.bash A way to set PS1 to some predefined strings.
|
||||
README README
|
||||
remap_keys.bash A front end to 'bind' to redo readline bindings.
|
||||
require.bash Lisp-like require/provide library functions for bash.
|
||||
send_mail.bash Replacement SMTP client written in bash.
|
||||
shcat.bash Bash replacement for 'cat(1)'.
|
||||
source.bash Replacement for source that uses current directory.
|
||||
string.bash The string(3) functions at the shell level.
|
||||
stty.bash Front-end to stty(1) that changes readline bindings too.
|
||||
y_or_n_p.bash Prompt for a yes/no/quit answer.
|
||||
@@ -1,44 +0,0 @@
|
||||
# aref.bash --- pseudo-array manipulating routines
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created 1992-07-01
|
||||
# Last modified: 1993-02-03
|
||||
# Public domain
|
||||
|
||||
# Conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring aref:
|
||||
# Usage: aref NAME INDEX
|
||||
#
|
||||
# In array NAME, access element INDEX (0-origin)
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function aref ()
|
||||
{
|
||||
local name="$1"
|
||||
local index="$2"
|
||||
|
||||
set -- ${!name}
|
||||
[ $index -ge 1 ] && shift $index
|
||||
echo $1
|
||||
}
|
||||
|
||||
#:docstring string_aref:
|
||||
# Usage: aref STRING INDEX
|
||||
#
|
||||
# Echo the INDEXth character in STRING (0-origin) on stdout.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function string_aref ()
|
||||
{
|
||||
local stuff=${1:$2}
|
||||
echo ${stuff:0:1}
|
||||
}
|
||||
|
||||
provide aref
|
||||
|
||||
# aref.bash ends here
|
||||
@@ -1,28 +0,0 @@
|
||||
# bash.sub.bash --- stub for standalone shell scripts using bash library
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-07-13
|
||||
# Last modified: 1993-09-29
|
||||
# Public domain
|
||||
|
||||
#:docstring bash.sub:
|
||||
# Standard subroutines for bash scripts wishing to use "require" to load
|
||||
# libraries.
|
||||
#
|
||||
# Usage: In each directory where a bash script that uses this script
|
||||
# exists, place a copy of this script. Then, at the top of such scripts,
|
||||
# put the command
|
||||
#
|
||||
# source ${0%/*}/bash.sub || exit 1
|
||||
#
|
||||
# Then you can use `require' to load packages.
|
||||
#
|
||||
#:end docstring:
|
||||
|
||||
default_FPATH="~friedman/etc/init/bash/functions/lib"
|
||||
|
||||
source "${default_FPATH}/feature"
|
||||
REQUIRE_FAILURE_FATAL=t
|
||||
|
||||
FPATH="${FPATH-${default_FPATH}}"
|
||||
|
||||
# bash.sub.bash ends here
|
||||
@@ -1,42 +0,0 @@
|
||||
# bash_version.bash --- get major and minor components of bash version number
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-01-26
|
||||
# Last modified: 1993-01-26
|
||||
# Public domain
|
||||
|
||||
# Converted to bash v2 syntax by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring bash_version:
|
||||
# Usage: bash_version {major|minor}
|
||||
#
|
||||
# Echo the major or minor number of this version of bash on stdout, or
|
||||
# just echo $BASH_VERSION if no argument is given.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function bash_version ()
|
||||
{
|
||||
local major minor
|
||||
|
||||
case "$1" in
|
||||
major) echo "${BASH_VERSION/.*/}" ;;
|
||||
minor) major="${BASH_VERSION/.*/}"
|
||||
minor="${BASH_VERSION#${major}.}"
|
||||
echo "${minor%%.*}" ;;
|
||||
patchlevel) minor="${BASH_VERSION#*.*.}"
|
||||
echo "${minor%(*}" ;;
|
||||
version) minor=${BASH_VERSION/#*.*./}
|
||||
echo ${BASH_VERSION/%.$minor/} ;;
|
||||
release) echo ${BASH_VERSION%(*} ;;
|
||||
build) minor="${BASH_VERSION#*.*.*(}"
|
||||
echo ${minor%)} ;;
|
||||
*) echo "${BASH_VERSION}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
provide bash_version
|
||||
|
||||
# bash_version.bash ends here
|
||||
@@ -1,37 +0,0 @@
|
||||
# meta.bash --- meta key frobnications
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-06-28
|
||||
# Last modified: 1993-01-26
|
||||
# Public domain
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring meta:
|
||||
# Usage: meta [on|off]
|
||||
#
|
||||
# An argument of "on" will make bash use the 8th bit of any input from
|
||||
# a terminal as a "meta" bit, i.e bash will be able to use a real meta
|
||||
# key.
|
||||
#
|
||||
# An argument of "off" causes bash to disregard the 8th bit, which is
|
||||
# assumed to be used for parity instead.
|
||||
#:end docstring:
|
||||
|
||||
function meta ()
|
||||
{
|
||||
case "$1" in
|
||||
on) bind 'set input-meta On'
|
||||
bind 'set output-meta on'
|
||||
bind 'set convert-meta off' ;;
|
||||
off) bind 'set input-meta Off'
|
||||
bind 'set output-meta off'
|
||||
bind 'set convert-meta on' ;;
|
||||
*) echo "Usage: meta [on|off]" 1>&2 ; return 1 ;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
provide meta
|
||||
|
||||
# meta.bash ends here
|
||||
@@ -1,66 +0,0 @@
|
||||
# mktmp.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-02-03
|
||||
# Last modified: 1993-02-03
|
||||
# Public domain
|
||||
|
||||
# Conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring mktmp:
|
||||
# Usage: mktmp [template] {createp}
|
||||
#
|
||||
# Generate a unique filename from TEMPLATE by appending a random number to
|
||||
# the end.
|
||||
#
|
||||
# If optional 2nd arg CREATEP is non-null, file will be created atomically
|
||||
# before returning. This is to avoid the race condition that in between
|
||||
# the time that the temporary name is returned and the caller uses it,
|
||||
# someone else creates the file.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function mktmp ()
|
||||
{
|
||||
local template="$1"
|
||||
local tmpfile="${template}${RANDOM}"
|
||||
local createp="$2"
|
||||
local noclobber_status
|
||||
|
||||
case "$-" in
|
||||
*C*) noclobber_status=set;;
|
||||
esac
|
||||
|
||||
if [ "${createp:+set}" = "set" ]; then
|
||||
# Version which creates file atomically through noclobber test.
|
||||
set -o noclobber
|
||||
(> "${tmpfile}") 2> /dev/null
|
||||
while [ $? -ne 0 ] ; do
|
||||
# Detect whether file really exists or creation lost because of
|
||||
# some other permissions problem. If the latter, we don't want
|
||||
# to loop forever.
|
||||
if [ ! -e "${tmpfile}" ]; then
|
||||
# Trying to create file again creates stderr message.
|
||||
echo -n "mktmp: " 1>&2
|
||||
> "${tmpfile}"
|
||||
return 1
|
||||
fi
|
||||
tmpfile="${template}${RANDOM}"
|
||||
(> "${tmpfile}") 2> /dev/null
|
||||
done
|
||||
test "${noclobber_status}" != "set" && set +o noclobber
|
||||
else
|
||||
# Doesn't create file, so it introduces race condition for caller.
|
||||
while [ -e "${tmpfile}" ]; do
|
||||
tmpfile="${template}${RANDOM}"
|
||||
done
|
||||
fi
|
||||
|
||||
echo "${tmpfile}"
|
||||
}
|
||||
|
||||
provide mktmp
|
||||
|
||||
# mktmp.bash ends here
|
||||
@@ -1,185 +0,0 @@
|
||||
# number.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-02-22
|
||||
# Last modified: 1993-04-01
|
||||
# Public domain
|
||||
|
||||
# Conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring number:
|
||||
# Usage: number [number]
|
||||
#
|
||||
# Converts decimal integers to english notation. Spaces and commas are
|
||||
# optional. Numbers 67 digits and larger will overflow this script.
|
||||
#
|
||||
# E.g: number 99,000,000,000,000,454
|
||||
# => ninety-nine quadrillion four hundred fifty-four
|
||||
#
|
||||
#:end docstring:
|
||||
|
||||
function number ()
|
||||
{
|
||||
local result
|
||||
local val1
|
||||
local val2
|
||||
local val3
|
||||
local d1
|
||||
local d2
|
||||
local d3
|
||||
|
||||
case "$*" in
|
||||
*[!0-9,.]* )
|
||||
echo "number: invalid character in argument." 1>&2
|
||||
return 1
|
||||
;;
|
||||
*.* )
|
||||
echo "number: fractions not supported (yet)." 1>&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
result=''
|
||||
|
||||
eval set - "`echo ${1+\"$@\"} | sed -n -e '
|
||||
s/[, ]//g;s/^00*/0/g;s/\(.\)\(.\)\(.\)$/\"\1 \2 \3\"/;
|
||||
:l
|
||||
/[0-9][0-9][0-9]/{
|
||||
s/\([^\" ][^\" ]*\)\([^\" ]\)\([^\" ]\)\([^\" ]\)/\1\"\2 \3 \4\"/g;
|
||||
t l
|
||||
}
|
||||
/^[0-9][0-9][0-9]/s/\([^\" ]\)\([^\" ]\)\([^\" ]\)/\"\1 \2 \3\"/;
|
||||
/^[0-9][0-9]/s/\([^\" ]\)\([^\" ]\)/\"\1 \2\"/;
|
||||
/^[0-9]/s/^\([^\" ][^\" ]*\)/\"\1\"/g;s/\"\"/\" \"/g;p;'`"
|
||||
|
||||
while test $# -ne 0 ; do
|
||||
eval `set - $1;
|
||||
d3='' d2='' d1=''
|
||||
case $# in
|
||||
1 ) d1=$1 ;;
|
||||
2 ) d2=$1 d1=$2 ;;
|
||||
3 ) d3=$1 d2=$2 d1=$3 ;;
|
||||
esac
|
||||
echo "d3=\"${d3}\" d2=\"${d2}\" d1=\"${d1}\""`
|
||||
|
||||
val1='' val2='' val3=''
|
||||
|
||||
case "${d3}" in
|
||||
'1' ) val3='one' ;;
|
||||
'2' ) val3='two' ;;
|
||||
'3' ) val3='three' ;;
|
||||
'4' ) val3='four' ;;
|
||||
'5' ) val3='five' ;;
|
||||
'6' ) val3='six' ;;
|
||||
'7' ) val3='seven' ;;
|
||||
'8' ) val3='eight' ;;
|
||||
'9' ) val3='nine' ;;
|
||||
esac
|
||||
|
||||
case "${d2}" in
|
||||
'1' ) val2='teen' ;;
|
||||
'2' ) val2='twenty' ;;
|
||||
'3' ) val2='thirty' ;;
|
||||
'4' ) val2='forty' ;;
|
||||
'5' ) val2='fifty' ;;
|
||||
'6' ) val2='sixty' ;;
|
||||
'7' ) val2='seventy' ;;
|
||||
'8' ) val2='eighty' ;;
|
||||
'9' ) val2='ninety' ;;
|
||||
esac
|
||||
|
||||
case "${val2}" in
|
||||
'teen')
|
||||
val2=''
|
||||
case "${d1}" in
|
||||
'0') val1='ten' ;;
|
||||
'1') val1='eleven' ;;
|
||||
'2') val1='twelve' ;;
|
||||
'3') val1='thirteen' ;;
|
||||
'4') val1='fourteen' ;;
|
||||
'5') val1='fifteen' ;;
|
||||
'6') val1='sixteen' ;;
|
||||
'7') val1='seventeen' ;;
|
||||
'8') val1='eighteen' ;;
|
||||
'9') val1='nineteen' ;;
|
||||
esac
|
||||
;;
|
||||
0 ) : ;;
|
||||
* )
|
||||
if test ".${val2}" != '.' && test ".${d1}" != '.0' ; then
|
||||
val2="${val2}-"
|
||||
fi
|
||||
case "${d1}" in
|
||||
'0') val2="${val2} " ;;
|
||||
'1') val1='one' ;;
|
||||
'2') val1='two' ;;
|
||||
'3') val1='three' ;;
|
||||
'4') val1='four' ;;
|
||||
'5') val1='five' ;;
|
||||
'6') val1='six' ;;
|
||||
'7') val1='seven' ;;
|
||||
'8') val1='eight' ;;
|
||||
'9') val1='nine' ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
if test ".${val3}" != '.' ; then
|
||||
result="${result}${val3} hundred "
|
||||
fi
|
||||
|
||||
if test ".${val2}" != '.' ; then
|
||||
result="${result}${val2}"
|
||||
fi
|
||||
|
||||
if test ".${val1}" != '.' ; then
|
||||
result="${result}${val1} "
|
||||
fi
|
||||
|
||||
if test ".${d1}${d2}${d3}" != '.000' ; then
|
||||
case $# in
|
||||
0 | 1 ) ;;
|
||||
2 ) result="${result}thousand " ;;
|
||||
3 ) result="${result}million " ;;
|
||||
4 ) result="${result}billion " ;;
|
||||
5 ) result="${result}trillion " ;;
|
||||
6 ) result="${result}quadrillion " ;;
|
||||
7 ) result="${result}quintillion " ;;
|
||||
8 ) result="${result}sextillion " ;;
|
||||
9 ) result="${result}septillion " ;;
|
||||
10 ) result="${result}octillion " ;;
|
||||
11 ) result="${result}nonillion " ;;
|
||||
12 ) result="${result}decillion " ;;
|
||||
13 ) result="${result}undecillion " ;;
|
||||
14 ) result="${result}duodecillion " ;;
|
||||
15 ) result="${result}tredecillion " ;;
|
||||
16 ) result="${result}quattuordecillion " ;;
|
||||
17 ) result="${result}quindecillion " ;;
|
||||
18 ) result="${result}sexdecillion " ;;
|
||||
19 ) result="${result}septendecillion " ;;
|
||||
20 ) result="${result}octodecillion " ;;
|
||||
21 ) result="${result}novemdecillion " ;;
|
||||
22 ) result="${result}vigintillion " ;;
|
||||
* )
|
||||
echo "Error: number too large (66 digits max)." 1>&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
set - ${result}
|
||||
case "$*" in
|
||||
'') set - 'zero' ;;
|
||||
esac
|
||||
|
||||
echo ${1+"$@"}
|
||||
}
|
||||
|
||||
provide number
|
||||
|
||||
# number.bash ends here
|
||||
@@ -1,40 +0,0 @@
|
||||
# prompt.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-01-15
|
||||
# Public domain
|
||||
|
||||
# $Id: prompt.bash,v 1.2 1994/10/18 16:34:35 friedman Exp $
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring prompt:
|
||||
# Usage: prompt [chars]
|
||||
#
|
||||
# Various preformatted prompt strings selected by argument. For a
|
||||
# list of available arguments and corresponding formats, do
|
||||
# `type prompt'.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function prompt ()
|
||||
{
|
||||
case "$1" in
|
||||
d) PS1='$(dirs) \$ ' ;;
|
||||
n) PS1='\$ ' ;;
|
||||
hsw) PS1='\h[$SHLVL]: \w \$ ' ;;
|
||||
hw) PS1='\h: \w \$ ' ;;
|
||||
sh) PS1='[$SHLVL] \h\$ ' ;;
|
||||
sw) PS1='[$SHLVL] \w \$ ' ;;
|
||||
uh) PS1='\u@\h\$ ' ;;
|
||||
uhsHw) PS1='\u@\h[$SHLVL]:\#: \w \$ ' ;;
|
||||
uhsw) PS1='\u@\h[$SHLVL]: \w \$ ' ;;
|
||||
uhw) PS1='\u@\h: \w \$ ' ;;
|
||||
uw) PS1='(\u) \w \$ ' ;;
|
||||
w) PS1='\w \$ ' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
provide prompt
|
||||
|
||||
# prompt.bash ends here
|
||||
@@ -1,71 +0,0 @@
|
||||
# remap_keybindings.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-01-11
|
||||
# Last modified: 1993-02-03
|
||||
# Public domain
|
||||
|
||||
# Conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring remap_keybindings:
|
||||
# Usage: remap_keybindings old_function new_function
|
||||
#
|
||||
# Clear all readline keybindings associated with OLD_FUNCTION (a Readline
|
||||
# function) rebinding them to NEW_FUNCTION (`self-insert' by default)
|
||||
#
|
||||
# This requires bash version 1.10 or newer, since previous versions did not
|
||||
# implement the `bind' builtin.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function remap_keybindings ()
|
||||
{
|
||||
local unbind_function="$1"
|
||||
local bind_function="${2:-'self-insert'}"
|
||||
local bind_output
|
||||
local arg
|
||||
|
||||
# If they're the same thing, the work has already been done. :-)
|
||||
if [ "${unbind_function}" = "${bind_function}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
while : ; do
|
||||
bind_output="$(bind -q ${unbind_function} 2> /dev/null)"
|
||||
|
||||
case "${bind_output}" in
|
||||
"${unbind_function} can be invoked via"* ) ;;
|
||||
"" ) return 1 ;; # probably bad argument to bind
|
||||
*) return 0 ;; # unbound
|
||||
esac
|
||||
|
||||
# Format of bind_output is like:
|
||||
# 'quoted-insert can be invoked via "\C-q", "\C-v".'
|
||||
# 'self-insert can be invoked via " ", "!", """, "$", "%", ...'
|
||||
set -- ${bind_output}
|
||||
shift 5
|
||||
|
||||
for arg in "$@" ; do
|
||||
# strip off trailing `.' or `,'
|
||||
arg=${arg%.};
|
||||
arg=${arg%,};
|
||||
|
||||
case ${arg} in
|
||||
..)
|
||||
# bind -q didn't provide whole list of key bindings; jump
|
||||
# to top loop to get more
|
||||
continue 2 ;
|
||||
;;
|
||||
*)
|
||||
bind "${arg}: ${bind_function}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
provide remap_keybindings
|
||||
|
||||
# remap_keybindings.bash ends here
|
||||
@@ -1,182 +0,0 @@
|
||||
# require.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-07-08
|
||||
# Last modified: 1993-09-29
|
||||
# Public domain
|
||||
|
||||
# Commentary:
|
||||
|
||||
# These functions provide an interface based on the lisp implementation for
|
||||
# loading libraries when they are needed and eliminating redundant loading.
|
||||
# The basic idea is that each "package" (or set of routines, even if it is
|
||||
# only one function) registers itself with a symbol that marks a "feature"
|
||||
# as being "provided". If later you "require" a given feature, you save
|
||||
# yourself the trouble of explicitly loading it again.
|
||||
#
|
||||
# At the bottom of each package, put a "provide foobar", so when another
|
||||
# package has a "require foobar", it gets loaded and registered as a
|
||||
# "feature" that won't need to get loaded again. (See warning below for
|
||||
# reasons why provide should be put at the end.)
|
||||
#
|
||||
# The list of provided features are kept in the `FEATURES' variable, which
|
||||
# is not exported. Care should be taken not to munge this in the shell.
|
||||
# The search path comes from a colon-separated `FPATH' variable. It has no
|
||||
# default value and must be set by the user.
|
||||
#
|
||||
# Require uses `fpath_search', which works by scanning all of FPATH for a
|
||||
# file named the same as the required symbol but with a `.bash' appended to
|
||||
# the name. If that is found, it is loaded. If it is not, FPATH is
|
||||
# searched again for a file name the same as the feature (i.e. without any
|
||||
# extension). Fpath_search may be useful for doing library filename
|
||||
# lookups in other functions (such as a `load' or `autoload' function).
|
||||
#
|
||||
# Warning: Because require ultimately uses the builtin `source' command to
|
||||
# read in files, it has no way of undoing the commands contained in the
|
||||
# file if there is an error or if no provide statement appeared (this
|
||||
# differs from the lisp implementation of require, which normally undoes
|
||||
# most of the forms that were loaded if the require fails). Therefore, to
|
||||
# minize the number of problems caused by requiring a faulty package (such
|
||||
# as syntax errors in the source file) it is better to put the provide at
|
||||
# the end of the file, rather than at the beginning.
|
||||
|
||||
# Code:
|
||||
|
||||
# Exporting this variable would cause considerable lossage, since none of
|
||||
# the functions are exported (or at least, they're not guaranteed to be)
|
||||
export -n FEATURES
|
||||
|
||||
#:docstring :
|
||||
# Null function. Provided only so that one can put page breaks in source
|
||||
# files without any ill effects.
|
||||
#:end docstring:
|
||||
#
|
||||
# (\\014 == C-l)
|
||||
eval "function $(echo -e \\014) () { : }"
|
||||
|
||||
|
||||
#:docstring featurep:
|
||||
# Usage: featurep argument
|
||||
#
|
||||
# Returns 0 (true) if argument is a provided feature. Returns 1 (false)
|
||||
# otherwise.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function featurep ()
|
||||
{
|
||||
local feature="$1"
|
||||
|
||||
case " ${FEATURES} " in
|
||||
*" ${feature} "* ) return 0 ;;
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
#:docstring provide:
|
||||
# Usage: provide symbol ...
|
||||
#
|
||||
# Register a list of symbols as provided features
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function provide ()
|
||||
{
|
||||
local feature
|
||||
|
||||
for feature in "$@" ; do
|
||||
if ! featurep "${feature}" ; then
|
||||
FEATURES="${FEATURES} ${feature}"
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#:docstring require:
|
||||
# Usage: require feature {file}
|
||||
#
|
||||
# Load FEATURE if it is not already provided. Note that require does not
|
||||
# call `provide' to register features. The loaded file must do that
|
||||
# itself. If the package does not explicitly do a `provide' after being
|
||||
# loaded, require will complain about the feature not being provided on
|
||||
# stderr.
|
||||
#
|
||||
# Optional argument FILE means to try to load FEATURE from FILE. If no
|
||||
# file argument is given, require searches through FPATH (see fpath_search)
|
||||
# for the appropriate file.
|
||||
#
|
||||
# If the variable REQUIRE_FAILURE_FATAL is set, require will cause the
|
||||
# current shell invocation to exit, rather than merely return. This may be
|
||||
# useful for a shell script that vitally depends on a package.
|
||||
#
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function require ()
|
||||
{
|
||||
local feature="$1"
|
||||
local path="$2"
|
||||
local file
|
||||
|
||||
if ! featurep "${feature}" ; then
|
||||
file=$(fpath_search "${feature}" "${path}") && source "${file}"
|
||||
|
||||
if ! featurep "${feature}" ; then
|
||||
echo "require: ${feature}: feature was not provided." 1>&2
|
||||
if [ "${REQUIRE_FAILURE_FATAL+set}" = "set" ]; then
|
||||
exit 1
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#:docstring fpath_search:
|
||||
# Usage: fpath_search filename {path ...}
|
||||
#
|
||||
# Search $FPATH for `filename' or, if `path' (a list) is specified, search
|
||||
# those directories instead of $FPATH. First the path is searched for an
|
||||
# occurrence of `filename.bash, then a second search is made for just
|
||||
# `filename'.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function fpath_search ()
|
||||
{
|
||||
local name="$1"
|
||||
local path="$2"
|
||||
local suffix=".bash"
|
||||
local file
|
||||
|
||||
if [ -z "${path}" ]; then path="${FPATH}"; fi
|
||||
|
||||
for file in "${name}${suffix}" "${name}" ; do
|
||||
set -- $(IFS=':'
|
||||
set -- ${path}
|
||||
for p in "$@" ; do
|
||||
echo -n "${p:-.} "
|
||||
done)
|
||||
|
||||
while [ $# -ne 0 ]; do
|
||||
test -f "${1}/${file}" && { file="${1}/${file}"; break 2 }
|
||||
shift
|
||||
done
|
||||
done
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "fpath_search: ${name}: file not found in fpath" 1>&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "${file}"
|
||||
return 0
|
||||
}
|
||||
|
||||
provide require
|
||||
|
||||
# require.bash ends here
|
||||
@@ -1,140 +0,0 @@
|
||||
# send_mail.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-07-02
|
||||
# Public domain
|
||||
|
||||
# Commentary:
|
||||
|
||||
# TODO: implement Fcc headers (see emacs manual)
|
||||
|
||||
# Code:
|
||||
|
||||
#:docstring send_mail:
|
||||
# Usage: send_mail
|
||||
#
|
||||
# This function serves as a simple replacement for sendmail as a client
|
||||
# interface on those systems where it is not available. It does assume
|
||||
# that one can talk to an SMTP mailer on port 25 either on the local host
|
||||
# or on the host specified by the MAILHOST environment variable. If you
|
||||
# have access to sendmail, it's better to use 'sendmail -t' instead of this
|
||||
# script (which probably isn't as robust).
|
||||
#
|
||||
# Message is read from stdin, and headers are parsed to determine
|
||||
# recipients.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function send_mail ()
|
||||
{
|
||||
# Need gawk, since several extensions are taken advantage of (like
|
||||
# IGNORECASE for regexps).
|
||||
local awk="${GAWK_LOCATION:-gawk}"
|
||||
local DefaultFrom="${USER:-${LOGNAME}}"
|
||||
local From
|
||||
local To
|
||||
local Cc
|
||||
local Bcc
|
||||
local tmpfile="/tmp/send_mail$$"
|
||||
|
||||
while [ -e "${tmpfile}" ]; do
|
||||
tmpfile="/tmp/send_mail${RANDOM}"
|
||||
done
|
||||
|
||||
# Lines consisting only of dots need one more dot appended. SMTP
|
||||
# servers eat one of the dots (and if only 1 dot appears, it signifies
|
||||
# the end of the message).
|
||||
sed '/^\.\.*/s/^\(\.\.*\)$/\1./' > "${tmpfile}"
|
||||
|
||||
# Parse mail headers in message to extract recipients list.
|
||||
# This doesn't affect what the user sees---it's only used to generate
|
||||
# the rcpt-to lines for SMTP.
|
||||
eval $(${awk} -f - "${tmpfile}" <<- '__EOF__'
|
||||
# Try to extract email address from amidst random data
|
||||
function parse_address (data)
|
||||
{
|
||||
# From: "real name" <foobar@host>
|
||||
# From: "" <foobar@host>
|
||||
if (match(data, /^\"[^\"]*\"[ \t]*<.*>/)) {
|
||||
data_idx = match(data, /^\"[^\"]*\"[ \t]*</)
|
||||
data = substr(data, RSTART + RLENGTH);
|
||||
if (data_idx = match(data, ">.*"))
|
||||
data = substr(data, 1, RSTART - 1);
|
||||
return data
|
||||
}
|
||||
# From: real name <foobar@host>
|
||||
if (match(data, /<.*>/)) {
|
||||
data_idx = match(data, /</)
|
||||
data = substr(data, RSTART + RLENGTH);
|
||||
if (data_idx = match(data, ">"))
|
||||
data = substr(data, 1, RSTART - 1);
|
||||
return data
|
||||
}
|
||||
# From: foobar@host (real name)
|
||||
if (match(data, /\(.*\)/)) {
|
||||
data_idx = match(data, /\(/);
|
||||
data = substr(data, 1, RSTART - 1);
|
||||
return data
|
||||
}
|
||||
# (hopefully) From: foobar@host
|
||||
return data
|
||||
}
|
||||
|
||||
BEGIN { IGNORECASE = 1; }
|
||||
|
||||
# Blank line signifies end of headers, so we can stop looking.
|
||||
/^$/ { exit(0) }
|
||||
|
||||
/^from:|^to:|^cc:|^bcc:/ {
|
||||
header_idx = match($0, /^[^:]*:/)
|
||||
if (header_idx) {
|
||||
# Capitalize header name
|
||||
header_firstchar = toupper(substr($0, RSTART, 1));
|
||||
header_rest = tolower(substr($0, RSTART + 1, RLENGTH - 2));
|
||||
header = header_firstchar header_rest
|
||||
|
||||
$0 = substr($0, RSTART + RLENGTH + 1);
|
||||
addresses = ""
|
||||
# parse addresses
|
||||
while ($0) {
|
||||
# Strip leading whitespace
|
||||
if (idx = match($0, /[ \t]*/))
|
||||
$0 = substr($0, RSTART + RLENGTH);
|
||||
|
||||
# Find everything up to a nonquoted comma
|
||||
# FIXME: doesnt handle quoting yet
|
||||
if (idx = match($0, /,/)) {
|
||||
data = substr($0, 1, RSTART);
|
||||
$0 = substr($0, RSTART + 1);
|
||||
} else {
|
||||
data = $0
|
||||
$0 = ""
|
||||
}
|
||||
addresses = addresses " " parse_address(data)
|
||||
}
|
||||
|
||||
printf("%s='%s'\n", header, addresses);
|
||||
}
|
||||
}
|
||||
__EOF__)
|
||||
|
||||
# Not sure if an address is *required* after the HELO.. every sendmail
|
||||
# I tried talking to didn't seem to care. Some sendmails don't care
|
||||
# if there's a HELO at all.
|
||||
cat <<- __EOF__ | telnet ${MAILHOST:-localhost} 25 > /dev/null 2>&1
|
||||
HELO
|
||||
mail from: ${From:-${DefaultFrom}}
|
||||
$(for name in ${To} ${Cc} ${Bcc} ; do
|
||||
echo "rcpt to: ${name}"
|
||||
done)
|
||||
data
|
||||
$(cat "${tmpfile}")
|
||||
.
|
||||
quit
|
||||
__EOF__
|
||||
|
||||
rm -f "${tmpfile}"
|
||||
}
|
||||
|
||||
provide send_mail
|
||||
|
||||
# send_mail.bash ends here
|
||||
@@ -1,49 +0,0 @@
|
||||
# shcat.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-07-17
|
||||
# Last modified: 1993-09-29
|
||||
# Public domain
|
||||
|
||||
# Conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring shcat:
|
||||
# Usage: shcat {file1} {file2} {...}
|
||||
#
|
||||
# Like `cat', only this is all inline bash.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function shcat ()
|
||||
{
|
||||
local IFS=""
|
||||
local line
|
||||
local file
|
||||
local exitstat=0
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
while read -r line; do
|
||||
echo "${line}"
|
||||
done
|
||||
return 0
|
||||
else
|
||||
for file in "$@" ; do
|
||||
if [ -r "${file}" ]; then
|
||||
while read -r line; do
|
||||
echo "${line}"
|
||||
done < "${file}"
|
||||
else
|
||||
# This will cause the error to be printed on stderr
|
||||
< "${file}"
|
||||
exitstat=1
|
||||
fi
|
||||
done
|
||||
return ${exitstat}
|
||||
fi
|
||||
}
|
||||
|
||||
provide shcat
|
||||
|
||||
# shcat.bash ends here
|
||||
@@ -1,63 +0,0 @@
|
||||
# source.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-05-17
|
||||
# Last modified: 1993-09-29
|
||||
# Public domain
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring source:
|
||||
# Usage: source file ...
|
||||
#
|
||||
# Source forces file arguments to be considered in the current directory
|
||||
# only, unless there is an absolute path starting with `/'. I think it's
|
||||
# bad that the builtin "source" searches PATH, because PATH normally
|
||||
# contains directories with binary files that aren't useful for bash to
|
||||
# read and most people don't put "." first in their path.
|
||||
#
|
||||
# This "source" is capable of reading more than one file at a time. Return
|
||||
# value is number of failed source attempts.
|
||||
#:end docstring:
|
||||
|
||||
# This function is not hygienic, but there's not much we can do about
|
||||
# variable name conflicts here.
|
||||
|
||||
###;;;autoload
|
||||
function source ()
|
||||
{
|
||||
local -i _source_failure_count=0
|
||||
local _source_file
|
||||
|
||||
for _source_file ; do
|
||||
# Check first part of each filename. If it's not `/', `./', or
|
||||
# `../' then prepend "./" to the path to force the builtin `source'
|
||||
# not to go searching through PATH to find the file.
|
||||
case "${_source_file}" in
|
||||
/*|./*|../* ) ;;
|
||||
* ) _source_file="./${_source_file}" ;;
|
||||
esac
|
||||
|
||||
builtin source "${_source_file}" ||
|
||||
_source_failure_count="_source_failure_count + 1"
|
||||
|
||||
done
|
||||
|
||||
return ${_source_failure_count}
|
||||
}
|
||||
|
||||
#:docstring .:
|
||||
# See "source"
|
||||
#:end docstring:
|
||||
|
||||
# So that `.' will call function definition of `source' instead of builtin
|
||||
|
||||
###;;;autoload
|
||||
function . ()
|
||||
{
|
||||
source "$@"
|
||||
}
|
||||
|
||||
provide source
|
||||
|
||||
# source.bash ends here
|
||||
@@ -1,226 +0,0 @@
|
||||
# string.bash --- bash emulation of string(3) library routines
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-07-01
|
||||
# Last modified: 1993-09-29
|
||||
# Public domain
|
||||
|
||||
# Conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring strcat:
|
||||
# Usage: strcat s1 s2
|
||||
#
|
||||
# Strcat appends the value of variable s2 to variable s1.
|
||||
#
|
||||
# Example:
|
||||
# a="foo"
|
||||
# b="bar"
|
||||
# strcat a b
|
||||
# echo $a
|
||||
# => foobar
|
||||
#
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strcat ()
|
||||
{
|
||||
local s1_val s2_val
|
||||
|
||||
s1_val=${!1} # indirect variable expansion
|
||||
s2_val=${!2}
|
||||
eval "$1"=\'"${s1_val}${s2_val}"\'
|
||||
}
|
||||
|
||||
#:docstring strncat:
|
||||
# Usage: strncat s1 s2 $n
|
||||
#
|
||||
# Line strcat, but strncat appends a maximum of n characters from the value
|
||||
# of variable s2. It copies fewer if the value of variabl s2 is shorter
|
||||
# than n characters. Echoes result on stdout.
|
||||
#
|
||||
# Example:
|
||||
# a=foo
|
||||
# b=barbaz
|
||||
# strncat a b 3
|
||||
# echo $a
|
||||
# => foobar
|
||||
#
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strncat ()
|
||||
{
|
||||
local s1="$1"
|
||||
local s2="$2"
|
||||
local -i n="$3"
|
||||
local s1_val s2_val
|
||||
|
||||
s1_val=${!s1} # indirect variable expansion
|
||||
s2_val=${!s2}
|
||||
|
||||
if [ ${#s2_val} -gt ${n} ]; then
|
||||
s2_val=${s2_val:0:$n} # substring extraction
|
||||
fi
|
||||
|
||||
eval "$s1"=\'"${s1_val}${s2_val}"\'
|
||||
}
|
||||
|
||||
#:docstring strcmp:
|
||||
# Usage: strcmp $s1 $s2
|
||||
#
|
||||
# Strcmp compares its arguments and returns an integer less than, equal to,
|
||||
# or greater than zero, depending on whether string s1 is lexicographically
|
||||
# less than, equal to, or greater than string s2.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strcmp ()
|
||||
{
|
||||
[ "$1" = "$2" ] && return 0
|
||||
|
||||
[ "${1}" '<' "${2}" ] > /dev/null && return -1
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#:docstring strncmp:
|
||||
# Usage: strncmp $s1 $s2 $n
|
||||
#
|
||||
# Like strcmp, but makes the comparison by examining a maximum of n
|
||||
# characters (n less than or equal to zero yields equality).
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strncmp ()
|
||||
{
|
||||
if [ -z "${3}" ] || [ "${3}" -le "0" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ ${3} -ge ${#1} ] && [ ${3} -ge ${#2} ]; then
|
||||
strcmp "$1" "$2"
|
||||
return $?
|
||||
else
|
||||
s1=${1:0:$3}
|
||||
s2=${2:0:$3}
|
||||
strcmp $s1 $s2
|
||||
return $?
|
||||
fi
|
||||
}
|
||||
|
||||
#:docstring strlen:
|
||||
# Usage: strlen s
|
||||
#
|
||||
# Strlen returns the number of characters in string literal s.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strlen ()
|
||||
{
|
||||
eval echo "\${#${1}}"
|
||||
}
|
||||
|
||||
#:docstring strspn:
|
||||
# Usage: strspn $s1 $s2
|
||||
#
|
||||
# Strspn returns the length of the maximum initial segment of string s1,
|
||||
# which consists entirely of characters from string s2.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strspn ()
|
||||
{
|
||||
# Unsetting IFS allows whitespace to be handled as normal chars.
|
||||
local IFS=
|
||||
local result="${1%%[!${2}]*}"
|
||||
|
||||
echo ${#result}
|
||||
}
|
||||
|
||||
#:docstring strcspn:
|
||||
# Usage: strcspn $s1 $s2
|
||||
#
|
||||
# Strcspn returns the length of the maximum initial segment of string s1,
|
||||
# which consists entirely of characters not from string s2.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strcspn ()
|
||||
{
|
||||
# Unsetting IFS allows whitspace to be handled as normal chars.
|
||||
local IFS=
|
||||
local result="${1%%[${2}]*}"
|
||||
|
||||
echo ${#result}
|
||||
}
|
||||
|
||||
#:docstring strstr:
|
||||
# Usage: strstr s1 s2
|
||||
#
|
||||
# Strstr echoes a substring starting at the first occurrence of string s2 in
|
||||
# string s1, or nothing if s2 does not occur in the string. If s2 points to
|
||||
# a string of zero length, strstr echoes s1.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strstr ()
|
||||
{
|
||||
# if s2 points to a string of zero length, strstr echoes s1
|
||||
[ ${#2} -eq 0 ] && { echo "$1" ; return 0; }
|
||||
|
||||
# strstr echoes nothing if s2 does not occur in s1
|
||||
case "$1" in
|
||||
*$2*) ;;
|
||||
*) return 1;;
|
||||
esac
|
||||
|
||||
# use the pattern matching code to strip off the match and everything
|
||||
# following it
|
||||
first=${1/$2*/}
|
||||
|
||||
# then strip off the first unmatched portion of the string
|
||||
echo "${1##$first}"
|
||||
}
|
||||
|
||||
#:docstring strtok:
|
||||
# Usage: strtok s1 s2
|
||||
#
|
||||
# Strtok considers the string s1 to consist of a sequence of zero or more
|
||||
# text tokens separated by spans of one or more characters from the
|
||||
# separator string s2. The first call (with a non-empty string s1
|
||||
# specified) echoes a string consisting of the first token on stdout. The
|
||||
# function keeps track of its position in the string s1 between separate
|
||||
# calls, so that subsequent calls made with the first argument an empty
|
||||
# string will work through the string immediately following that token. In
|
||||
# this way subsequent calls will work through the string s1 until no tokens
|
||||
# remain. The separator string s2 may be different from call to call.
|
||||
# When no token remains in s1, an empty value is echoed on stdout.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strtok ()
|
||||
{
|
||||
:
|
||||
}
|
||||
|
||||
#:docstring strtrunc:
|
||||
# Usage: strtrunc $n $s1 {$s2} {$...}
|
||||
#
|
||||
# Used by many functions like strncmp to truncate arguments for comparison.
|
||||
# Echoes the first n characters of each string s1 s2 ... on stdout.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function strtrunc ()
|
||||
{
|
||||
n=$1 ; shift
|
||||
for z; do
|
||||
echo "${z:0:$n}"
|
||||
done
|
||||
}
|
||||
|
||||
provide string
|
||||
|
||||
# string.bash ends here
|
||||
@@ -1,64 +0,0 @@
|
||||
# stty.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-01-11
|
||||
# Last modified: 1993-09-29
|
||||
# Public domain
|
||||
|
||||
# Conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
require remap_keybindings
|
||||
|
||||
#:docstring stty:
|
||||
# Track changes to certain keybindings with stty, and make those changes
|
||||
# reflect in bash's readline bindings as well.
|
||||
#
|
||||
# This requires bash version 1.10 or newer, since previous versions did not
|
||||
# implement the `bind' builtin.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function stty ()
|
||||
{
|
||||
local erase="backward-delete-char"
|
||||
local kill="unix-line-discard"
|
||||
local werase="backward-kill-word"
|
||||
local lnext="quoted-insert"
|
||||
local readline_function=""
|
||||
local key=""
|
||||
local stty_command=""
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
erase | kill | werase | lnext )
|
||||
key=$(echo "${2}" | cat -v | sed 's/\^/\\C-/')
|
||||
readline_function=$(eval echo \$${1})
|
||||
|
||||
# Get rid of any current bindings; the whole point of this
|
||||
# function is to make the distinction between readline
|
||||
# bindings and particular cbreak characters transparent; old
|
||||
# readline keybindings shouldn't hang around.
|
||||
# could use bind -r here instead of binding to self-insert
|
||||
remap_keybindings "${readline_function}" "self-insert"
|
||||
|
||||
# Bind new key to appropriate readline function
|
||||
bind "\"${key}\": ${readline_function}"
|
||||
|
||||
stty_command="${stty_command} ${1} ${2}"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
stty_command="${stty_command} ${1}"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
command stty ${stty_command}
|
||||
}
|
||||
|
||||
provide stty
|
||||
|
||||
# stty.bash ends here
|
||||
@@ -1,78 +0,0 @@
|
||||
# y_or_n_p.bash
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1992-06-18
|
||||
# Last modified: 1993-03-01
|
||||
# Public domain
|
||||
|
||||
# Conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# Commentary:
|
||||
# Code:
|
||||
|
||||
#:docstring y_or_n_p:
|
||||
# Usage: y_or_n_p QUERY
|
||||
#
|
||||
# Print QUERY on stderr, then read stdin for a y-or-n response. Actually,
|
||||
# user may type anything they like, but first character must be a `y', `n',
|
||||
# `q', or `!', otherwise the question is repeated until such an answer is
|
||||
# obtained.
|
||||
#
|
||||
# If user typed `y', y_or_n_p returns 0.
|
||||
#
|
||||
# If user typed `n', y_or_n_p returns 1.
|
||||
#
|
||||
# If user typed `!', y_or_n_p returns 2. This is an indication to the
|
||||
# caller that no more queries should be made. Assume `y' for all the rest.
|
||||
#
|
||||
# If user typed `q', y_or_n_p returns 3. This is an indication to the
|
||||
# caller that no more queries should be made. Assume `n' for all the rest.
|
||||
#
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function y_or_n_p ()
|
||||
{
|
||||
local ans
|
||||
|
||||
[ ! -t 0 ] && return 1
|
||||
|
||||
while read -p "$*" -e ans ; do
|
||||
case "${ans}" in
|
||||
y* | Y* ) return 0 ;;
|
||||
n* | N* ) return 1 ;;
|
||||
\! ) return 2 ;;
|
||||
q* | Q* ) return 3 ;;
|
||||
*) echo "Please answer one of \`y', \`n', \`q', or \`"\!"'" 1>&2 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
#:docstring yes_or_no_p:
|
||||
# Usage: yes_or_no_p QUERY
|
||||
#
|
||||
# Like y_or_n_p, but require a full `yes', `no', `yes!', or `quit' response.
|
||||
#:end docstring:
|
||||
|
||||
###;;;autoload
|
||||
function yes_or_no_p ()
|
||||
{
|
||||
local ans
|
||||
|
||||
[ ! -t 0 ] && return 3
|
||||
|
||||
while read -p "$*" -e ans; do
|
||||
ans="$(echo ${ans} | tr '[A-Z]' '[a-z]')"
|
||||
|
||||
case "${ans}" in
|
||||
yes ) return 0 ;;
|
||||
no ) return 1 ;;
|
||||
yes\! ) return 2 ;;
|
||||
quit ) return 3 ;;
|
||||
*) echo "Please answer \`yes', \`no', \`yes"\!"', or \`quit'" 1>&2 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
provide y_or_n_p
|
||||
|
||||
# y_or_n_p.bash ends here
|
||||
@@ -1,59 +0,0 @@
|
||||
From spcecdt@armory.com Wed May 10 10:21:11 1995
|
||||
Flags: 10
|
||||
Return-Path: spcecdt@armory.com
|
||||
Received: from po.cwru.edu (root@po.CWRU.Edu [129.22.4.2]) by odin.INS.CWRU.Edu with ESMTP (8.6.10+cwru/CWRU-2.1-ins)
|
||||
id KAA22876; Wed, 10 May 1995 10:21:10 -0400 (from spcecdt@armory.com for <chet@odin.INS.CWRU.Edu>)
|
||||
Received: from deepthought.armory.com (mmdf@deepthought.armory.com [192.122.209.42]) by po.cwru.edu with SMTP (8.6.10+cwru/CWRU-2.3)
|
||||
id BAA16354; Wed, 10 May 1995 01:33:22 -0400 (from spcecdt@armory.com for <chet@po.cwru.edu>)
|
||||
From: John DuBois <spcecdt@armory.com>
|
||||
Date: Tue, 9 May 1995 22:33:12 -0700
|
||||
In-Reply-To: Chet Ramey <chet@odin.ins.cwru.edu>
|
||||
"ksh scripts" (May 9, 1:36pm)
|
||||
X-Www: http://www.armory.com/~spcecdt/
|
||||
X-Mailer: Mail User's Shell (7.2.5 10/14/92)
|
||||
To: chet@po.cwru.edu
|
||||
Subject: Re: ksh scripts
|
||||
Message-ID: <9505092233.aa13001@deepthought.armory.com>
|
||||
|
||||
Sure. The canonical versions are available on ftp.armory.com; you might
|
||||
want to pick up the latest versions before modifying them.
|
||||
|
||||
John
|
||||
|
||||
On May 9, 1:36pm, Chet Ramey wrote:
|
||||
} Subject: ksh scripts
|
||||
} From odin.ins.cwru.edu!chet Tue May 9 10:39:51 1995
|
||||
} Received: from odin.INS.CWRU.Edu by deepthought.armory.com id aa22336;
|
||||
} 9 May 95 10:39 PDT
|
||||
} Received: (chet@localhost) by odin.INS.CWRU.Edu (8.6.10+cwru/CWRU-2.1-ins)
|
||||
} id NAA20487; Tue, 9 May 1995 13:39:24 -0400 (from chet)
|
||||
} Date: Tue, 9 May 1995 13:36:54 -0400
|
||||
} From: Chet Ramey <chet@odin.ins.cwru.edu>
|
||||
} To: john@armory.com
|
||||
} Subject: ksh scripts
|
||||
} Cc: chet@odin.ins.cwru.edu
|
||||
} Reply-To: chet@po.cwru.edu
|
||||
} Message-ID: <9505091736.AA20411.SM@odin.INS.CWRU.Edu>
|
||||
} Read-Receipt-To: chet@po.CWRU.Edu
|
||||
} MIME-Version: 1.0
|
||||
} Content-Type: text/plain; charset=us-ascii
|
||||
} Status: OR
|
||||
}
|
||||
} Hi. I'm the maintainer of bash (the GNU `Bourne Again shell') for
|
||||
} the FSF.
|
||||
}
|
||||
} I picked up a tar file of ksh scripts you wrote from an anon FTP site
|
||||
} a while back. I'd like your permission to include modified versions
|
||||
} of some of them in the next major bash distribution (with proper credit
|
||||
} given, of course). Is it OK if I do that?
|
||||
}
|
||||
} Chet Ramey
|
||||
}
|
||||
} --
|
||||
} ``The lyf so short, the craft so long to lerne.'' - Chaucer
|
||||
}
|
||||
} Chet Ramey, Case Western Reserve University Internet: chet@po.CWRU.Edu
|
||||
}-- End of excerpt from Chet Ramey
|
||||
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
This collection of scripts was originally written for ksh-88 by
|
||||
John DuBois <spcecdt@armory.com>. The conversion to bash v2
|
||||
syntax was done by Chet Ramey.
|
||||
|
||||
These scripts are as-is; there is no copyright associated with
|
||||
any of them. They exist simply as examples of bash scripting.
|
||||
|
||||
Here's a description of what's in this directory:
|
||||
|
||||
arc2tarz Convert an "arc" archive to a compressed tar archive.
|
||||
cal2day.bash Convert a day number to a name.
|
||||
corename Tell what produced a core file.
|
||||
fman Fast man(1) replacement.
|
||||
frcp Copy files using ftp(1) but with rcp-type command line syntax.
|
||||
lowercase Change filenames to lower case.
|
||||
ncp A nicer front end for cp(1) (has -i, etc.).
|
||||
newext Change the extension of a group of files.
|
||||
nmv A nicer front end for mv(1) (has -i, etc.).
|
||||
pages Print specified pages from files.
|
||||
PERMISSION Permissions to use the scripts in this directory.
|
||||
pf A pager front end that handles compressed files.
|
||||
README README
|
||||
ren Rename files by changing parts of filenames that match a pattern.
|
||||
rename Change the names of files that match a pattern.
|
||||
repeat Execute a command multiple times.
|
||||
untar Unarchive a (possibly compressed) tarfile into a directory.
|
||||
uudec Carefully uudecode(1) multiple files.
|
||||
uuenc uuencode(1) multiple files.
|
||||
vtree Print a visual display of a directory tree.
|
||||
where Show where commands that match a pattern are.
|
||||
|
||||
The following scripts were written or converted by Chet Ramey:
|
||||
|
||||
bashrand Random number generator with upper and lower bounds and optional seed.
|
||||
cdhist.bash cd replacement with a directory stack added.
|
||||
pmtop Poor man's 'top(1)' for SunOS 4.x and BSD/OS.
|
||||
shprof Line profiler for bash scripts.
|
||||
@@ -1,85 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# arc2tarz: convert arced file to tarred, compressed form.
|
||||
# @(#) arc2tarz.ksh 1.0 92/02/16
|
||||
# 91/03/28 john h. dubois iii (john@armory.com)
|
||||
# 92/02/16 added -h option for help
|
||||
#
|
||||
# conversion to bash v2 syntax by Chet Ramey
|
||||
|
||||
unset ENV
|
||||
Usage="Usage: $0 arcfile [-hcg] [ tarzfile ]"
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$Usage
|
||||
arcfile is the name of an arc file to convert to tarred, compressed form.
|
||||
The file must have a .arc extension, but only the base name needs to be
|
||||
given. If no output file name is given, it will be created in the current
|
||||
directory with the name being the arcfile basename followed by .tar.EXT.
|
||||
If the -c option is given, compress will be used, and EXT will be Z.
|
||||
The default (also available with -g) is to use gzip, in which case EXT
|
||||
is gz. If the basename is too long the extension may be truncated. All
|
||||
uppercase letters in the names of files in the archive are moved to lowercase."
|
||||
}
|
||||
|
||||
compress=gzip
|
||||
ext=gz
|
||||
|
||||
while getopts "hcg" opt; do
|
||||
case "$opt" in
|
||||
h) phelp; exit 0;;
|
||||
c) compress=compress; ext=Z;;
|
||||
g) compress=gzip ; ext=gz ;;
|
||||
*) echo "$Usage" 1>&2 ; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# = 0 ]; then
|
||||
phelp
|
||||
exit 0
|
||||
fi
|
||||
|
||||
[ -z "$TMP" ] && tmpdir=/tmp/arc2tarz.$$ || tmpdir=$TMP/arc2tarz.$$
|
||||
|
||||
case "$1" in
|
||||
*.arc) arcfile=$1 ;;
|
||||
*) arcfile=$1.arc ;;
|
||||
esac
|
||||
|
||||
if [ ! -f $arcfile ] || [ ! -r $arcfile ]; then
|
||||
echo "Could not open arc file \"$arcfile\"."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$arcfile" in
|
||||
/*) ;;
|
||||
*) arcfile=$PWD/$arcfile ;;
|
||||
esac
|
||||
|
||||
basename=${arcfile%.arc}
|
||||
basename=${basename##*/}
|
||||
[ $# -lt 2 ] && tarzname=$PWD/$basename.tar.$ext || tarzname=$2
|
||||
|
||||
trap 'rm -rf $tmpdir $tarzname' 1 2 3 6 15
|
||||
|
||||
mkdir $tmpdir
|
||||
cd $tmpdir
|
||||
echo "unarcing files..."
|
||||
arc -ie $arcfile
|
||||
|
||||
# lowercase
|
||||
for f in *; do
|
||||
new=$(echo $f | tr A-Z a-z)
|
||||
if [ "$f" != "$new" ]; then
|
||||
mv $f $new
|
||||
fi
|
||||
done
|
||||
|
||||
echo "tarring/compressing files..."
|
||||
tar cf - * | $compress > $tarzname
|
||||
cd -
|
||||
rm -rf $tmpdir
|
||||
@@ -1,76 +0,0 @@
|
||||
#! /bin/bash
|
||||
# bashrand - generate a random number in a specified range with an
|
||||
# optionally specified ``seed'' value.
|
||||
#
|
||||
# Original Author: Peter Turnbull, May 1993
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "$PROG: usage: $PROG [-s seed] lower-limit upper-limit" >&2
|
||||
}
|
||||
|
||||
PROG=${0##*/}
|
||||
|
||||
SEED=$$ # Initialize random-number seed value with PID
|
||||
|
||||
while getopts s: opt
|
||||
do
|
||||
case "$opt" in
|
||||
s) SEED=$OPTARG ;;
|
||||
*) usage ; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
# Process command-line arguments:
|
||||
case $# in
|
||||
2) Lower=$1; Upper=$2 ;;
|
||||
*) usage ; exit 2 ;;
|
||||
esac
|
||||
|
||||
# Check that specified values are integers:
|
||||
expr "$Lower" + 0 >/dev/null 2>&1 || {
|
||||
echo "$PROG: lower ($Lower) not an integer" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
expr "$Upper" + 0 >/dev/null 2>&1 || {
|
||||
echo "$PROG: upper ($Upper) not an integer" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
expr "$SEED" + 0 >/dev/null 2>&1 || {
|
||||
echo "$PROG: seed ($SEED) not an integer" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check that values are in the correct range:
|
||||
(( $Lower < 0 )) || [ `expr "$Lower" : '.*'` -gt 5 ] && {
|
||||
echo "$PROG: Lower limit ($Lower) out of range" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
(( $Upper > 32767 )) || [ `expr "$Upper" : '.*'` -gt 5 ] && {
|
||||
echo "$PROG: Upper limit ($Upper) out of range" >&2;
|
||||
exit 1
|
||||
}
|
||||
|
||||
(( $SEED < 0 )) || (( $SEED > 32767 )) || [ `expr "$SEED" : '.*'` -gt 5 ] && {
|
||||
echo "$PROG: Seed value ($SEED) out of range (0 to 32767)" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
(( $Upper <= $Lower )) && {
|
||||
echo "$PROG: upper ($Upper) <= lower value ($Lower)" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Seed the random-number generator:
|
||||
RANDOM=$SEED
|
||||
|
||||
# Compute value, scaled within range:
|
||||
let rand="$RANDOM % ($Upper - $Lower + 1) + $Lower"
|
||||
|
||||
# Report result:
|
||||
echo $rand
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/bin/bash
|
||||
# cal2day - "parse" appropriate calendar output to match date number
|
||||
# with day name.
|
||||
#
|
||||
# usage: cal2day month day [year]
|
||||
#
|
||||
# ORIGINAL *TAG:33239 3:Dec 9 1997:0755:sh.d/cal2day:
|
||||
#
|
||||
# Obtained from usenet
|
||||
#
|
||||
# Converted to bash v2 syntax by Chet Ramey <chet@po.cwru.edu>
|
||||
|
||||
#1 PARSE OPTIONS
|
||||
while getopts :dls _inst
|
||||
do case $_inst in
|
||||
(d) format='%1d%.0s\n' ;; # 0, 1, ..., 7
|
||||
(l) format='%0.s%-s\n' ;; # Sunday, Monday, ..., Saturday
|
||||
(s) format='%0.s%-.3s\n' ;; # Sun, Mon, ..., Sat
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#2 PARAMETER VALUES
|
||||
((!$#)) && set -- $(date '+%m %d')
|
||||
: ${format:='%0.s%-.3s\n'}
|
||||
: ${1:?missing month parameter [1-12]}
|
||||
: ${2:?missing day parameter [1-31]}
|
||||
|
||||
#3 CALCULATE DAY-OF-WEEK FROM DATE
|
||||
cal $1 ${3:-$(date +%Y)} | gawk -FX '
|
||||
BEGIN { day="Sunday Monday Tuesday WednesdayThursday Friday Saturday"
|
||||
sub(/^0/, "", daynum)
|
||||
dayre="(^| )" daynum "( |$)"
|
||||
}
|
||||
#NR==2 { print length($0) }
|
||||
NR==1 || NR==2 \
|
||||
{ next }
|
||||
dayre { if (match($0, dayre))
|
||||
{ #print RSTART, RLENGTH, substr($0, RSTART, RLENGTH)
|
||||
if (daynum<=9 || RSTART==1) RSTART-=1
|
||||
exit
|
||||
}
|
||||
}
|
||||
END { # 20/21 char width assumed
|
||||
printf format, RSTART/3, substr(day, RSTART*3+1, 9)
|
||||
}
|
||||
' daynum=$2 format=$format -
|
||||
|
||||
exit 0
|
||||
@@ -1,176 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# cdhist - cd replacement with a directory stack like pushd/popd
|
||||
#
|
||||
# usage: cd [-l] [-n] [-] [dir]
|
||||
#
|
||||
# options:
|
||||
# -l print the cd directory stack, one entry per line
|
||||
# - equivalent to $OLDPWD
|
||||
# -n cd to nth directory in cd directory stack
|
||||
# -s cd to first directory in stack matching (substring) `s'
|
||||
#
|
||||
# arguments:
|
||||
# dir cd to dir and push dir onto the cd directory stack
|
||||
#
|
||||
# If the new directory is a directory in the stack and the options selected
|
||||
# it (-n, -s), the new working directory is printed
|
||||
#
|
||||
# If the variable CDHISTFILE is set, the cd directory stack is loaded from
|
||||
# and written to $CDHISTFILE every time `cd' is executed.
|
||||
#
|
||||
# Note: I got this off the net somewhere; I don't know the original author
|
||||
#
|
||||
# Chet Ramey
|
||||
# chet@po.cwru.edu
|
||||
|
||||
_cd_print()
|
||||
{
|
||||
echo -e "$@"
|
||||
}
|
||||
|
||||
cd()
|
||||
{
|
||||
typeset -i cdlen i
|
||||
typeset t
|
||||
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
set -- $HOME
|
||||
fi
|
||||
|
||||
if [ "$CDHISTFILE" ] && [ -r "$CDHISTFILE" ] # if directory history exists
|
||||
then
|
||||
typeset CDHIST
|
||||
i=-1
|
||||
while read -r t # read directory history file
|
||||
do
|
||||
CDHIST[i=i+1]=$t
|
||||
done <$CDHISTFILE
|
||||
fi
|
||||
|
||||
if [ "${CDHIST[0]}" != "$PWD" ] && [ -n "$PWD" ]
|
||||
then
|
||||
_cdins # insert $PWD into cd history
|
||||
fi
|
||||
|
||||
cdlen=${#CDHIST[*]} # number of elements in history
|
||||
|
||||
case "$@" in
|
||||
-) # cd to new dir
|
||||
if [ "$OLDPWD" = "" ] && ((cdlen>1))
|
||||
then
|
||||
'_cdprint' ${CDHIST[1]}
|
||||
builtin cd ${CDHIST[1]}
|
||||
pwd
|
||||
else
|
||||
builtin cd "$@"
|
||||
# pwd
|
||||
fi
|
||||
;;
|
||||
-l) # _cdprint directory list
|
||||
((i=cdlen))
|
||||
while (((i=i-1)>=0))
|
||||
do
|
||||
num=$i
|
||||
'_cdprint' "$num ${CDHIST[i]}"
|
||||
done
|
||||
return
|
||||
;;
|
||||
-[0-9]|-[0-9][0-9]) # cd to dir in list
|
||||
if (((i=${1#-})<cdlen))
|
||||
then
|
||||
'_cdprint' ${CDHIST[i]}
|
||||
builtin cd ${CDHIST[i]}
|
||||
pwd
|
||||
else
|
||||
builtin cd $@
|
||||
# pwd
|
||||
fi
|
||||
;;
|
||||
-*) # cd to matched dir in list
|
||||
t=${1#-}
|
||||
i=1
|
||||
while ((i<cdlen))
|
||||
do
|
||||
case ${CDHIST[i]} in
|
||||
*$t*)
|
||||
'_cdprint' ${CDHIST[i]}
|
||||
builtin cd ${CDHIST[i]}
|
||||
pwd
|
||||
break
|
||||
;;
|
||||
esac
|
||||
((i=i+1))
|
||||
done
|
||||
if ((i>=cdlen))
|
||||
then
|
||||
builtin cd $@
|
||||
# pwd
|
||||
fi
|
||||
;;
|
||||
*) # cd to new dir
|
||||
builtin cd $@
|
||||
# pwd
|
||||
;;
|
||||
esac
|
||||
|
||||
_cdins # insert $PWD into cd history
|
||||
|
||||
if [ "$CDHISTFILE" ]
|
||||
then
|
||||
cdlen=${#CDHIST[*]} # number of elements in history
|
||||
|
||||
i=0
|
||||
while ((i<cdlen))
|
||||
do
|
||||
echo ${CDHIST[i]} # update directory history
|
||||
((i=i+1))
|
||||
done >$CDHISTFILE
|
||||
fi
|
||||
}
|
||||
|
||||
_cdins() # insert $PWD into cd history
|
||||
{ # meant to be called only by cd
|
||||
typeset -i i
|
||||
|
||||
i=0
|
||||
|
||||
while (( i < ${#CDHIST[*]} )) # see if dir is already in list
|
||||
do
|
||||
if [ "${CDHIST[$i]}" = "$PWD" ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
((i=i+1))
|
||||
done
|
||||
|
||||
if (( i>22 )) # limit max size of list
|
||||
then
|
||||
i=22
|
||||
fi
|
||||
|
||||
while (((i=i-1)>=0)) # bump old dirs in list
|
||||
do
|
||||
CDHIST[i+1]=${CDHIST[i]}
|
||||
done
|
||||
|
||||
CDHIST[0]=$PWD # insert new directory in list
|
||||
}
|
||||
|
||||
# examples
|
||||
shopt -s expand_aliases
|
||||
|
||||
# go to known place before doing anything
|
||||
cd /
|
||||
|
||||
echo CDHIST: "${CDHIST[@]}"
|
||||
for dir in /tmp /bin - -2 -l
|
||||
do
|
||||
cd $dir
|
||||
echo CDHIST: "${CDHIST[@]}"
|
||||
echo PWD: $PWD
|
||||
|
||||
done
|
||||
|
||||
exit 0
|
||||
@@ -1,43 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# @(#) corename.ksh 1.0 93/04/01
|
||||
# 92/11/11 john h. dubois iii (john@armory.com)
|
||||
# 92/02/16 Added help option.
|
||||
# 92/02/22 Added cd to origdir to fix prob w/multiple relative paths.
|
||||
# 93/04/01 Added check for whether file exists.
|
||||
#
|
||||
# conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
# inspired by belal's equivalent utility
|
||||
|
||||
if [ "$1" = -h ]; then
|
||||
echo \
|
||||
"$0: print the names of executables that dumped core.
|
||||
Usage: $0 [corename ...]
|
||||
If no corename is given, \"core\" is assumed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
[ $# = 0 ] && set core
|
||||
origdir=$PWD
|
||||
for i; do
|
||||
cd $origdir
|
||||
file=${i##*/}
|
||||
dir=${i%$file}
|
||||
[ -z "$dir" ] && dir=$origdir/
|
||||
if [ ! -f $dir$file ]; then
|
||||
echo "$dir$file: No such file."
|
||||
continue
|
||||
fi
|
||||
if [ ! -r $dir$file ]; then
|
||||
echo "$dir$file: Cannot open."
|
||||
continue
|
||||
fi
|
||||
cd $dir
|
||||
|
||||
# the adb output syntax is highly variable. this works on SunOS 4.x
|
||||
set -- $(adb $file < /dev/null 2>&1 | sed 1q)
|
||||
name=${7#??}
|
||||
echo "$i: ${name%??}"
|
||||
done
|
||||
@@ -1,281 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# fman: new man program
|
||||
# @(#) fman.ksh 1.5 94/04/16
|
||||
# 91/07/03 john h. dubois iii (john@armory.com)
|
||||
# 91/07/11 made it unpack man pages if neccessary
|
||||
# 91/07/16 fixed test for whether man file pattern was expanded
|
||||
# 92/01/21 made it read /etc/default/man to get section order,
|
||||
# and only display the first section found.
|
||||
# 92/02/06 changed name to fman
|
||||
# 92/02/07 fixed bug in notfound
|
||||
# 92/02/13 incorporated changes from DOS version
|
||||
# 92/03/11 changed to use MANPATH from environment if set,
|
||||
# and search all directories given in MANPATH
|
||||
# 92/03/15 exec pager or man w/o forking
|
||||
# 92/05/31 try using index if one exists
|
||||
# 92/10/01 Added "See also <other sections>"
|
||||
# 92/10/18 If PAGER is less, search for name of man page to make it easier
|
||||
# to find information in man pages for multiple items
|
||||
# 92/11/11 Make it work for compressed files not listed in index;
|
||||
# deal with man pages listed in index that don't exist.
|
||||
# 93/03/30 Fixed bug in MANPATH processing
|
||||
# 93/06/17 Include paths in "See also:" message if they would be needed
|
||||
# to get to a man page. Allow MANPATH spec on command line.
|
||||
# 93/07/09 Added -h and -e options.
|
||||
# 94/04/16 Added x option.
|
||||
#
|
||||
# conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
istrue()
|
||||
{
|
||||
test 0 -ne "$1"
|
||||
}
|
||||
|
||||
isfalse()
|
||||
{
|
||||
test 0 -eq "$1"
|
||||
}
|
||||
|
||||
# Finds all sections that man page $1 is in and puts them in the the
|
||||
# global array Sections[].
|
||||
# The filename of each page is put in FileNames[] with the same index.
|
||||
# Global vars used:
|
||||
# patharr[] MANPATH directories.
|
||||
|
||||
FindSectionsInIndex ()
|
||||
{
|
||||
typeset index indexes section mpath page=$1
|
||||
typeset -i i=0 NIndex=0
|
||||
|
||||
for mpath in "${patharr[@]}"; do
|
||||
if [ -r $mpath/index ]; then
|
||||
indexes="$indexes $mpath/index"
|
||||
let NIndex+=1
|
||||
fi
|
||||
done
|
||||
[ -z "$indexes" ] && return
|
||||
# Make grep give filename
|
||||
[ NIndex -lt 2 ] && indexes="$indexes /dev/null"
|
||||
# set positional parameters to
|
||||
# indexfile:searchname pagename section ...
|
||||
# e.g.
|
||||
# /usr/man/index:FP_OFF Routines DOS
|
||||
set -- `grep "^$page[ ]" $indexes`
|
||||
while [ $# -gt 2 ]; do
|
||||
FileNames[i]=${1%%index*}cat$3/$2.$3
|
||||
Sections[i]=$3
|
||||
shift 3
|
||||
let i+=1
|
||||
done
|
||||
}
|
||||
|
||||
# Finds all sections that man page $1 is in by searching each man directory
|
||||
# in the order given in patharr[],
|
||||
# and puts them in the the global array Sections[].
|
||||
# The filename of each page is put in FileNames[] with the same index.
|
||||
# Global vars used:
|
||||
# patharr[] MANPATH directories.
|
||||
FindSectionsInDirs ()
|
||||
{
|
||||
local page=$1 mpath AllPaths Path
|
||||
typeset -i i
|
||||
|
||||
for mpath in "${patharr[@]}"; do
|
||||
AllPaths="$AllPaths $mpath/cat[0-9]*/$page.* $mpath/man[0-9]*/$page.*"
|
||||
done
|
||||
|
||||
i=0
|
||||
for Path in $AllPaths; do
|
||||
istrue $debug && echo Path = $Path
|
||||
case "$Path" in
|
||||
*\*) ;;
|
||||
*)
|
||||
# Remove compressed-file suffix to make FileNames be the same
|
||||
# as it is when built by FindSectionsInIndex()
|
||||
FileNames[i]=${Path%.[zZ]}
|
||||
Path=${Path%/*}
|
||||
Sections[i]=${Path##*/*.}
|
||||
let i+=1 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# FindSection: display man page.
|
||||
# Uses ordarr[] (built from $ORDER) to display the version of the man
|
||||
# page that occurs first in $ORDER.
|
||||
# Sections[] gives the sections that a man page was found in.
|
||||
# If the global variable "exist" is set to 1, nothing is displayed;
|
||||
# the function instead returns zero if a page is found, nonzero if not.
|
||||
# The filename of each page is in FileNames[] with the same index.
|
||||
# Global vars used:
|
||||
# Sections[], FileNames[], ordarr[]
|
||||
FindSection ()
|
||||
{
|
||||
typeset -i NumPages i foundsec
|
||||
local section OtherSec filename NPAGER=$PAGER POpt page=$1 Pat
|
||||
local PageFile
|
||||
|
||||
NumPages=${#Sections[*]} # Number of versions of man page found.
|
||||
isfalse $NumPages && return 1
|
||||
case "$PAGER" in
|
||||
*less) Popt="-p$page" ;;
|
||||
esac
|
||||
|
||||
# For each section in ORDER, determine if any man page was found in
|
||||
# that section
|
||||
for section in "${ordarr[@]}"; do
|
||||
i=0
|
||||
foundsec=0
|
||||
while [ $i -lt $NumPages ]; do
|
||||
if [ "${Sections[i]}" = $section ]; then
|
||||
# Found a man page from this section of ORDER
|
||||
filename=${FileNames[i]}
|
||||
if [ -z "$PageFile" ]; then
|
||||
PageFile=$filename
|
||||
else
|
||||
if istrue $foundsec; then
|
||||
OtherSec="$OtherSec$page(${filename%/*/*} $section) "
|
||||
else
|
||||
OtherSec="$OtherSec$page($section) "
|
||||
fi
|
||||
fi
|
||||
foundsec=1
|
||||
istrue $exist && return
|
||||
fi
|
||||
let i+=1
|
||||
done
|
||||
done
|
||||
# No pages with the specified section found.
|
||||
[ -z "$PageFile" ] && return 1
|
||||
# Return if all we want to know is whether the man page exists.
|
||||
[ "$exist" = 1 ] && return 0
|
||||
if [ -z "$OtherSec" ]; then
|
||||
NPAGER="exec $PAGER"
|
||||
fi
|
||||
if [ -r $PageFile ]; then
|
||||
$NPAGER $POpt $PageFile
|
||||
elif [ -r $PageFile.z ]; then
|
||||
pcat $PageFile.z | $NPAGER $POpt
|
||||
elif [ -r $PageFile.Z ]; then
|
||||
zcat $PageFile.Z | $NPAGER $POpt
|
||||
elif [ -f $PageFile.gz ]; then
|
||||
gzip -dc $PageFile.gz | $NPAGER $POpt
|
||||
else
|
||||
echo "$PageFile: cannot open." 1>&2
|
||||
OtherSec=
|
||||
unset Sections[i]
|
||||
let i+=1
|
||||
continue
|
||||
fi
|
||||
echo "See also $OtherSec"
|
||||
exit 0
|
||||
}
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$name: print man pages.
|
||||
$name locates and prints the specified manual pages from the online UNIX
|
||||
documentation.
|
||||
$Usage
|
||||
Options:
|
||||
-e: Determine whether the specified man page exists. Nothing is printed;
|
||||
$0 exits with a zero status if the page exists and a nonzero status if
|
||||
it does not.
|
||||
-h: Print this help."
|
||||
}
|
||||
|
||||
# main program
|
||||
|
||||
typeset -i exist=0 debug=0
|
||||
|
||||
name=${0##*/}
|
||||
Usage="Usage: $name [-eh] [[manpath] section] command-name"
|
||||
|
||||
while getopts :hex opt; do
|
||||
case $opt in
|
||||
h) phelp; exit 0;;
|
||||
e) exist=1 ;;
|
||||
x) debug=1 ;;
|
||||
+?) echo "$name: options should not be preceded by a '+'." 1>&2; exit 2;;
|
||||
?)
|
||||
echo "$name: $OPTARG: bad option. Use -h for help." 1>&2 ; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# remove args that were options
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo -e "$Usage\nUse -h for help." 1>&2
|
||||
exit
|
||||
fi
|
||||
|
||||
P=$PAGER
|
||||
O=1:n:l:6:8:2:3:4:5:7:p:o
|
||||
T=$TERM
|
||||
M=${MANPATH:-/usr/local/man:/usr/man}
|
||||
[ -f /etc/default/man ] && . /etc/default/man
|
||||
[ -n "$P" ] && PAGER=$P
|
||||
[ -n "$O" ] && ORDER=$O
|
||||
[ -n "$T" ] && TERM=$T
|
||||
[ -n "$M" ] && MANPATH=$M
|
||||
|
||||
case $# in
|
||||
0) echo "No man page specified." ; exit 1;;
|
||||
1) page=$1;;
|
||||
2) ORDER=$(echo $1 | tr a-z A-Z) ; page=$2;;
|
||||
3) MANPATH=$1
|
||||
[ -n "$2" ] && ORDER=$(echo $2 | tr a-z A-Z)
|
||||
page=$3;;
|
||||
*) echo "Too many arguments."; exit 1;;
|
||||
esac
|
||||
|
||||
aargs=("$@")
|
||||
[ ! -t 0 ] && PAGER=cat
|
||||
|
||||
OIFS=$IFS
|
||||
IFS=:
|
||||
patharr=($MANPATH)
|
||||
i=0
|
||||
for d in $MANPATH; do
|
||||
for sec in $ORDER; do
|
||||
ordarr[i]=$d/cat${sec}
|
||||
let i+=1
|
||||
ordarr[i]=$d/man${sec}
|
||||
let i+=1
|
||||
done
|
||||
done
|
||||
IFS=$OIFS
|
||||
|
||||
istrue $debug && echo patharr = "${patharr[@]}"
|
||||
|
||||
# if less or more is being used, remove multiple blank lines
|
||||
export LESS="-s $LESS"
|
||||
export MORE="-s $MORE"
|
||||
|
||||
# Try using index
|
||||
FindSectionsInIndex "$page"
|
||||
# Exit 0 if a page was found and we're just testing for existence.
|
||||
FindSection "$page" && exit 0
|
||||
|
||||
# Try searching directories
|
||||
unset Sections[*]
|
||||
FindSectionsInDirs "$page"
|
||||
FindSection "$page" && exit 0
|
||||
|
||||
istrue $exist && exit 1
|
||||
|
||||
# Try using man
|
||||
# If using more or less, make man run faster by letting more or less compress
|
||||
# multiple blank lines instead of rmb
|
||||
#case "$PAGER" in
|
||||
#*more|*less) manopt=-b;;
|
||||
#esac
|
||||
|
||||
#cmd=(man $manopt -p$PAGER "${aargs[@]}")
|
||||
export PAGER
|
||||
cmd=(man $manopt "${aargs[@]}")
|
||||
istrue $debug && echo "$name: running ${cmd[*]}" 1>&2
|
||||
exec "${cmd[@]}"
|
||||
@@ -1,288 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
#
|
||||
# @(#) frcp.ksh 2.2 93/11/14
|
||||
# 92/06/29 john h. dubois iii (john@armory.com)
|
||||
# 92/10/14 Cleaned up, improved, added -d and -r options
|
||||
# 92/11/11 Made work with a dest of '.'
|
||||
# 93/07/09 Added -l and -n options, & login as anonymous if no .netrc entry
|
||||
# 93/11/14 Use either passwd or password in .netrc, since ftp does.
|
||||
#
|
||||
# conversion to bash v2 syntax by Chet Ramey
|
||||
#
|
||||
# frcp: ftp front end with rcp-like syntax.
|
||||
# Note: requires any machine names given to be listed with
|
||||
# user and password in .netrc. If not, anonymous FTP is
|
||||
# done.
|
||||
#
|
||||
# full path to ftp binary
|
||||
if [ -x /usr/bin/ftp ]; then
|
||||
FTP=/usr/bin/ftp;
|
||||
elif [ -x /usr/ucb/ftp ]; then
|
||||
FTP=/usr/ucb/ftp
|
||||
else
|
||||
FTP=ftp
|
||||
fi
|
||||
|
||||
istrue()
|
||||
{
|
||||
test 0 -ne "$1"
|
||||
}
|
||||
isfalse()
|
||||
{
|
||||
test 0 -eq "$1"
|
||||
}
|
||||
|
||||
# For each filename given, put the filename in filename[n]
|
||||
# and the machine it is on in machine[n].
|
||||
function SplitNames {
|
||||
typeset file
|
||||
typeset -i i=1
|
||||
|
||||
unset filename[*] machine[*]
|
||||
for file; do
|
||||
case "$file" in
|
||||
*:*) machine[i]=${file%%:*} ;;
|
||||
*) machine[i]=$LocalMach ;;
|
||||
esac
|
||||
filename[i]=${file#*:}
|
||||
let i+=1
|
||||
done
|
||||
}
|
||||
|
||||
function verboseprint {
|
||||
echo "$@"
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
|
||||
function MakeDir {
|
||||
OFS=$IFS
|
||||
local IFS=/ dir component
|
||||
|
||||
case "$1" in
|
||||
/*) ;;
|
||||
*) dir=.
|
||||
esac
|
||||
set -- $1
|
||||
IFS=$OFS
|
||||
for component; do
|
||||
dir=$dir/$component
|
||||
if [ ! -d "$dir" ]; then
|
||||
if mkdir "$dir"; then :; else
|
||||
echo "Could not make directory $dir." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
lastisdot ()
|
||||
{
|
||||
case "$1" in
|
||||
*/.|*/..) return 0;;
|
||||
*) return 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
# CopyFiles: issue ftp(TC) commands to copy files.
|
||||
# Usage: CopyFiles [sourcemachine:]sourcepath ... [destmachine:]destpath
|
||||
# Global vars:
|
||||
# Uses LocalMach (should be name of local machine)
|
||||
# Sets global arrs machine[]/filename[]
|
||||
function CopyFiles {
|
||||
unset machine[*] filename[*]
|
||||
|
||||
SplitNames "$@" # split names into filename[1..n] and machine[1..n]
|
||||
|
||||
local DestMach=${machine[$#]} # Machine to copy files to
|
||||
local DestPath=${filename[$#]} # Destination file/dir
|
||||
|
||||
unset machine[$#] filename[$#]
|
||||
|
||||
[ -z "$DestPath" ] && DestPath=. # dest was given as machine:
|
||||
|
||||
# Try to determine if destination should be a directory
|
||||
# so that it can be forced to be a directory.
|
||||
|
||||
case "$DestPath" in
|
||||
*/) ;; # don't add / if trailing / already present
|
||||
*) if [ $# -gt 2 ] || # if more than two args given, last must be a dir
|
||||
# If dest in on local machine, check whether it is a directory
|
||||
[ $DestMach = $LocalMach ] && [ -d "$DestPath" ] ||
|
||||
# If dest ends with . or .., it is a directory
|
||||
lastisdot "$DestPath"
|
||||
then
|
||||
DestPath=$DestPath/
|
||||
fi ;;
|
||||
esac
|
||||
|
||||
# If one of the above tests made us think dest is a directory,
|
||||
# but it isn't, complain
|
||||
case "$DestPath" in
|
||||
*/) if [ "$DestMach" = "$LocalMach" ] && [ ! -d "$DestPath" ]; then
|
||||
echo "Destination is not a directory." 1>&2
|
||||
exit 1
|
||||
fi ;;
|
||||
esac
|
||||
|
||||
DoCopy "$DestMach" "$DestPath"
|
||||
}
|
||||
|
||||
# Usage: OpenMachine machine-name
|
||||
# Emits login sequence or doesn't, depending on .netrc file and global
|
||||
# variables anon and noanon
|
||||
OpenMachine ()
|
||||
{
|
||||
local machine=$1 netrc=$HOME/.netrc user= password=
|
||||
|
||||
if isfalse $anon && [ -r $netrc ]; then
|
||||
set -- $(gawk '
|
||||
/machine (.* )?'"$machine"'($| )/,/^ *$/ {
|
||||
Fields[$1] = $2
|
||||
if ("passwd" in Fields)
|
||||
Fields["password"] = Fields["passwd"]
|
||||
if ("login" in Fields && "password" in Fields) {
|
||||
print Fields["login"] " " Fields["password"]
|
||||
exit
|
||||
}
|
||||
}
|
||||
' $netrc )
|
||||
user=$1
|
||||
password=$2
|
||||
fi
|
||||
if [ -z "$password" ]; then
|
||||
if istrue $noanon; then
|
||||
echo "No .netrc entry for machine $machine" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
user=anonymous
|
||||
password=$USER@$LocalMach
|
||||
fi
|
||||
verboseprint open $machine
|
||||
echo user $user "*******" 1>&2
|
||||
echo user $user $password
|
||||
}
|
||||
|
||||
# Usage: DoCopy destination-machine destination-path
|
||||
# Copies the files in global arrs machine[]/filename[] to the given dest
|
||||
# Global vars:
|
||||
# Uses machine[], filename[], LocalMach, check
|
||||
DoCopy ()
|
||||
{
|
||||
local DestMach=$1
|
||||
local DestPath=$2
|
||||
local OpenMach # Machine that connection is currently open to
|
||||
local OWD=$PWD SourceMach SourceFile
|
||||
local FileName
|
||||
typeset -i i=1
|
||||
|
||||
while [ $i -le ${#machine[*]} ]; do
|
||||
istrue $check && verboseprint "runique"
|
||||
|
||||
SourceMach=${machine[i]}
|
||||
SourceFile=${filename[i]}
|
||||
|
||||
DestFile=$DestPath
|
||||
# if DestPath is a dir,
|
||||
# add source filename to it without source path
|
||||
case "$DestFile" in
|
||||
*/) DestFile=$DestFile${SourceFile##*/} ;;
|
||||
esac
|
||||
|
||||
if [ $SourceMach = $LocalMach ]; then
|
||||
if [ $DestMach != "$OpenMach" ]; then
|
||||
OpenMachine $DestMach
|
||||
OpenMach=$DestMach
|
||||
fi
|
||||
verboseprint put $SourceFile $DestFile
|
||||
elif [ $DestMach = $LocalMach ]; then
|
||||
if istrue $check && [ -f "$DestFile" ]; then
|
||||
echo "$DestFile already exists." 1>&2
|
||||
continue
|
||||
fi
|
||||
# If destination is on local machine,
|
||||
# the dest will be a full dir/filename
|
||||
if istrue $createdirs; then
|
||||
MakeDir "${DestFile%/*}" || continue
|
||||
fi
|
||||
if [ $SourceMach != "$OpenMach" ]; then
|
||||
OpenMachine $SourceMach
|
||||
OpenMach=$SourceMach
|
||||
fi
|
||||
# If source filename has wildcards ([, ], *, ?) do an mget
|
||||
case "$SourceFile" in
|
||||
\[*\]|*\**|*\?*)
|
||||
verboseprint lcd "$DestFile"
|
||||
verboseprint mget "$SourceFile"
|
||||
verboseprint lcd $OWD ;;
|
||||
*) verboseprint get "$SourceFile" "$DestFile" ;;
|
||||
esac
|
||||
else
|
||||
echo "Neither source machine \"$SourceMach\" "\
|
||||
"nor destination machine \"$DestMach\" is local." 1>&2
|
||||
fi
|
||||
let i+=1
|
||||
done
|
||||
}
|
||||
|
||||
# Start of main program
|
||||
name=${0##*/}
|
||||
|
||||
if [ "$1" = -h ]; then
|
||||
echo \
|
||||
"$name: do ftp transfers using rcp-style parameters.
|
||||
Usage: $name <source> <destpath> or $name <source> [<source> ...] <destdir>
|
||||
At least one of <source> and <destpath> must be the local system.
|
||||
A remote filename is given as machinename:filename
|
||||
If remote filenames contain wildcards, they will be globbed on the remote
|
||||
machine. Make sure they are quoted when $name is invoked.
|
||||
If the invoking user's .netrc file (see ftp(TC)) contains an entry for the
|
||||
remote system with a login and password supplied, $name will log in using
|
||||
the given login and password. If not, $name will login in as user
|
||||
anonymous and with the user@localsystem as the password.
|
||||
Options:
|
||||
-c: check: do not overwrite files.
|
||||
-d: create directories as needed.
|
||||
-f: force: overwrite files (default).
|
||||
-h: print this help.
|
||||
-l: fail if there is no entry with login and password for the remote system,
|
||||
instead of logging in as anonymous.
|
||||
-n: log in as anonymous even if there is an entry for the remote system in
|
||||
the user's .netrc file.
|
||||
-r: read source/dest filename pairs from the standard input,
|
||||
one pair per line, and copy files accordingly."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
typeset -i check=0 createdirs=0 readinput=0 anon=0 noanon=0
|
||||
|
||||
while getopts :cdflnr Option
|
||||
do
|
||||
case "$Option" in
|
||||
c) check=1;;
|
||||
d) createdirs=1;;
|
||||
f) check=0;;
|
||||
l) noanon=1;;
|
||||
n) anon=1;;
|
||||
r) readinput=1;;
|
||||
\?) echo "$OPTARG: invalid option."; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND-1))
|
||||
|
||||
LocalMach=`hostname`
|
||||
|
||||
if istrue $readinput; then
|
||||
while read line; do
|
||||
CopyFiles $line
|
||||
done | $FTP -nv
|
||||
else
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "$name: Not enough arguments. Use -h for help." 1>&2
|
||||
exit
|
||||
fi
|
||||
CopyFiles "$@" | $FTP -nv
|
||||
fi
|
||||
@@ -1,44 +0,0 @@
|
||||
#! /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
|
||||
|
||||
Usage="Usage: $name file ..."
|
||||
phelp()
|
||||
{
|
||||
echo "$name: change filenames to lower case.
|
||||
$Usage
|
||||
Each file is moved to a name with the same directory component, if any,
|
||||
and with a filename component that is the same as the original but with
|
||||
any upper case letters changed to lower case."
|
||||
}
|
||||
|
||||
name=${0##*/}
|
||||
|
||||
while getopts "h" opt; do
|
||||
case "$opt" in
|
||||
h) phelp; exit 0;;
|
||||
*) echo "$Usage" 1>&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
for file; do
|
||||
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 "$0: $file -> $newname"
|
||||
else
|
||||
echo "$0: $file not changed."
|
||||
fi
|
||||
done
|
||||
@@ -1,187 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# @(#) ncp.ksh,nmv.ksh 1.1 94/07/23
|
||||
# 92/01/18 john h. dubois iii (john@armory.com)
|
||||
# 92/01/31 added check for no args left after shifts
|
||||
# 92/02/17 added help
|
||||
# 92/02/25 remove path component from filename before tacking it onto dest.
|
||||
# 92/03/15 exec mv or cp
|
||||
# 93/07/13 Added -i
|
||||
# 93/09/29 Made abort if file exists optional.
|
||||
# 93/11/19 Exit before invoking mv if no files to move
|
||||
# 94/01/03 Added o option
|
||||
# 94/04/13 Added x option.
|
||||
# Fixed appending of source filename, broken by earlier change.
|
||||
# 94/07/23 Append only the filename part of the source path.
|
||||
#
|
||||
# conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
false()
|
||||
{
|
||||
return 1
|
||||
}
|
||||
|
||||
true()
|
||||
{
|
||||
return 0
|
||||
}
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$name: do a $cmd with extra checking and options.
|
||||
$Usage
|
||||
$name is used as a front end for $cmd to get the [icfo] options, and so
|
||||
that a trailing / will force the last component of the path to be
|
||||
interpreted as a directory, so that $name foo bar/ will fail if bar is
|
||||
not an existing directory, instead of changing the name of foo to bar.
|
||||
Effectively, $name foo bar/ is short for $name foo bar/foo
|
||||
Options:
|
||||
-h prints this help.
|
||||
-c checks first for the existence of each file, and fails if it exists.
|
||||
-i is like -c except that if the file exists and stdin and stdout are a
|
||||
tty, a query is printed and a reply is read; a file is overwritten only
|
||||
if the reply begins with 'y'.
|
||||
-f unsets -c and -i (in case $cmd is aliased to $name).
|
||||
-o (overwrite only) checks that the named file(s) exist and fails for any
|
||||
that do not. It is the complement of the -c option.
|
||||
Whichever of [cifo] comes later on the command line determines the behaviour.
|
||||
Any of these options must come before any standard $cmd options."
|
||||
}
|
||||
|
||||
# interactive: Attempt to overwrite file should result in interactive
|
||||
# query rather than automatic failure.
|
||||
# noover: Do not overwrite files (if interactive is true, query, else fail)
|
||||
# overwrite: Only overwriting is allowed, not creation of new files.
|
||||
# debug: Print debugging info.
|
||||
typeset interactive=false noover=false overwrite=false debug=false
|
||||
name=${0##*/}
|
||||
|
||||
case "$name" in
|
||||
ncp|nmv) cmd=/bin/${name#?} ;;
|
||||
*) echo "$name: Must be invoked as ncp or nmv." 1>&2 ; exit 2;;
|
||||
esac
|
||||
|
||||
Usage="Usage: $name [-cfhio] $cmd-cmd-line"
|
||||
|
||||
while getopts :cfhiox opt; do
|
||||
case $opt in
|
||||
h) phelp; exit 0;;
|
||||
x) debug=true ;;
|
||||
c) noover=true ;;
|
||||
i) noover=true ; interactive=true ;;
|
||||
f) noover=false ; interactive=false ;;
|
||||
o) overwrite=true ; noover=false ; interactive=false;;
|
||||
+?) echo "$name: options should not be preceded by a '+'." 1>&2; exit 2;;
|
||||
?) echo "$name: $OPTARG: bad option. Use -h for help." 1>&2 ; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
# remove args that were options
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo -e "$Usage\nUse -h for help."
|
||||
exit
|
||||
fi
|
||||
|
||||
Check()
|
||||
{
|
||||
if [ ! -f "$1" ] && $overwrite; then
|
||||
echo "$name: $1: File does not exist." 1>&2
|
||||
return 1
|
||||
elif [ -f "$1" ] && $noover; then
|
||||
if [ $interactive = false ] || [ ! -t 0 ] || [ ! -t 1 ]; then
|
||||
echo "$name: $1: File exists." 1>&2
|
||||
return 1
|
||||
else
|
||||
while :; do
|
||||
echo -n \
|
||||
"$name: $1: File exists. Overwrite? (y)es/(n)o/(a)bort/(Y)es for all: " 1>&2
|
||||
read reply
|
||||
case "$reply" in
|
||||
y*)
|
||||
echo "$name: Overwriting $1."
|
||||
return 0
|
||||
;;
|
||||
Y*)
|
||||
echo "$name: Overwriting $1."
|
||||
interactive=false
|
||||
noover=false
|
||||
return 0
|
||||
;;
|
||||
[nN]*)
|
||||
echo "$name: Skipping $2."
|
||||
return 1
|
||||
;;
|
||||
[aA]*)
|
||||
echo "$name: Aborting."
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "$name: Invalid response." 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# i is the index of the filename being examined
|
||||
# lastarg is the index of the last filename before the dest directory name
|
||||
typeset -i i=0 lastarg=$(($#-1))
|
||||
|
||||
# Sets argv[0..$#-1]
|
||||
argv=("$@")
|
||||
$debug && echo argv = "${argv[@]}" 1>&2
|
||||
dest=${argv[lastarg]}
|
||||
|
||||
if $debug; then
|
||||
echo \
|
||||
"interactive=$interactive noover=$noover overwrite=$overwrite debug=$debug
|
||||
lastarg=$lastarg dest=$dest name=$name cmd=$cmd
|
||||
files=$*" 1>&2
|
||||
fi
|
||||
|
||||
if $noover || $overwrite; then
|
||||
$debug && echo "checking for existance of directories..." 1>&2
|
||||
# If the destination is not intended to be a directory...
|
||||
if [ $# -eq 2 ] && [ ! -d "$dest" ]; then
|
||||
Check "$dest" "$1" || exit 0 # No files to copy
|
||||
else
|
||||
while [ $i -lt $lastarg ]; do
|
||||
Check "$dest/${argv[i]##*/}" "${argv[i]}" || unset argv[i]
|
||||
let i+=1
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
[ ${#argv[@]} -lt 2 ] && exit 0
|
||||
|
||||
# If only 2 args are given, mv/cp will not insist that the destination
|
||||
# be a directory, which we want if the destination ends in "/" or if
|
||||
# the original number of args was >2.
|
||||
# $# is still the original number of args.
|
||||
# Tack the file name onto the destination to force this behaviour.
|
||||
|
||||
lastisslash()
|
||||
{
|
||||
case "$1" in
|
||||
*/) return 0;;
|
||||
*) return 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ ${#argv[@]} = 2 ] && { lastisslash "$2" || [ $# -gt 2 ]; }; then
|
||||
$debug && echo "Appending filename." 1>&2
|
||||
# Don't know which element of argv[] holds the source filename,
|
||||
# since may have started with more than 1 source file & had some unset.
|
||||
# So, compact args to make it easy to find the set one.
|
||||
argv=("${argv[@]}")
|
||||
argv[1]="${argv[1]}/${argv[0]##*/}"
|
||||
fi
|
||||
|
||||
$debug && echo "Executing command: $cmd ${argv[@]}" 1>&2
|
||||
exec $cmd "${argv[@]}"
|
||||
@@ -1,64 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# newext: change filename extension
|
||||
# @(#) newext.sh 1.1 93/04/13
|
||||
# 90/06/06 john h. dubois iii (john@armory.com)
|
||||
# 90/11/14 changed ksh-specific code to hybrid: if running under Bourne,
|
||||
# uses expr instead of ksh builtin ops. Removed SYSV specific code.
|
||||
# 91/08/06 added -t option
|
||||
# 92/11/06 made earlier code actually work!
|
||||
# 93/04/13 If no filenames given, act on files in current dir
|
||||
#
|
||||
# conversion to bash v2 syntax by Chet Ramey
|
||||
|
||||
usage="Usage: newext [-th] <oldext> <newext> [filename ...]"
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$usage
|
||||
Rename all given files that end in oldext with newext replacing oldext.
|
||||
If no filenames are given, all files in the current directory that end
|
||||
in oldext are acted on (no filename is equivalent to '*').
|
||||
Options:
|
||||
-h: Print this help.
|
||||
-t: Test: No action is taken except to print the mv commands that would
|
||||
be executed if -t was not given."
|
||||
}
|
||||
|
||||
while getopts "th" opt; do
|
||||
case "$opt" in
|
||||
t) echo=echo;;
|
||||
h) phelp; exit 0;;
|
||||
*) echo "$usage" 1>&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
oldext=$1
|
||||
newext=$2
|
||||
|
||||
case $# in
|
||||
[01]) echo -e "$usage\nUse -h for help." 1>&2; exit 2;;
|
||||
2) shift ; shift; set -- *;;
|
||||
*) shift ; shift;;
|
||||
esac
|
||||
|
||||
found=
|
||||
|
||||
for file
|
||||
do
|
||||
case "$file" in
|
||||
*$oldext)
|
||||
newname="${file%$oldext}$newext"
|
||||
$echo mv "$file" "$newname"
|
||||
found=true;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$found" ]; then
|
||||
echo "No files ending in \"$oldext\"."
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
@@ -1,187 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# @(#) ncp.ksh,nmv.ksh 1.1 94/07/23
|
||||
# 92/01/18 john h. dubois iii (john@armory.com)
|
||||
# 92/01/31 added check for no args left after shifts
|
||||
# 92/02/17 added help
|
||||
# 92/02/25 remove path component from filename before tacking it onto dest.
|
||||
# 92/03/15 exec mv or cp
|
||||
# 93/07/13 Added -i
|
||||
# 93/09/29 Made abort if file exists optional.
|
||||
# 93/11/19 Exit before invoking mv if no files to move
|
||||
# 94/01/03 Added o option
|
||||
# 94/04/13 Added x option.
|
||||
# Fixed appending of source filename, broken by earlier change.
|
||||
# 94/07/23 Append only the filename part of the source path.
|
||||
#
|
||||
# conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
false()
|
||||
{
|
||||
return 1
|
||||
}
|
||||
|
||||
true()
|
||||
{
|
||||
return 0
|
||||
}
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$name: do a $cmd with extra checking and options.
|
||||
$Usage
|
||||
$name is used as a front end for $cmd to get the [icfo] options, and so
|
||||
that a trailing / will force the last component of the path to be
|
||||
interpreted as a directory, so that $name foo bar/ will fail if bar is
|
||||
not an existing directory, instead of changing the name of foo to bar.
|
||||
Effectively, $name foo bar/ is short for $name foo bar/foo
|
||||
Options:
|
||||
-h prints this help.
|
||||
-c checks first for the existence of each file, and fails if it exists.
|
||||
-i is like -c except that if the file exists and stdin and stdout are a
|
||||
tty, a query is printed and a reply is read; a file is overwritten only
|
||||
if the reply begins with 'y'.
|
||||
-f unsets -c and -i (in case $cmd is aliased to $name).
|
||||
-o (overwrite only) checks that the named file(s) exist and fails for any
|
||||
that do not. It is the complement of the -c option.
|
||||
Whichever of [cifo] comes later on the command line determines the behaviour.
|
||||
Any of these options must come before any standard $cmd options."
|
||||
}
|
||||
|
||||
# interactive: Attempt to overwrite file should result in interactive
|
||||
# query rather than automatic failure.
|
||||
# noover: Do not overwrite files (if interactive is true, query, else fail)
|
||||
# overwrite: Only overwriting is allowed, not creation of new files.
|
||||
# debug: Print debugging info.
|
||||
typeset interactive=false noover=false overwrite=false debug=false
|
||||
name=${0##*/}
|
||||
|
||||
case "$name" in
|
||||
ncp|nmv) cmd=/bin/${name#?} ;;
|
||||
*) echo "$name: Must be invoked as ncp or nmv." 1>&2 ; exit 2;;
|
||||
esac
|
||||
|
||||
Usage="Usage: $name [-cfhio] $cmd-cmd-line"
|
||||
|
||||
while getopts :cfhiox opt; do
|
||||
case $opt in
|
||||
h) phelp; exit 0;;
|
||||
x) debug=true ;;
|
||||
c) noover=true ;;
|
||||
i) noover=true ; interactive=true ;;
|
||||
f) noover=false ; interactive=false ;;
|
||||
o) overwrite=true ; noover=false ; interactive=false;;
|
||||
+?) echo "$name: options should not be preceded by a '+'." 1>&2; exit 2;;
|
||||
?) echo "$name: $OPTARG: bad option. Use -h for help." 1>&2 ; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
# remove args that were options
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo -e "$Usage\nUse -h for help."
|
||||
exit
|
||||
fi
|
||||
|
||||
Check()
|
||||
{
|
||||
if [ ! -f "$1" ] && $overwrite; then
|
||||
echo "$name: $1: File does not exist." 1>&2
|
||||
return 1
|
||||
elif [ -f "$1" ] && $noover; then
|
||||
if [ $interactive = false ] || [ ! -t 0 ] || [ ! -t 1 ]; then
|
||||
echo "$name: $1: File exists." 1>&2
|
||||
return 1
|
||||
else
|
||||
while :; do
|
||||
echo -n \
|
||||
"$name: $1: File exists. Overwrite? (y)es/(n)o/(a)bort/(Y)es for all: " 1>&2
|
||||
read reply
|
||||
case "$reply" in
|
||||
y*)
|
||||
echo "$name: Overwriting $1."
|
||||
return 0
|
||||
;;
|
||||
Y*)
|
||||
echo "$name: Overwriting $1."
|
||||
interactive=false
|
||||
noover=false
|
||||
return 0
|
||||
;;
|
||||
[nN]*)
|
||||
echo "$name: Skipping $2."
|
||||
return 1
|
||||
;;
|
||||
[aA]*)
|
||||
echo "$name: Aborting."
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "$name: Invalid response." 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# i is the index of the filename being examined
|
||||
# lastarg is the index of the last filename before the dest directory name
|
||||
typeset -i i=0 lastarg=$(($#-1))
|
||||
|
||||
# Sets argv[0..$#-1]
|
||||
argv=("$@")
|
||||
$debug && echo argv = "${argv[@]}" 1>&2
|
||||
dest=${argv[lastarg]}
|
||||
|
||||
if $debug; then
|
||||
echo \
|
||||
"interactive=$interactive noover=$noover overwrite=$overwrite debug=$debug
|
||||
lastarg=$lastarg dest=$dest name=$name cmd=$cmd
|
||||
files=$*" 1>&2
|
||||
fi
|
||||
|
||||
if $noover || $overwrite; then
|
||||
$debug && echo "checking for existance of directories..." 1>&2
|
||||
# If the destination is not intended to be a directory...
|
||||
if [ $# -eq 2 ] && [ ! -d "$dest" ]; then
|
||||
Check "$dest" "$1" || exit 0 # No files to copy
|
||||
else
|
||||
while [ $i -lt $lastarg ]; do
|
||||
Check "$dest/${argv[i]##*/}" "${argv[i]}" || unset argv[i]
|
||||
let i+=1
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
[ ${#argv[@]} -lt 2 ] && exit 0
|
||||
|
||||
# If only 2 args are given, mv/cp will not insist that the destination
|
||||
# be a directory, which we want if the destination ends in "/" or if
|
||||
# the original number of args was >2.
|
||||
# $# is still the original number of args.
|
||||
# Tack the file name onto the destination to force this behaviour.
|
||||
|
||||
lastisslash()
|
||||
{
|
||||
case "$1" in
|
||||
*/) return 0;;
|
||||
*) return 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ ${#argv[@]} = 2 ] && { lastisslash "$2" || [ $# -gt 2 ]; }; then
|
||||
$debug && echo "Appending filename." 1>&2
|
||||
# Don't know which element of argv[] holds the source filename,
|
||||
# since may have started with more than 1 source file & had some unset.
|
||||
# So, compact args to make it easy to find the set one.
|
||||
argv=("${argv[@]}")
|
||||
argv[1]="${argv[1]}/${argv[0]##*/}"
|
||||
fi
|
||||
|
||||
$debug && echo "Executing command: $cmd ${argv[@]}" 1>&2
|
||||
exec $cmd "${argv[@]}"
|
||||
@@ -1,187 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# @(#) pages.sh 1.0 92/09/26
|
||||
# 92/09/05 John H. DuBois III (jhdiii@armory.com)
|
||||
# 92/09/26 Added help
|
||||
#
|
||||
# conversion to bash v2 syntax by Chet Ramey
|
||||
|
||||
Usage="$0 [-h] [-n lines/page] page-ranges [file ...]"
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "$Usage" 1>&2
|
||||
}
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$0: print selected pages.
|
||||
Usage: $Usage
|
||||
|
||||
If no file names are given, the standard input is read.
|
||||
|
||||
The input is grouped into pages and a selected subset of them is printed.
|
||||
Formfeeds are acted on correctly.
|
||||
|
||||
If the output device does automatic line wrap, lines that longer than
|
||||
the width of the output device will result in incorrect output.
|
||||
The first non-option argument is a list of pages to print.
|
||||
|
||||
Pages are given as a list of ranges separated by commas.
|
||||
A range is either one number, two numbers separted by a dash,
|
||||
or one number followed by a dash. A range consisting of one
|
||||
number followed by a dash extends to the end of the document.
|
||||
|
||||
Options:
|
||||
-n sets the number of lines per page to n. The default is 66."
|
||||
}
|
||||
|
||||
while getopts "n:h" opt; do
|
||||
case "$opt" in
|
||||
n) LinesPerPage=$OPTARG;;
|
||||
h) phelp; exit 0;;
|
||||
*) usage; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $(($OPTIND - 1))
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo $0: no page ranges given. 1>&2
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PageList=$1
|
||||
shift
|
||||
|
||||
gawk "
|
||||
BEGIN {
|
||||
PageList = \"$PageList\"; LinesPerPage = \"$LinesPerPage\""'
|
||||
if (LinesPerPage == "")
|
||||
LinesPerPage = 66
|
||||
else
|
||||
if (LinesPerPage !~ "[1-9][0-9]*")
|
||||
ErrExit("Bad value for lines per page: " LinesPerPage)
|
||||
LinesPerPage += 0
|
||||
NumRanges = split(PageList,Ranges,",")
|
||||
for (i = 1; i <= NumRanges; i++) {
|
||||
if ((StartRange = EndRange = Ranges[i]) !~ "^[0-9]+(-([0-9]+)?)?$")
|
||||
ErrExit("Bad range \"" StartRange "\"")
|
||||
sub("-.*","",StartRange)
|
||||
sub(".*-","",EndRange)
|
||||
if (EndRange == "")
|
||||
EndRange = 2 ^ 30
|
||||
# Force StartRange and EndRange to be numeric values
|
||||
if ((StartRange += 0) == 0 || (EndRange += 0) == 0)
|
||||
ErrExit("Invalid page number \"0\" in range " Ranges[i])
|
||||
if (StartRange > EndRange)
|
||||
ErrExit("Start page comes after end page in range " Ranges[i])
|
||||
TmpRangeStarts[i] = StartRange
|
||||
TmpRangeEnds[i] = EndRange
|
||||
}
|
||||
|
||||
# Sort ranges
|
||||
qsort(TmpRangeStarts,k)
|
||||
RangeEnds[0] = 0
|
||||
for (i = 1; i <= NumRanges; i++) {
|
||||
RangeEnds[i] = TmpRangeEnds[k[i]]
|
||||
if ((RangeStarts[i] = TmpRangeStarts[k[i]]) <= RangeEnds[i - 1])
|
||||
ErrExit("Overlapping ranges: " Ranges[k[i]] "," Ranges[k[i - 1]])
|
||||
}
|
||||
|
||||
RangeNum = LineNum = PageNum = 1
|
||||
InRange = In(PageNum,RangeStarts[RangeNum],RangeEnds[RangeNum])
|
||||
FS = "\014"
|
||||
}
|
||||
|
||||
{
|
||||
if (LineNum > LinesPerPage)
|
||||
NewPage()
|
||||
if (InRange)
|
||||
printf "%s",$1
|
||||
# Deal with formfeeds
|
||||
for (i = 2; i <= NF; i++) {
|
||||
if (InRange)
|
||||
printf "\014"
|
||||
NewPage()
|
||||
if (InRange)
|
||||
printf "%s",$i
|
||||
}
|
||||
if (InRange)
|
||||
print ""
|
||||
LineNum++
|
||||
}
|
||||
|
||||
function NewPage() {
|
||||
PageNum++
|
||||
LineNum = 1
|
||||
# At the start of each page, check whether we are in a print range
|
||||
WereInRange = InRange
|
||||
InRange = In(PageNum,RangeStarts[RangeNum],RangeEnds[RangeNum])
|
||||
# If last page was in range and we no longer are, move to next range
|
||||
if (WereInRange && !InRange && ++RangeNum > NumRanges)
|
||||
exit
|
||||
}
|
||||
|
||||
function In(a,Min,Max) {
|
||||
return (Min <= a && a <= Max)
|
||||
}
|
||||
|
||||
function ErrExit(S) {
|
||||
print S > "/dev/stderr"
|
||||
Err = 1
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Arr is an array of values with arbitrary indices.
|
||||
# Array k is returned with numeric indices 1..n.
|
||||
# The values in k are the indices of array arr,
|
||||
# ordered so that if array arr is stepped through
|
||||
# in the order arr[k[1]] .. arr[k[n]], it will be stepped
|
||||
# through in order of the values of its elements.
|
||||
# The return value is the number of elements in the array (n).
|
||||
function qsort(arr,k, ArrInd,end) {
|
||||
end = 0
|
||||
for (ArrInd in arr)
|
||||
k[++end] = ArrInd;
|
||||
qsortseg(arr,k,1,end);
|
||||
return end
|
||||
}
|
||||
|
||||
function qsortseg(arr,k,start,end, left,right,sepval,tmp,tmpe,tmps) {
|
||||
# handle two-element case explicitely for a tiny speedup
|
||||
if ((end - start) == 1) {
|
||||
if (arr[tmps = k[start]] > arr[tmpe = k[end]]) {
|
||||
k[start] = tmpe
|
||||
k[end] = tmps
|
||||
}
|
||||
return
|
||||
}
|
||||
left = start;
|
||||
right = end;
|
||||
sepval = arr[k[int((left + right) / 2)]]
|
||||
# Make every element <= sepval be to the left of every element > sepval
|
||||
while (left < right) {
|
||||
while (arr[k[left]] < sepval)
|
||||
left++
|
||||
while (arr[k[right]] > sepval)
|
||||
right--
|
||||
if (left < right) {
|
||||
tmp = k[left]
|
||||
k[left++] = k[right]
|
||||
k[right--] = tmp
|
||||
}
|
||||
}
|
||||
if (left == right)
|
||||
if (arr[k[left]] < sepval)
|
||||
left++
|
||||
else
|
||||
right--
|
||||
if (start < right)
|
||||
qsortseg(arr,k,start,right)
|
||||
if (left < end)
|
||||
qsortseg(arr,k,left,end)
|
||||
}
|
||||
' "$@"
|
||||
@@ -1,127 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
#
|
||||
# @(#) p.ksh 1.1 93/11/09
|
||||
# p: page compressed & plain files in the order given
|
||||
# 92/01/23 john h. dubois iii (john@armory.com)
|
||||
# 92/02/14 changed incorrect zpack to pcat
|
||||
# 92/02/16 added help
|
||||
# 92/10/11 search for file.Z and file.z if file not found
|
||||
# 92/10/18 pass options to pager
|
||||
# 93/11/09 Understand gzipped files too
|
||||
# Wait after printing message about unreadable files
|
||||
# Make less prompt include name of file being uncompressed
|
||||
#
|
||||
# conversion to bash v2 by Chet Ramey; renamed to pf
|
||||
#
|
||||
DefPager=/local/bin/less
|
||||
|
||||
istrue()
|
||||
{
|
||||
test 0 -ne "$1"
|
||||
}
|
||||
|
||||
warn()
|
||||
{
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
|
||||
if [ "$1" = -h ]; then
|
||||
echo \
|
||||
"$0: page a file.
|
||||
Usage: $0 [pager-option ...] [filename ...]
|
||||
Files are paged by the program specified in the user's PAGER
|
||||
environment variable, or by $DefPager if PAGER is not set.
|
||||
If no filename is given, text to page is read from the standard input.
|
||||
If filenames are given, they are either paged directly, or unpacked/
|
||||
uncompressed and then paged. Files are assumed to be in packed, compressed,
|
||||
or gzipped format if the filename ends in .Z, .z, or .gz respectively.
|
||||
If a filename that does not end in .Z, .z, or .gz is not found, it is
|
||||
searched for with one of those extensions attached.
|
||||
Each group of plain files is paged by a single instance of the pager.
|
||||
Each packed or compressed file is paged by a separate instance of the
|
||||
pager.
|
||||
Initial arguments beginning with + or - are taken to be pager options and
|
||||
are passed to each instance of the pager.
|
||||
If a pager option takes a value it should be given with the option as a
|
||||
single argument (with no space between the option and the value)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get pager options
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-*|+*) Opts="$Opts $1" ; shift;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -z "$PAGER" ] && PAGER=$DefPager
|
||||
|
||||
# Read from stdin
|
||||
[ $# = 0 ] && exec $PAGER $Opts
|
||||
|
||||
typeset -i filenum=0 badfile=0
|
||||
|
||||
for file; do
|
||||
if [ ! -r "$file" ]; then
|
||||
case "$file" in
|
||||
*.[Zz]|*.gz)
|
||||
# Check if user specified a compressed file without giving its extension
|
||||
for ext in Z z gz; do
|
||||
if [ -r "$file.$ext" ]; then
|
||||
file="$file.$ext"
|
||||
break
|
||||
fi
|
||||
done;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -r "$file" ]; then
|
||||
warn "$file: cannot read."
|
||||
badfile=1
|
||||
else
|
||||
files[filenum]=$file
|
||||
let filenum+=1
|
||||
fi
|
||||
done
|
||||
|
||||
if istrue $badfile && [ $filenum -gt 0 ]; then
|
||||
echo -n "Press return to continue..." 1>&2
|
||||
read
|
||||
fi
|
||||
|
||||
unset plain
|
||||
|
||||
for file in "${files[@]}"; do
|
||||
case "$file" in
|
||||
*.[zZ]|*.gz)
|
||||
set -- Z zcat z pcat gz gzcat
|
||||
# Find correct uncompression program
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$file" in
|
||||
*.$1)
|
||||
# Page any uncompressed files so that they will be read
|
||||
# in the correct order
|
||||
[ ${#plain[@]} -gt 0 ] && $PAGER $Opts "${plain[@]}"
|
||||
unset plain[*]
|
||||
# If page is less, set the prompt to include the name of
|
||||
# the file being uncompressed. Escape the . in the extension
|
||||
# because less treats is specially in prompts (other dots
|
||||
# in filenames will still be mucked with).
|
||||
case "$PAGER" in
|
||||
*less) Prompt="-P[${file%.$1}\\.$1] (%pb\\%)" ;;
|
||||
*) unset Prompt ;;
|
||||
esac
|
||||
$2 "$file" | $PAGER "$Prompt" $Opts
|
||||
break
|
||||
esac
|
||||
shift 2
|
||||
done
|
||||
;;
|
||||
*) plain[${#plain[@]}]=$file;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Page any uncompressed files that haven't been paged yet
|
||||
[ ${#plain[@]} -gt 0 ] && exec $PAGER $Opts "${plain[@]}"
|
||||
@@ -1,25 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# pmtop - poor man's `top' for SunOS 4.x
|
||||
#
|
||||
|
||||
CLEAR=clear # could also be 'tput clear'
|
||||
HEADER="USER PID %CPU %MEM SZ RSS TT STAT START TIME COMMAND"
|
||||
|
||||
if [ -n "$LINES" ]; then
|
||||
SS=$(( $LINES - 2 ))
|
||||
else
|
||||
SS=20
|
||||
fi
|
||||
|
||||
while :
|
||||
do
|
||||
$CLEAR
|
||||
echo "$HEADER"
|
||||
ps -aux | sort -nr -k 3 | sed ${SS}q
|
||||
sleep 5
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
@@ -1,585 +0,0 @@
|
||||
#!/bin/bash
|
||||
#@ This program came from: ftp://ftp.armory.com/pub/scripts/ren
|
||||
#@ Look there for the latest version.
|
||||
#@ If you don't find it, look through http://www.armory.com/~ftp/
|
||||
#
|
||||
# @(#) ren 2.1.1 2002-03-17
|
||||
# 1990-06-01 John H. DuBois III (john@armory.com)
|
||||
# 1991-02-25 Improved help info
|
||||
# 1992-06-07 Remove quotes from around shell pattern as required by new ksh
|
||||
# 1994-05-10 Exit if no globbing chars given.
|
||||
# 1995-01-23 Allow filename set to be given on command line.
|
||||
# 1997-09-24 1.4 Let [] be used for globbing. Added x option.
|
||||
# 1997-11-26 1.4.1 Notice if the sequences of globbing chars aren't the same.
|
||||
# 1999-05-13 Changed name to ren to avoid conflict with /etc/rename
|
||||
# 2000-01-01 1.4.2 Let input patterns that contain whitespace be used.
|
||||
# 2001-02-14 1.5 Better test for whether old & new globbing seqs are identical.
|
||||
# 2001-02-20 1.6 Added pP options.
|
||||
# 2001-02-27 1.7 Added qf options. Improved interpretation of rename patterns.
|
||||
# 2001-05-10 1.8 Allow multiple pP options. Added Qr options.
|
||||
# 2001-07-25 2.0 Added mz options.
|
||||
# 2001-11-25 2.1 Allow segment ranges to be given with -m. Work under ksh93.
|
||||
# 2002-03-17 2.1.1 Fixed bug in test for legal expressions.
|
||||
|
||||
# todo: It would be nice to be able to escape metacharacters with '\'
|
||||
# todo: Should enhance patterns to make ] in a pair of brackets work ([]])
|
||||
# todo: Allow use of all ksh globbing patterns.
|
||||
# todo: Allow use of extended regexps, with () to enumerate pieces and \num to
|
||||
# todo: select them.
|
||||
#
|
||||
# Modifications for bash made by Chet Ramey <chet@po.cwru.edu>
|
||||
|
||||
name=${0##*/}
|
||||
Usage="Usage:
|
||||
$name [-fhqtv] [-m<segstart[:segend]=operation>] [-z<len>] [-[pP]<pattern>]
|
||||
oldpattern [newpattern [filename ...]]
|
||||
or
|
||||
$name -r [same options as above] oldpattern newpattern directory ..."
|
||||
tell=false
|
||||
verbose=false
|
||||
warn=true
|
||||
warnNoFiles=true
|
||||
debug=false
|
||||
recurse=false
|
||||
inclPat=
|
||||
exclPat=
|
||||
declare -i inclCt=0 exclCt=0
|
||||
check=true
|
||||
declare -i j op_end_seg
|
||||
|
||||
# Begin bash additions
|
||||
shopt -s extglob
|
||||
|
||||
#
|
||||
# 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
|
||||
}
|
||||
|
||||
# End bash additions
|
||||
|
||||
while getopts :htvxp:P:fqQrm:z: opt; do
|
||||
case $opt in
|
||||
h)
|
||||
print -r -- \
|
||||
"$name: rename files by changing parts of filenames that match a pattern.
|
||||
$Usage
|
||||
oldpattern and newpattern are subsets of sh filename patterns; the only
|
||||
globbing operators (wildcards) allowed are ?, *, and []. All filenames that
|
||||
match oldpattern will be renamed with the filename characters that match the
|
||||
constant (non-globbing) characters of oldpattern changed to the corresponding
|
||||
constant characters of newpattern. The characters of the filename that match
|
||||
the globbing operators of oldpattern will be preserved. Globbing operators
|
||||
in oldpattern must occur in the same order in newpattern; for every globbing
|
||||
operators in newpattern there must be an identical globbing operators in
|
||||
oldpattern in the same sequence. Both arguments should be quoted since
|
||||
globbing operators are special to the shell. If filenames are given, only
|
||||
those named are acted on; if not, all filenames that match oldpattern are acted
|
||||
on. newpattern is required in all cases except when -m is given and no further
|
||||
arguments are given.
|
||||
If you are unsure whether a $name command will do what you intend, issue it
|
||||
with the -t option first to be sure.
|
||||
Examples:
|
||||
$name \"/tmp/foo*.ba.?\" \"/tmp/new*x?\"
|
||||
All filenames in /tmp that match foo*.ba.? will have the \"foo\" part
|
||||
replaced by \"new\" and the \".ba.\" part replaced by \"x\".
|
||||
For example, /tmp/fooblah.ba.baz would be renamed to /tmp/newblahxbaz.
|
||||
$name \* \*- foo bar baz
|
||||
foo, bar, and baz will be renamed to foo-, bar-, and baz-.
|
||||
$name '????????' '????-??-??'
|
||||
All filenames that are 8 characters long will be changed such that dashes
|
||||
are inserted after the 4th and 6th characters.
|
||||
Options:
|
||||
-h: Print this help.
|
||||
-r: Recursive operation. Filenames given on the command line after oldpattern
|
||||
and newpattern are taken to be directories to traverse recursively. For
|
||||
each subdirectory found, the specified renaming is applied to any matching
|
||||
filenames. oldpattern and newpattern should not include any directory
|
||||
components.
|
||||
-p<pattern>, -P<pattern>: Act only on filenames that do (if -p is given) or do
|
||||
not (if -P is given) match the sh-style filename globbing pattern
|
||||
<pattern>. This further restricts the filenames that are acted on, beyond
|
||||
the filename selection produced by oldpattern and the filename list (if
|
||||
any). <pattern> must be quoted to prevent it from being interpreted by the
|
||||
shell. Multiple instances of these options may be given. In this case,
|
||||
filenames are acted on only if they match at least one of the patterns
|
||||
given with -p and do not match any of the patterns given with -P.
|
||||
-m<segstart[:segend]=operation>: For each file being renamed, perform a
|
||||
mathematical operation on the string that results from concatenating
|
||||
together the filename segments that matched globbing operator numbers
|
||||
segstart through segend, where operators are numbered in order of
|
||||
occurrence from the left. For example, in the pattern a?b*c[0-9]f, segment
|
||||
1 consists of the character that matched ?, segment 2 consists of the
|
||||
character(s) that matched *, and segment 3 consists of the character that
|
||||
matched [0-9]. The selected segments are replaced with the result of the
|
||||
mathematical operation.
|
||||
The concatenated string must consist of characters that can be interpreted
|
||||
as a decimal integer; if it does not, the filename is not acted on. This
|
||||
number is assigned to the variable 'i', which can be referenced by the
|
||||
operation. The operations available are those understood by the ksh
|
||||
interpreter, which includes most of the operators and syntax of the C
|
||||
language. The original filename segment is replaced by the result of the
|
||||
operation. If -m is used, newpattern may be an empty string or not given
|
||||
at all (if no directory/file names are given). In this case, it is taken
|
||||
to be the same as oldpattern.
|
||||
If segend is given, any fixed text that occurs in the pattern between the
|
||||
starting and ending globbing segments is discarded. If there are fewer
|
||||
globbing segments than segend, no complaint is issued; the string is formed
|
||||
from segment segstart through the last segment that does exist.
|
||||
If segend is not given, the only segment acted on is startseg.
|
||||
Examples:
|
||||
$name -m3=i+6 '??*.ppm'
|
||||
This is equivalent to:
|
||||
$name -m3=i+6 '??*.ppm' '??*.ppm'
|
||||
Since the old pattern and new pattern are identical, this would
|
||||
normally be a no-op. But in this case, if a filename of ab079.ppm is
|
||||
given, it is changed to ab85.ppm.
|
||||
$name '-m1:2=i*2' 'foo??bar'
|
||||
This will change a file named foo12bar to foo24bar
|
||||
$name '-m1:2=i*2' 'foo?xyz?bar'
|
||||
This will also change a file named foo1xyz2bar to foo24bar
|
||||
-z<len>: Set the size of the number fields that result when -m is used. The
|
||||
field is truncated to the trailing <len> digits or filled out to <len>
|
||||
digits with leading zeroes. In the above example, if -z3 is given, the
|
||||
output filename will be ab085.ppm.
|
||||
-f: Force rename. By default, $name will not rename files if a file with the
|
||||
new filename already exists. If -f is given, $name will carry out the
|
||||
rename anyway.
|
||||
-q: Quiet operation. By default, if -f is given, $name will still notify the
|
||||
user if a rename results in replacement of an already-existing filename.
|
||||
If -q is given, no notification is issued.
|
||||
-Q: Suppress other warnings. By default, a warning is issued if no files are
|
||||
selected for acting upon. If -Q is given, no warning is issued.
|
||||
-v: Show the rename commands being executed.
|
||||
-t: Show what rename commands would be done, but do not carry them out."
|
||||
exit 0
|
||||
;;
|
||||
f)
|
||||
check=false
|
||||
;;
|
||||
q)
|
||||
warn=false
|
||||
;;
|
||||
Q)
|
||||
warnNoFiles=false
|
||||
;;
|
||||
r)
|
||||
warnNoFiles=false
|
||||
recurse=true
|
||||
;;
|
||||
t)
|
||||
tell=true
|
||||
;;
|
||||
v)
|
||||
verbose=true
|
||||
;;
|
||||
x)
|
||||
verbose=true
|
||||
debug=true
|
||||
;;
|
||||
p)
|
||||
inclPats[inclCt]=$OPTARG
|
||||
((inclCt+=1))
|
||||
;;
|
||||
P)
|
||||
exclPats[exclCt]=$OPTARG
|
||||
((exclCt+=1))
|
||||
;;
|
||||
m)
|
||||
# Store operation for each segment number in ops[num]
|
||||
# Store ending segment number in op_end_seg[num]
|
||||
range=${OPTARG%%=*}
|
||||
op=${OPTARG#*=}
|
||||
start=${range%%:*}
|
||||
end=${range#*:}
|
||||
if [[ "$start" != +([0-9]) || "$start" -eq 0 ]]; then
|
||||
print -ru2 -- "$name: Bad starting segment number given with -m: $start"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$end" != +([0-9]) || "$end" -eq 0 ]]; then
|
||||
print -ru2 -- "$name: Bad ending segment number given with -m: $end"
|
||||
exit 1
|
||||
fi
|
||||
if [[ start -gt end ]]; then
|
||||
print -ru2 -- "$name: Ending segment ($end) is less than starting segment ($start)"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$op" != @(|*[!_a-zA-Z0-9])i@(|[!_a-zA-Z0-9]*) ]]; then
|
||||
print -ru2 -- \
|
||||
"$name: Operation given with -m does not reference 'i': $op"
|
||||
exit 1
|
||||
fi
|
||||
# Test whether operation is legal. let returns 1 both for error
|
||||
# indication and when last expression evaluates to 0, so evaluate 1
|
||||
# after test expression.
|
||||
i=1
|
||||
let "$op" 1 2>/dev/null || {
|
||||
print -ru2 -- \
|
||||
"$name: Bad operation given with -m: $op"
|
||||
exit 1
|
||||
}
|
||||
ops[start]=$op
|
||||
op_end_seg[start]=$end
|
||||
;;
|
||||
z)
|
||||
if [[ "$OPTARG" != +([0-9]) || "$OPTARG" -eq 0 ]]; then
|
||||
print -ru2 -- "$name: Bad length given with -z: $OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
typeset -Z$OPTARG j || exit 1
|
||||
;;
|
||||
+?) # no way to tell getopts to not treat +x as an option
|
||||
print -r -u2 "$name: Do not prefix options with '+'."
|
||||
exit 1
|
||||
;;
|
||||
:)
|
||||
print -r -u2 \
|
||||
"$name: Option -$OPTARG requires a value.
|
||||
$Usage
|
||||
Use -h for help."
|
||||
exit 1
|
||||
;;
|
||||
\?)
|
||||
print -r -u2 \
|
||||
"$name: -$OPTARG: no such option.
|
||||
$Usage
|
||||
Use -h for help."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# remove args that were options
|
||||
let OPTIND=OPTIND-1
|
||||
shift $OPTIND
|
||||
|
||||
oldpat=$1
|
||||
newpat=$2
|
||||
|
||||
# If -m is given, a non-existant or null newpat should be set to oldpat
|
||||
if [ ${#ops[*]} -gt 0 ]; then
|
||||
case $# in
|
||||
0)
|
||||
;;
|
||||
1)
|
||||
set -- "$oldpat" "$oldpat"
|
||||
newpat=$oldpat
|
||||
$debug && print -ru2 -- "Set new pattern to: $newpat"
|
||||
;;
|
||||
*)
|
||||
if [ -z "$newpat" ]; then
|
||||
shift 2
|
||||
set -- "$oldpat" "$oldpat" "$@"
|
||||
newpat=$oldpat
|
||||
$debug && print -ru2 -- "Set new pattern to: $newpat"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Make sure input patterns that contain whitespace can be expanded properly
|
||||
IFS=
|
||||
|
||||
origPat=$oldpat
|
||||
|
||||
# Generate list of filenames to act on.
|
||||
case $# in
|
||||
[01])
|
||||
print -u2 "$Usage\nUse -h for help."
|
||||
exit 1
|
||||
;;
|
||||
2)
|
||||
if $recurse; then
|
||||
print -r -u2 "$name: No directory names given with -r. Use -h for help."
|
||||
exit 1
|
||||
fi
|
||||
set -- $oldpat # Get list of all filenames that match 1st globbing pattern.
|
||||
if [[ ! -a $1 ]]; then
|
||||
$warnNoFiles && print -r -- "$name: No filenames match this pattern: $oldpat"
|
||||
exit
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
shift 2
|
||||
;;
|
||||
esac
|
||||
|
||||
integer patSegNum=1 numPatSegs
|
||||
|
||||
# For old ksh
|
||||
# while [[ "$oldpat" = *'[\*\?]'* ]]; do
|
||||
|
||||
# Example oldpat: foo*.a
|
||||
# Example newpat: bar*.b
|
||||
|
||||
# Build list of non-pattern segments and globbing segments found in arguments.
|
||||
# Note the patterns given are used to get the list of filenames to act on,
|
||||
# to delimit constant segments, and to determine which parts of filenames are
|
||||
# to be replaced.
|
||||
# Examples given for first iteration (in the example, the only iteration)
|
||||
# The || newpat is to ensure that new pattern does not have more globbing
|
||||
# segments than old pattern
|
||||
while [[ "$oldpat" = *@([\*\?]|\[+([!\]])\])* ||
|
||||
"$newpat" = *@([\*\?]|\[+([!\]])\])* ]]; do
|
||||
## Get leftmost globbing pattern in oldpat
|
||||
|
||||
# Make r be oldpat with smallest left piece that includes a globbing
|
||||
# pattern removed from it
|
||||
r=${oldpat#*@([\*\?]|\[+([!\]])\])} # r=.a
|
||||
# Make pat be oldpat with the above removed from it, leaving smallest
|
||||
# left piece that includes a globbing pattern
|
||||
pat=${oldpat%%"$r"} # pat=foo*
|
||||
# Make l be pat with the globbing pattern removed from the right,
|
||||
# leaving a constant string
|
||||
l=${pat%@([\*\?]|\[+([!\]])\])} # l=foo
|
||||
# Remove the constant part of pat from the left, leaving the globbing
|
||||
# pattern
|
||||
pat=${pat#"$l"} # pat=*
|
||||
|
||||
# Do the same thing for newpat, solely to provide a reliable test that
|
||||
# both oldpat & newpat contain exactly the same sequence of globbing
|
||||
# patterns.
|
||||
r=${newpat#*@([\*\?]|\[+([!\]])\])} # r=.b
|
||||
npat=${newpat%%"$r"} # pat=bar*
|
||||
l=${npat%@([\*\?]|\[+([!\]])\])} # l=bar
|
||||
npat=${npat#"$l"} # npat=*
|
||||
|
||||
if [[ "$pat" != "$npat" ]]; then
|
||||
print -ru2 -- \
|
||||
"$name: Old-pattern and new-pattern do not have the same sequence of globbing chars.
|
||||
Pattern segment $patSegNum: Old pattern: $pat New pattern: $npat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## Find parts before & after pattern
|
||||
# oldpre[] stores the old constant part before the pattern,
|
||||
# so that it can be removed and replaced with the new constant part.
|
||||
oldpre[patSegNum]=${oldpat%%"$pat"*} # oldpre[1]=foo
|
||||
# oldsuf stores the part that follows the globbing pattern,
|
||||
# so that it too can be removed.
|
||||
# After oldpre[] & oldsuf[] have been removed from a filename, what remains
|
||||
# is the part matched by the globbing pattern, which is to be retained.
|
||||
oldsuf[patSegNum]=${oldpat#*"$pat"} # oldsuf[1]=.a
|
||||
# newpre[] stores the new constant part before the pattern,
|
||||
# so that it can be used to replace the old constant part.
|
||||
newpre[patSegNum]=${newpat%%"$pat"*} # newpre[1]=bar
|
||||
# Get rid of processed part of patterns
|
||||
oldpat=${oldpat#${oldpre[patSegNum]}"$pat"} # oldpat=.a
|
||||
newpat=${newpat#${newpre[patSegNum]}"$pat"} # newpat=.b
|
||||
# Store either * or ? in pats[], depending on whether this segment matches 1
|
||||
# or any number of characters.
|
||||
[[ "$pat" = \[* ]] && pat=?
|
||||
pats[patSegNum]=$pat
|
||||
((patSegNum+=1))
|
||||
done
|
||||
|
||||
if [ patSegNum -eq 1 ]; then
|
||||
print -u2 "No globbing chars in pattern."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
oldpre[patSegNum]=${oldpat%%"$pat"*} # oldpre[2]=.a
|
||||
oldsuf[patSegNum]=${oldpat#*"$pat"} # oldsuf[2]=.a
|
||||
newpre[patSegNum]=${newpat%%"$pat"*} # newpre[2]=.b
|
||||
|
||||
numPatSegs=patSegNum
|
||||
|
||||
if $debug; then
|
||||
patSegNum=1
|
||||
while [[ patSegNum -le numPatSegs ]]; do
|
||||
print -ru2 -- \
|
||||
"Old prefix: <${oldpre[patSegNum]}> Old suffix: <${oldsuf[patSegNum]}> New prefix: <${newpre[patSegNum]}> Pattern: <${pats[patSegNum]}>"
|
||||
((patSegNum+=1))
|
||||
done
|
||||
fi
|
||||
|
||||
# Example filename: foox.a
|
||||
# Example oldpat: foo*.a
|
||||
# Example newpat: bar*.b
|
||||
|
||||
integer numFiles=0
|
||||
|
||||
# Usage: renameFile filename [dirname]
|
||||
# [dirname] is a directory name to prefix filenames with when they are printed
|
||||
# for informational purposes.
|
||||
# Uses globals:
|
||||
# inclCt exclCt inclPats[] exclPats[] ops[]
|
||||
# numPatSegs oldpre[] oldsuf[] newpre[] pats[]
|
||||
# check warn tell verbose name
|
||||
# Modifies globals: numFiles
|
||||
function renameFile {
|
||||
typeset file=$1 subdir=$2
|
||||
integer patSegNum patnum
|
||||
typeset origname porigname newfile matchtext pnewfile matchsegs
|
||||
integer startseg endseg
|
||||
|
||||
origname=$file # origname=foox.a
|
||||
porigname=$subdir$file
|
||||
# Unfortunately, ksh88 does not do a good job of allowing for patterns
|
||||
# stored in variables. Without the conditional expression being eval'ed,
|
||||
# only sh patterns are recognized. If the expression is eval'ed, full
|
||||
# ksh expressions can be used, but then expressions that contain whitespace
|
||||
# break unless the user passed a pattern with the whitespace properly
|
||||
# quoted, which is not intuititive. This is fixed in ksh93; full patterns
|
||||
# work without being eval'ed.
|
||||
if [ inclCt -gt 0 ]; then
|
||||
patnum=0
|
||||
while [ patnum -lt inclCt ]; do
|
||||
[[ "$file" = ${inclPats[patnum]} ]] && break
|
||||
((patnum+=1))
|
||||
done
|
||||
if [ patnum -eq inclCt ]; then
|
||||
$debug && print -ru2 -- "Skipping not-included filename '$porigname'"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
patnum=0
|
||||
while [ patnum -lt exclCt ]; do
|
||||
if [[ "$file" = ${exclPats[patnum]} ]]; then
|
||||
$debug && print -ru2 -- "Skipping excluded filename '$porigname'"
|
||||
return 1
|
||||
fi
|
||||
((patnum+=1))
|
||||
done
|
||||
# Extract matching segments from filename
|
||||
((numFiles+=1))
|
||||
patSegNum=1
|
||||
while [[ patSegNum -le numPatSegs ]]; do
|
||||
# Remove a fixed prefix iteration: 1 2
|
||||
file=${file#${oldpre[patSegNum]}} # file=x.a file=
|
||||
# Save the part of this suffix that is to be retained. To do this, we
|
||||
# need to know what part of the suffix matched the current globbing
|
||||
# segment. If the globbing segment is a *, this is done by removing
|
||||
# the minimum part of the suffix that matches oldsuf (since * matches
|
||||
# the longest segment possible). If the globbing segment is ? or []
|
||||
# (the latter has already been coverted to ?), it is done by taking the
|
||||
# next character.
|
||||
if [ "${pats[patSegNum]}" == \? ]; then
|
||||
matchtext=${file#?}
|
||||
matchtext=${file%$matchtext}
|
||||
else
|
||||
matchtext=${file%${oldsuf[patSegNum]}} # matchtext=x matchtext=
|
||||
fi
|
||||
$debug && print -ru2 -- "Matching segment $patSegNum: $matchtext"
|
||||
file=${file#$matchtext} # file=.a file=.a
|
||||
|
||||
matchsegs[patSegNum]=$matchtext
|
||||
((patSegNum+=1))
|
||||
done
|
||||
|
||||
# Paste fixed and matching segments together to form new filename.
|
||||
patSegNum=0
|
||||
newfile=
|
||||
while [[ patSegNum -le numPatSegs ]]; do
|
||||
matchtext=${matchsegs[patSegNum]}
|
||||
startseg=patSegNum
|
||||
if [ -n "${ops[startseg]}" ]; then
|
||||
endseg=${op_end_seg[startseg]}
|
||||
while [ patSegNum -lt endseg ]; do
|
||||
((patSegNum+=1))
|
||||
matchtext=$matchtext${matchsegs[patSegNum]}
|
||||
done
|
||||
if [[ "$matchtext" != +([-0-9]) ]]; then
|
||||
print -ru2 -- \
|
||||
"Segment(s) $startseg - $endseg ($matchtext) of file '$porigname' do not form an integer; skipping this file."
|
||||
return 2
|
||||
fi
|
||||
i=$matchtext
|
||||
let "j=${ops[startseg]}" || {
|
||||
print -ru2 -- \
|
||||
"Operation failed on segment(s) $startseg - $endseg ($matchtext) of file '$file'; skipping this file."
|
||||
return 2
|
||||
}
|
||||
$debug && print -ru2 -- "Converted $matchtext to $j"
|
||||
matchtext=$j
|
||||
fi
|
||||
newfile=$newfile${newpre[startseg]}$matchtext # newfile=barx newfile=barx.b
|
||||
((patSegNum+=1))
|
||||
done
|
||||
|
||||
pnewfile=$subdir$newfile
|
||||
if $check && [ -e "$newfile" ]; then
|
||||
$warn &&
|
||||
print -ru2 -- "$name: Not renaming \"$porigname\"; destination filename \"$pnewfile\" already exists."
|
||||
return 2
|
||||
fi
|
||||
if $tell; then
|
||||
print -n -r -- "Would move: $porigname -> $pnewfile"
|
||||
$warn && [ -e "$newfile" ] && print -n -r " (destination filename already exists; would replace it)"
|
||||
print ""
|
||||
else
|
||||
if $verbose; then
|
||||
print -n -r -- "Moving: $porigname -> $pnewfile"
|
||||
$warn && [ -e "$newfile" ] && print -n -r -- " (replacing old destination filename \"$pnewfile\")"
|
||||
print ""
|
||||
elif $warn && [ -e "$newfile" ]; then
|
||||
print -r -- "$name: Note: Replacing old file \"$pnewfile\""
|
||||
fi
|
||||
mv -f -- "$origname" "$newfile"
|
||||
fi
|
||||
}
|
||||
|
||||
if $recurse; then
|
||||
oPWD=$PWD
|
||||
find "$@" -depth -type d ! -name '*
|
||||
*' -print | while read dir; do
|
||||
cd -- "$oPWD"
|
||||
if cd -- "$dir"; then
|
||||
for file in $origPat; do
|
||||
renameFile "$file" "$dir/"
|
||||
done
|
||||
else
|
||||
print -ru2 -- "$name: Could not access directory '$dir' - skipped."
|
||||
fi
|
||||
done
|
||||
else
|
||||
for file; do
|
||||
renameFile "$file"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ numFiles -eq 0 ]; then
|
||||
$warnNoFiles && print -ru2 -- \
|
||||
"$name: All filenames were excluded by patterns given with -p or -P."
|
||||
fi
|
||||
@@ -1,122 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# @(#) rename.ksh 1.1 94/05/10
|
||||
# 90/06/01 John DuBois (spcecdt@armory.com)
|
||||
# 91/02/25 Improved help info
|
||||
# 92/06/07 remove quotes from around shell pattern as required by new ksh
|
||||
# 94/05/10 Exit if no globbing chars given.
|
||||
#
|
||||
# conversion to bash v2 syntax by Chet Ramey
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$usage
|
||||
All files that match oldpattern will be renamed with the
|
||||
filename components that match the constant parts of oldpattern
|
||||
changed to the corresponding constant parts of newpattern.
|
||||
The components of the filename that match variable parts of
|
||||
oldpattern will be preserved. Variable parts in oldpattern
|
||||
must occur in the same order in newpattern. Variables parts
|
||||
can be '?' and '*'.
|
||||
Example:
|
||||
rename \"/tmp/foo*.ba.?\" \"/tmp/new*x?\"
|
||||
All files in /tmp that match foo*.ba.? will have the \"foo\" part
|
||||
replaced by \"new\" and the \".ba.\" part replaced by \"x\"."
|
||||
}
|
||||
|
||||
usage="usage: $name [-htv] oldpattern newpattern"
|
||||
name=${0##/}
|
||||
|
||||
while getopts "htv" opt; do
|
||||
case "$opt" in
|
||||
t) tell=true;;
|
||||
v) verbose=true;;
|
||||
h) phelp; exit 0;;
|
||||
*) echo "$name: $usage" 1>&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
phelp
|
||||
exit 2
|
||||
fi
|
||||
|
||||
oldpat=$1
|
||||
newpat=$2
|
||||
|
||||
set -- $1
|
||||
if [ ! -e "$1" ]; then
|
||||
echo "$name: no files match $oldpat."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
typeset -i i=1 j
|
||||
|
||||
# Example oldpat: foo*.a
|
||||
# Example newpat: bar*.b
|
||||
|
||||
# Examples given for first iteration (in the example, the only interation)
|
||||
while :; do
|
||||
case "$oldpat" in
|
||||
*[\*\?]*) ;;
|
||||
*) break;;
|
||||
esac
|
||||
|
||||
# Get leftmost globbing pattern in oldpat
|
||||
pat=${oldpat#*[\*\?]} # pat=.a
|
||||
pat=${oldpat%%"$pat"} # pat=foo*
|
||||
pat=${pat##*[!\?\*]} # pat=*
|
||||
# Find parts before & after pattern
|
||||
oldpre[i]=${oldpat%%"$pat"*} # oldpre[1]=foo
|
||||
oldsuf[i]=${oldpat#*"$pat"} # oldsuf[1]=.a
|
||||
newpre[i]=${newpat%%"$pat"*} # newpre[1]=bar
|
||||
# Get rid of processed part of patterns
|
||||
oldpat=${oldpat#${oldpre[i]}"$pat"} # oldpat=.a
|
||||
newpat=${newpat#${newpre[i]}"$pat"} # newpat=.b
|
||||
let i=i+1
|
||||
done
|
||||
|
||||
if [ $i -eq 1 ]; then
|
||||
echo "No globbing chars in pattern." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
oldpre[i]=${oldpat%%"$pat"*} # oldpre[2]=.a
|
||||
oldsuf[i]=${oldpat#*"$pat"} # oldsuf[2]=.a
|
||||
newpre[i]=${newpat%%"$pat"*} # newpre[2]=.b
|
||||
|
||||
if [ -n "$verbose" ]; then
|
||||
j=1
|
||||
while let "j < i"; do
|
||||
echo \
|
||||
"Old prefix: ${oldpre[j]} Old suffix: ${oldsuf[j]} New prefix: ${newpre[j]}"
|
||||
let j=j+1
|
||||
done
|
||||
fi
|
||||
|
||||
# Example file: foox.a
|
||||
|
||||
for file; do
|
||||
j=1
|
||||
origname=$file # origname=foox.a
|
||||
newfile=
|
||||
while let "j <= i"; do
|
||||
# Peel off a prefix interation 1 2
|
||||
file=${file#${oldpre[j]}} # file=x.a file=
|
||||
# Save the part of this prefix that is to be retained
|
||||
const=${file%${oldsuf[j]}} # const=x const=
|
||||
newfile=$newfile${newpre[j]}$const # newfile=barx newfile=barx.b
|
||||
file=${file#$const} # file=.a file=.a
|
||||
let j=j+1
|
||||
done
|
||||
if [ -n "$tell" ]; then
|
||||
echo "Would move \"$origname\" to \"$newfile\"."
|
||||
else
|
||||
if [ -n "$verbose" ]; then
|
||||
echo "Moving \"$origname\" to \"$newfile\"."
|
||||
fi
|
||||
mv $origname $newfile
|
||||
fi
|
||||
done
|
||||
@@ -1,121 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# repeat: repeat a command.
|
||||
# @(#) repeat.ksh 1.1 93/06/03
|
||||
# 90/05 john h. dubois iii (john@armory.com)
|
||||
# 90/11 added help
|
||||
# 93/06/03 Added s, h, p, and v options
|
||||
#
|
||||
# conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
istrue()
|
||||
{
|
||||
test 0 -ne "$1"
|
||||
}
|
||||
|
||||
isfalse()
|
||||
{
|
||||
test 0 -eq "$1"
|
||||
}
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$name: repeatedly execute a command line.
|
||||
$Usage
|
||||
commandline is executed once for each integer from startcount through endcount
|
||||
inclusive. The default for startcount is 1 if a positive endcount or no
|
||||
endcount is given, and -1 if a negative endcount is given. A count
|
||||
parameter consisting of a single number is taken to be an endcount. If
|
||||
only an endcount is given and it is positive, commandline is executed
|
||||
endcount times. endcount may be less than startcount. If no endcount is
|
||||
given (e.g. a count parameter of \"10-\"), commandline execution repeats
|
||||
indefinitely with the iteration variable incrementing in a positive
|
||||
direction. A count parameter of consisting of \"-\" will repeat
|
||||
indefinitely starting with 1.
|
||||
|
||||
Note that quoting and variables in commandline are interpreted twice, once
|
||||
when it is passed to the repeat command, and once when it is actually executed.
|
||||
|
||||
The iteration variable is \"count\". If \$count is used in commandline, make
|
||||
sure it is quoted with ' or \.
|
||||
|
||||
Options:
|
||||
-h: Print this help.
|
||||
-p: Print value of iteration variable on stderr before each iteration.
|
||||
-s <sec>: sleep for <sec> seconds after each iteration except the last.
|
||||
-v: Print start and end values before beginning."
|
||||
}
|
||||
|
||||
name=${0##*/}
|
||||
Usage="Usage: repeat [-hpv] [-s <sec>] [[startcount]-][endcount] command [arg ...]"
|
||||
|
||||
typeset -i count=1 forever=0 sleep=0 print=0 verbose=0
|
||||
|
||||
while getopts :0123456789hpvs: opt; do
|
||||
case $opt in
|
||||
h) phelp; exit 0;;
|
||||
s) sleep=$OPTARG || exit 1;;
|
||||
p) print=1;;
|
||||
v)verbose=1;;
|
||||
[0-9]) break;;
|
||||
+?) echo "$name: options should not be preceded by a '+'." 1>&2; exit 2;;
|
||||
?) echo "$name: $OPTARG: bad option. Use -h for help." 1>&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
# remove args that were options
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo -e "$Usage\nUse -h for help." 1>&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
-[0-9]*-|[0-9]*-)
|
||||
# Start value only
|
||||
count=${1%-}
|
||||
forever=1
|
||||
end="-1";
|
||||
;;
|
||||
-[0-9]*-[0-9]*|[0-9]*-[0-9]*)
|
||||
# Start and end value
|
||||
s=${1%-}
|
||||
end=${s##[0-9]*-}
|
||||
count=${s%-$end}
|
||||
;;
|
||||
-[0-9]*|[0-9]*)
|
||||
end=$1
|
||||
case "$end" in
|
||||
-\*) count=-1;;
|
||||
esac
|
||||
;;
|
||||
-)
|
||||
forever=1
|
||||
end="-1";
|
||||
;;
|
||||
*)
|
||||
echo "$name: bad count parameter: $1" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
|
||||
[ -z "$end" ] && [ $count -le "$end" ] && increment=1 || increment=-1
|
||||
|
||||
istrue $verbose && echo "start=$count end=$end" 1>&2
|
||||
|
||||
# Need to do this here so that up to this point, -0 will keep the leading -
|
||||
# and end will not be 0 if no value assigned
|
||||
typeset -i end
|
||||
|
||||
let end+=increment # make loop inclusive of original endcount
|
||||
|
||||
while istrue $forever || [ $count -ne $end ]; do
|
||||
istrue $print && echo $count 1>&2
|
||||
eval "$@"
|
||||
istrue $sleep && sleep $sleep
|
||||
let count+=increment
|
||||
done
|
||||
@@ -1,66 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# shprof - a line profiler for shell scripts
|
||||
#
|
||||
# adapted from a similar program included in `The New KornShell' by
|
||||
# Bolsky and Korn and posted to usenet by bsh20858@challenger.fhda.edu
|
||||
#
|
||||
# converted to bash v2 syntax by Chet Ramey
|
||||
#
|
||||
TMPFILE=${TMP:-/tmp}/shprof$$
|
||||
|
||||
trap 'rm -f $TMPFILE' EXIT
|
||||
|
||||
errexit()
|
||||
{
|
||||
echo $0: "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# create script with profiling enabled
|
||||
cat > $TMPFILE <<- \_EOF_
|
||||
declare -a _line
|
||||
_profend()
|
||||
{
|
||||
case "$1" in
|
||||
/*|./*) file="$1" ;;
|
||||
*) file=$(type -path "$1") ;;
|
||||
esac
|
||||
|
||||
echo "*** line profile for $file ***"
|
||||
i=1;
|
||||
while read -r && [ $i -le $NLINE ]; do
|
||||
count=${_line[$i]}
|
||||
if [ "$count" -gt 0 ]; then
|
||||
echo "[$count] $i: $REPLY"
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done <$file
|
||||
_EOF_
|
||||
# make the profiling script remove itself after printing line stats
|
||||
echo "rm -f $TMPFILE" >> $TMPFILE
|
||||
cat >> $TMPFILE <<- \_EOF_
|
||||
}
|
||||
_command=$1
|
||||
shift
|
||||
i=1
|
||||
NLINE=$(wc -l < "$_command")
|
||||
while [ $i -le $NLINE ]; do
|
||||
_line[$i]=0
|
||||
i=$((i + 1))
|
||||
done
|
||||
unset i
|
||||
trap "_profend ${_command}" EXIT
|
||||
trap '_line[$LINENO]=$((${_line[$LINENO]} + 1))' DEBUG
|
||||
LINENO=0
|
||||
_EOF_
|
||||
|
||||
case "$1" in
|
||||
/*|./*) file=$1 ;;
|
||||
*) file=$((type -path "$1")) ;;
|
||||
esac
|
||||
|
||||
cat "${file-$1}" >> $TMPFILE || errexit "${1}: cannot open"
|
||||
chmod +x $TMPFILE
|
||||
|
||||
exec -a "$file" $TMPFILE "$@"
|
||||
@@ -1,80 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# @(#) untar.ksh 1.0 93/11/10
|
||||
# 92/10/08 john h. dubois iii (john@armory.com)
|
||||
# 92/10/31 make it actually work if archive isn't in current dir!
|
||||
# 93/11/10 Added pack and gzip archive support
|
||||
#
|
||||
# conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo \
|
||||
"$name: extract tar archives into directories, uncompressing if neccessary.
|
||||
Usage: $name archive[.tar[.[Z|gz]]] ..
|
||||
If an archive name given does not end in .tar, .tar.Z, or .tar.gz, it is
|
||||
searched for first with .tar added, then .tar.Z, and then .tar.gz added.
|
||||
The real filename must end in either .tar, .tar.Z, or .tar.gz. A
|
||||
directory with the name of the archive is created in the current directory
|
||||
(not necessarily the directory that the archive is in) if it does not
|
||||
exist, and the the contents of the archive are extracted into it.
|
||||
Absolute pathnames in tarfiles are suppressed."
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
phelp
|
||||
exit 1
|
||||
fi
|
||||
|
||||
name=${0##/}
|
||||
OWD=$PWD
|
||||
|
||||
for file; do
|
||||
cd $OWD
|
||||
case "$file" in
|
||||
*.tar.Z) ArchiveName=${file%%.tar.Z} zcat=zcat;;
|
||||
*.tar.z) ArchiveName=${file%%.tar.z} zcat=pcat;;
|
||||
*.tar.gz) ArchiveName=${file%%.tar.gz} zcat=gzcat;;
|
||||
*) ArchiveName=$file
|
||||
for ext in "" .Z .z .gz; do
|
||||
if [ -f "$file.tar$ext" ]; then
|
||||
file="$file.tar$ext"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "$file: cannot find archive." 1>&2
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if [ ! -r "$file" ]; then
|
||||
echo "$file: cannot read." >&2
|
||||
continue
|
||||
fi
|
||||
DirName=${ArchiveName##*/}
|
||||
[ -d "$DirName" ] || {
|
||||
mkdir "$DirName" || {
|
||||
echo "$DirName: could not make archive directory." 1>&2
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
cd $DirName || {
|
||||
echo "$name: cannot cd to $DirName" 1>&2
|
||||
continue
|
||||
}
|
||||
|
||||
case "$file" in
|
||||
/*) ;;
|
||||
*) file=$OWD/$file ;;
|
||||
esac
|
||||
|
||||
echo "Extracting archive $file into directory $DirName..."
|
||||
case "$file" in
|
||||
*.tar.Z|*.tar.z|*.tar.gz) $zcat $file | tar xvf -;;
|
||||
*.tar) tar xvf $file;;
|
||||
esac
|
||||
echo "Done extracting archive $file into directory $DirName."
|
||||
done
|
||||
@@ -1,45 +0,0 @@
|
||||
:
|
||||
# @(#) uudec.sh 1.0 93/11/22
|
||||
# 92/08/04 john@armory.com (John H. DuBois III)
|
||||
# 93/11/22 Added help.
|
||||
|
||||
isfalse()
|
||||
{
|
||||
test 0 -eq "$1"
|
||||
}
|
||||
|
||||
phelp()
|
||||
{
|
||||
"$name: process uuencoded files.
|
||||
Usage: uudec [-h] filename ...
|
||||
Options:
|
||||
-h: Print this help."
|
||||
}
|
||||
|
||||
name=${0##*/}
|
||||
|
||||
typeset -i force=0
|
||||
|
||||
while getopts "hf" opt; do
|
||||
case "$opt" in
|
||||
h) phelp; exit 0;;
|
||||
f) force=1;;
|
||||
*) echo "$Usage" 1>&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
for file; do
|
||||
echo "$file"
|
||||
while read b mode filename && [ "$b" != begin ]; do :; done < "$file"
|
||||
if [ "$b" = begin ]; then
|
||||
if [ -f "$filename" ] && isfalse $force; then
|
||||
echo "Output file \"$filename\" exists. Not written."
|
||||
else
|
||||
uudecode "$file"
|
||||
fi
|
||||
else
|
||||
echo "No begin line."
|
||||
fi
|
||||
done
|
||||
@@ -1,69 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# @(#) uuenc.ksh 1.0 93/09/18
|
||||
# 93/09/18 john h. dubois iii (john@armory.com)
|
||||
#
|
||||
# conversion to bash v2 syntax by Chet Ramey
|
||||
|
||||
istrue()
|
||||
{
|
||||
test 0 -ne "$1"
|
||||
}
|
||||
|
||||
isfalse()
|
||||
{
|
||||
test 0 -eq "$1"
|
||||
}
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$name: uuencode files.
|
||||
$Usage
|
||||
For each filename given, $name uuencodes the file, using the final
|
||||
component of the file's path as the stored filename in the uuencoded
|
||||
archive and, with a .${SUF} appended, as the name to store the archive in.
|
||||
Example:
|
||||
$name /tmp/foo
|
||||
The file /tmp/foo is uuencoded, with \"foo\" stored as the name to uudecode
|
||||
the file into, and the output is stored in a file in the current directory
|
||||
with the name \"foo.${SUF}\".
|
||||
Options:
|
||||
-f: Normally, if the file the output would be stored in already exists,
|
||||
it is not overwritten and an error message is printed. If -f (force)
|
||||
is given, it is silently overwritten.
|
||||
-h: Print this help."
|
||||
}
|
||||
|
||||
name=${0##*/}
|
||||
Usage="Usage: $name [-hf] <filename> ..."
|
||||
typeset -i force=0
|
||||
|
||||
SUF=uu
|
||||
|
||||
while getopts :hf opt; do
|
||||
case $opt in
|
||||
h) phelp; exit 0;;
|
||||
f) force=1;;
|
||||
+?) echo "$name: options should not be preceded by a '+'." 1>&2 ; exit 2;;
|
||||
?) echo "$name: $OPTARG: bad option. Use -h for help." 1>&2 ; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
# remove args that were options
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "$Usage\nUse -h for help." 1>&2
|
||||
exit
|
||||
fi
|
||||
|
||||
for file; do
|
||||
tail=${file##*/}
|
||||
out="$tail.${SUF}"
|
||||
if isfalse $force && [ -a "$out" ]; then
|
||||
echo "$name: $out: file exists. Use -f to overwrite." 1>&2
|
||||
else
|
||||
uuencode $file $tail > $out
|
||||
fi
|
||||
done
|
||||
@@ -1,137 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# vtree: visual directory tree
|
||||
# @(#) vtree.sh 1.1 91/07/01
|
||||
# 90/04 john h. dubois iii (john@armory.com)
|
||||
# 91/07/01 fixed bug that caused problems when dir given on command line,
|
||||
# added some info to help, changed to 4-space indenting
|
||||
#
|
||||
# conversion to bash v2 syntax done by Chet Ramey
|
||||
#
|
||||
help=\
|
||||
"Syntax: vtree [startdir] [namelen=#] [linelen=#]
|
||||
If startdir is not specified, tree will start at current dir.
|
||||
|
||||
namelen specifies the minimum number of characters of a directory name that
|
||||
are guaranteed to be printed.
|
||||
This is a tradeoff between the number of tree levels that can fit on a
|
||||
screen line and the number of chars of each dir name that can be printed.
|
||||
In most cases it will be possible to print more than namelen characters of
|
||||
the name (a name up to namelen+1 chars will always be printed in full),
|
||||
but in some cases truncation down to namelen chars will occur.
|
||||
If truncation occurs, a '>' is printed at the end of the name.
|
||||
namelen=8 (the default) typically causes about 5 dirs/1000 to be truncated.
|
||||
namelen=7 typically causes about 10 dirs/1000 to be truncated.
|
||||
namelen=8 will allow 6 full length dirs to be printed in 79 columns.
|
||||
namelen=7 will allow 7 full length dirs to be printed in 79 columns;
|
||||
|
||||
linelen specifies the maximum number of characters to print on one screen
|
||||
line. All characters beyond this are truncated. The default is 1024.
|
||||
To avoid line wrap on an 80 column terminal with autowrap, use linelen=79.
|
||||
"
|
||||
|
||||
for i in "$@"; do
|
||||
case $i in
|
||||
-h) echo "$help"; exit;;
|
||||
*=*)
|
||||
vars="$vars $i"
|
||||
;;
|
||||
*)
|
||||
if [ ! -x $i ] || [ ! -d $i ]; then # arg must be a dir and executable
|
||||
echo "$i: directory not accessible."
|
||||
exit
|
||||
fi
|
||||
cd $i
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
pwd # print path of root of tree
|
||||
|
||||
# find all directories depth first; ignore permission errors
|
||||
find . -type d -print 2> /dev/null | \
|
||||
gawk -F/ '
|
||||
|
||||
# Do this block for NR == 1 instead of BEGIN because command line var
|
||||
# assignments are not done until after BEGIN block is executed.
|
||||
NR == 1 {
|
||||
if (namelen)
|
||||
MaxLen = namelen;
|
||||
else
|
||||
MaxLen = 8;
|
||||
if (!linelen)
|
||||
linelen = 1024
|
||||
HSpace = substr(" ",1,MaxLen); # used to indent tree
|
||||
n = 0; # number of dirs found on one major branch
|
||||
}
|
||||
|
||||
$0 != "." { # do for every line produced by find except tree root dir
|
||||
if (NF == 2 && n > 0) # print major branch whenever a new one starts
|
||||
list();
|
||||
Depth[n] = NF - 1; # record depth and name of dir
|
||||
Name[n++] = $NF;
|
||||
}
|
||||
|
||||
END {
|
||||
list() # print last major branch
|
||||
}
|
||||
|
||||
function list() {
|
||||
Line = Name[0]; # initialize first line of branch to be branch base
|
||||
for (i = 1; i < n; i++) { # for each name in major branch
|
||||
if (Depth[i] == Depth[i-1] + 1)
|
||||
AddHLink(); # if moving deeper into branch, use same line
|
||||
else {
|
||||
print substr(Line,1,linelen); # last line is done; print it
|
||||
Line = ""; # start new line
|
||||
# print indentation, vert links, and vert/horiz links
|
||||
for (d = 1; d < Depth[i] - 1; d++) # for each level of indentation
|
||||
# if a vert. link has been established for this level
|
||||
if (VLink[d])
|
||||
Line = Line HSpace " | ";
|
||||
else # print empty indentation
|
||||
Line = Line HSpace " ";
|
||||
# Print last part of vert. link
|
||||
if (VLink[d] == i) {
|
||||
VLink[d] = 0; # mark level for no vert link
|
||||
Line = Line HSpace " \\--";
|
||||
}
|
||||
else
|
||||
Line = Line HSpace " |--";
|
||||
}
|
||||
Line = Line Name[i]; # Add dir name to line
|
||||
}
|
||||
print substr(Line,1,linelen); # print last line of major branch
|
||||
n = 0; # reset name counter
|
||||
}
|
||||
|
||||
function AddHLink() {
|
||||
NDepth = Depth[i]; # Depth of this name
|
||||
VLink[NDepth - 1] = 0;
|
||||
# search until a name found at a level less than this one
|
||||
for (j = i + 1; j < n && Depth[j] >= NDepth; j++)
|
||||
# keep track of last name that VLink should connect to
|
||||
if (Depth[j] == NDepth)
|
||||
VLink[NDepth - 1] = j;
|
||||
if (VLink[NDepth - 1]) {
|
||||
NLine = substr(Line,1,(NDepth - 2) * (MaxLen + 4) + MaxLen + 1);
|
||||
if (length(NLine) < length(Line))
|
||||
Line = substr(NLine,1,length(NLine) - 1) ">"
|
||||
else
|
||||
Line = NLine;
|
||||
Line = Line substr("--------------+--",
|
||||
18 - ((NDepth - 1) * (MaxLen + 4) - length(Line)));
|
||||
}
|
||||
else {
|
||||
NLine = substr(Line,1,(NDepth - 2) * (MaxLen + 4) + MaxLen + 3);
|
||||
if (length(NLine) < length(Line))
|
||||
Line = substr(NLine,1,length(NLine) - 1) ">"
|
||||
else
|
||||
Line = NLine;
|
||||
Line = Line substr("-----------------",
|
||||
1,(NDepth - 1) * (MaxLen + 4) - length(Line));
|
||||
}
|
||||
}
|
||||
' $vars
|
||||
@@ -1,111 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# original from:
|
||||
# @(#) where.ksh 1.1 94/07/11
|
||||
# 91/01/12 john h. dubois iii (john@armory.com)
|
||||
# 92/08/10 Only print executable *files*.
|
||||
# 92/10/06 Print err msg if no match found.
|
||||
# 92/11/27 Added implicit *
|
||||
# 93/07/23 Print help only if -h is given.
|
||||
# 94/01/01 Added -x option
|
||||
# 94/07/11 Don't bother with eval
|
||||
#
|
||||
# conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
name=${0##*/}
|
||||
Usage="Usage: $name [-hx] 'pattern' ..."
|
||||
typeset -i exact=0
|
||||
|
||||
phelp()
|
||||
{
|
||||
echo "$name: find executable files in PATH that match patterns.
|
||||
$Usage
|
||||
$name searches each directory specified in the PATH environment variable
|
||||
for executable files that match the specified patterns. Patterns are
|
||||
given as Korn shell filename patterns. They are surrounded by implicit
|
||||
'*' characters, so that \"foo\" will match any executble file whose name
|
||||
contains contains \"foo\". This can be overridden by using '^' and '$' to
|
||||
force a match to start at the beginning and end at the end of a filename
|
||||
respectively. Characters that are special to the shell must generally
|
||||
be protected from the shell by surrounding them with quotes.
|
||||
Examples:
|
||||
$name foo
|
||||
lists all executable files in PATH that contain foo.
|
||||
$name '^b*sh$'
|
||||
lists all executable files in PATH that start with b and end with sh.
|
||||
An error message is printed if a no matching file is found for a pattern.
|
||||
Options:
|
||||
-h: Print this help.
|
||||
-x: Find exact matches only; equivalent to putting ^ and $ at the start
|
||||
and end of each pattern."
|
||||
}
|
||||
|
||||
istrue()
|
||||
{
|
||||
test 0 -ne "$1"
|
||||
}
|
||||
|
||||
isfalse()
|
||||
{
|
||||
test 0 -eq "$1"
|
||||
}
|
||||
|
||||
while getopts "xh" opt; do
|
||||
case "$opt" in
|
||||
x) exact=1;;
|
||||
h) phelp ; exit 0;;
|
||||
*) echo -e "$Usage\nUse -h for help." 1>&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND-1))
|
||||
|
||||
set +f # make sure filename globbing is on
|
||||
Args=("$@") # save args
|
||||
|
||||
OIFS=$IFS
|
||||
IFS=: # Make PATH be split on :
|
||||
Paths=($PATH)
|
||||
IFS=$OIFS
|
||||
|
||||
for arg in "${Args[@]}"; do
|
||||
|
||||
# get rid of leading ^
|
||||
if istrue $exact; then
|
||||
arg=${arg}
|
||||
else
|
||||
case "$arg" in
|
||||
^*) arg=${arg#?};;
|
||||
*) arg="*$arg" ;; # Pattern is not anchored at start
|
||||
esac
|
||||
fi
|
||||
|
||||
# get rid of trailing $
|
||||
if istrue $exact; then
|
||||
arg="$arg"
|
||||
else
|
||||
case "$arg" in
|
||||
*\$) arg=${arg%?} ;;
|
||||
*) arg="$arg*" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
found=0 # Pattern not found yet
|
||||
Patterns=
|
||||
# Make a pattern for each element of PATH
|
||||
for PathElem in "${Paths[@]}"; do
|
||||
[ -z "$PathElem" ] && PathElem=.
|
||||
Patterns="$Patterns $PathElem/$arg"
|
||||
done
|
||||
|
||||
# Find all pattern matches that are executable regular files.
|
||||
for file in $Patterns; do
|
||||
if [ -x "$file" ] && [ -f "$file" ]; then
|
||||
echo "$file"
|
||||
found=1
|
||||
fi
|
||||
done
|
||||
if [ $found = 0 ]; then
|
||||
echo "$arg: not found." 1>&2
|
||||
fi
|
||||
done
|
||||
@@ -1,553 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ash -- "Adventure shell"
|
||||
# last edit: 86/04/21 D A Gwyn
|
||||
# SCCS ID: @(#)ash.sh 1.4
|
||||
|
||||
OPATH=$PATH
|
||||
|
||||
ask()
|
||||
{
|
||||
echo -n "$@" '[y/n] '
|
||||
read ans
|
||||
|
||||
case "$ans" in
|
||||
y*|Y*)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
CAT=${PAGER:-more}
|
||||
|
||||
ash_inst()
|
||||
{
|
||||
cat <<- EOF
|
||||
|
||||
Instructions for the Adventure shell
|
||||
|
||||
Welcome to the Adventure shell! In this exploration of the UNIX file
|
||||
system, I will act as your eyes and hands. As you move around, I will
|
||||
describe whatever is visible and will carry out your commands. The
|
||||
general form of a command is
|
||||
Verb Object Extra_stuff.
|
||||
Most commands pay no attention to the "Extra_stuff", and many do not
|
||||
need an "Object". A typical command is
|
||||
get all
|
||||
which picks up all files in the current "room" (directory). You can
|
||||
find out what you are carrying by typing the command
|
||||
inventory
|
||||
The command "help" results in a full description of all commands that I
|
||||
understand. To quit the Adventure shell, type
|
||||
quit
|
||||
|
||||
There are UNIX monsters lurking in the background. These are also
|
||||
known as "commands with arguments".
|
||||
|
||||
Good luck!
|
||||
EOF
|
||||
}
|
||||
|
||||
ash_help()
|
||||
{
|
||||
echo "I understand the following commands (synonyms in parentheses):"
|
||||
echo ""
|
||||
|
||||
echo "change OBJECT to NEW_NAME changes the name of the object"
|
||||
echo "clone OBJECT as NEW_NAME duplicates the object"
|
||||
echo "drop OBJECTS leaves the objects in the room"
|
||||
echo "enter (go) PASSAGE takes the labeled passage"
|
||||
echo "examine OBJECTS describes the objects in detail"
|
||||
echo "feed OBJECT to MONSTER stuffs the object into a UNIX monster"
|
||||
echo "get (take) OBJECTS picks up the specified objects"
|
||||
echo "gripe (bug) report a problem with the Adventure shell"
|
||||
echo "help prints this summary"
|
||||
echo "inventory (i) tells what you are carrying"
|
||||
echo "kill (destroy) OBJECTS destroys the objects"
|
||||
echo "look (l) describes the room, including hidden objects"
|
||||
echo "open (read) OBJECT shows the contents of an object"
|
||||
echo "quit (exit) leaves the Adventure shell"
|
||||
echo "resurrect OBJECTS attempts to restore dead objects"
|
||||
echo "steal OBJECT from MONSTER obtains the object from a UNIX monster"
|
||||
echo "throw OBJECT at daemon feeds the object to the printer daemon"
|
||||
echo "up takes the overhead passage"
|
||||
echo "wake MONSTER awakens a UNIX monster"
|
||||
echo "where (w) tells you where you are"
|
||||
echo "xyzzy moves you to your home"
|
||||
}
|
||||
|
||||
MAINT=chet@ins.cwru.edu
|
||||
|
||||
PATH=/usr/ucb:/bin:/usr/bin:/usr/local/bin:.
|
||||
export PATH
|
||||
|
||||
trap 'echo Ouch!' 2 3
|
||||
#trap '' 18 # disable Berkeley job control
|
||||
|
||||
#ash_lk(){ echo " $1 " | fgrep " $2 " >&- 2>&-; }
|
||||
ash_lk(){ echo " $1 " | fgrep -q " $2 " >/dev/null 2>&1 ; }
|
||||
ash_pr(){ echo $* | tr ' ' '\012' | pr -5 -t -w75 -l$(( ( $# + 4 ) / 5 )); }
|
||||
ash_rm(){ echo " $1 " | sed -e "s/ $2 / /" -e 's/^ //' -e 's/ $//'; }
|
||||
|
||||
# enable history, bang history expansion, and emacs editing
|
||||
set -o history
|
||||
set -o histexpand
|
||||
set -o emacs
|
||||
|
||||
cd
|
||||
LIM=.limbo # $HOME/$LIM contains "destroyed" objects
|
||||
mkdir $LIM || {
|
||||
echo "ash: cannot mkdir $LIM: exiting"
|
||||
exit 1
|
||||
}
|
||||
KNAP=.knapsack # $HOME/$KNAP contains objects being "carried"
|
||||
if [ ! -d $KNAP ]
|
||||
then mkdir $KNAP >/dev/null 2>&1
|
||||
if [ $? = 0 ]
|
||||
then echo 'You found a discarded empty knapsack.'
|
||||
else echo 'You have no knapsack to carry things in.'
|
||||
exit 1
|
||||
fi
|
||||
else echo 'One moment while I peek in your old knapsack...'
|
||||
fi
|
||||
|
||||
kn=`echo \`ls -a $KNAP | sed -e '/^\.$/d' -e '/^\.\.$/d'\``
|
||||
|
||||
if ask 'Welcome to the Adventure shell! Do you need instructions?'
|
||||
then
|
||||
ash_inst
|
||||
echo -n 'Type a newline to continue: '
|
||||
read
|
||||
fi
|
||||
|
||||
wiz=false
|
||||
cha=false
|
||||
prev=$LIM
|
||||
while :
|
||||
do room=`pwd`
|
||||
if [ $room != $prev ]
|
||||
then if [ $room = $HOME ]
|
||||
then echo 'You are in your own home.'
|
||||
else echo "You have entered $room."
|
||||
fi
|
||||
exs=
|
||||
obs=
|
||||
hexs=
|
||||
hobs=
|
||||
f=false
|
||||
for i in `ls -a`
|
||||
do case $i in
|
||||
.|..) ;;
|
||||
.*) if [ -f $i ]
|
||||
then hobs="$hobs $i"
|
||||
elif [ -d $i ]
|
||||
then hexs="$hexs $i"
|
||||
else f=true
|
||||
fi
|
||||
;;
|
||||
*) if [ -f $i ]
|
||||
then obs="$obs $i"
|
||||
elif [ -d $i ]
|
||||
then exs="$exs $i"
|
||||
else f=true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [ "$obs" ]
|
||||
then echo 'This room contains:'
|
||||
ash_pr $obs
|
||||
else echo 'The room looks empty.'
|
||||
fi
|
||||
if [ "$exs" ]
|
||||
then echo 'There are exits labeled:'
|
||||
ash_pr $exs
|
||||
echo 'as well as a passage overhead.'
|
||||
else echo 'There is a passage overhead.'
|
||||
fi
|
||||
if sh -c $f
|
||||
then echo 'There are shadowy figures in the corner.'
|
||||
fi
|
||||
prev=$room
|
||||
fi
|
||||
|
||||
read -e -p '-advsh> ' verb obj x # prompt is '-advsh> '
|
||||
if [ $? != 0 ]
|
||||
then verb=quit # EOF
|
||||
fi
|
||||
|
||||
case $verb in
|
||||
change) if [ "$obj" ]
|
||||
then if ash_lk "$obs $hobs" "$obj"
|
||||
then set -- $x
|
||||
case "$1" in
|
||||
to) if [ "$2" ]
|
||||
then if [ -f $2 ]
|
||||
then echo "You must destroy $2 first."
|
||||
set --
|
||||
fi
|
||||
if [ "$2" ]
|
||||
then if mv $obj $2 # >&- 2>&-
|
||||
then echo "The $obj shimmers and turns into $2."
|
||||
obs=`ash_rm "$2 $obs" "$obj"`
|
||||
else echo "There is a cloud of smoke but the $obj is unchanged."
|
||||
fi
|
||||
fi
|
||||
else echo 'To what?'
|
||||
fi
|
||||
;;
|
||||
*) echo "Change $obj to what?"
|
||||
;;
|
||||
esac
|
||||
else if ash_lk "$kn" "$obj"
|
||||
then echo 'You must drop it first.'
|
||||
else echo "I see no $obj here."
|
||||
fi
|
||||
fi
|
||||
else echo 'Change what?'
|
||||
fi
|
||||
;;
|
||||
clone) if [ "$obj" ]
|
||||
then if ash_lk "$obs $hobs" "$obj"
|
||||
then if [ ! -r $obj ]
|
||||
then echo "The $obj does not wish to be cloned."
|
||||
else set -- $x
|
||||
case "$1" in
|
||||
as) if [ "$2" ]
|
||||
then if [ -f $2 ]
|
||||
then echo "You must destroy $2 first."
|
||||
else if cp $obj $2 # >&- 2>&-
|
||||
then echo "Poof! When the smoke clears, you see the new $2."
|
||||
obs="$obs $2"
|
||||
else echo 'You hear a dull thud but no clone appears.'
|
||||
fi
|
||||
fi
|
||||
else echo 'As what?'
|
||||
fi
|
||||
;;
|
||||
*) echo "Clone $obj as what?"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
else if ash_lk "$kn" "$obj"
|
||||
then echo 'You must drop it first.'
|
||||
else echo "I see no $obj here."
|
||||
fi
|
||||
fi
|
||||
else echo 'Clone what?'
|
||||
fi
|
||||
;;
|
||||
drop) if [ "$obj" ]
|
||||
then for it in $obj $x
|
||||
do if ash_lk "$kn" "$it"
|
||||
then if [ -w $it ]
|
||||
then echo "You must destroy $it first."
|
||||
else if mv $HOME/$KNAP/$it $it # >&- 2>&-
|
||||
then echo "$it: dropped."
|
||||
kn=`ash_rm "$kn" "$it"`
|
||||
obs=`echo $it $obs`
|
||||
else echo "The $it is caught in your knapsack."
|
||||
fi
|
||||
fi
|
||||
else echo "You're not carrying the $it!"
|
||||
fi
|
||||
done
|
||||
else echo 'Drop what?'
|
||||
fi
|
||||
;;
|
||||
enter|go) if [ "$obj" ]
|
||||
then if [ $obj != up ]
|
||||
then if ash_lk "$exs $hexs" "$obj"
|
||||
then if [ -x $obj ]
|
||||
then if cd $obj
|
||||
then echo 'You squeeze through the passage.'
|
||||
else echo "You can't go that direction."
|
||||
fi
|
||||
else echo 'An invisible force blocks your way.'
|
||||
fi
|
||||
else echo 'I see no such passage.'
|
||||
fi
|
||||
else if cd ..
|
||||
then echo 'You struggle upwards.'
|
||||
else echo "You can't reach that high."
|
||||
fi
|
||||
fi
|
||||
else echo 'Which passage?'
|
||||
fi
|
||||
;;
|
||||
examine) if [ "$obj" ]
|
||||
then if [ $obj = all ]
|
||||
then $obj=`echo $obs $exs`
|
||||
x=
|
||||
fi
|
||||
for it in $obj $x
|
||||
do if ash_lk "$obs $hobs $exs $hexs" "$it"
|
||||
then echo "Upon close inspection of the $it, you see:"
|
||||
ls -ld $it 2>/dev/null
|
||||
if [ $? != 0 ]
|
||||
then echo "-- when you look directly at the $it, it vanishes."
|
||||
fi
|
||||
else if ash_lk "$kn" "$it"
|
||||
then echo 'You must drop it first.'
|
||||
else echo "I see no $it here."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else echo 'Examine what?'
|
||||
fi
|
||||
;;
|
||||
feed) if [ "$obj" ]
|
||||
then if ash_lk "$obs $hobs" "$obj"
|
||||
then set -- $x
|
||||
case "$1" in
|
||||
to) if [ "$2" ]
|
||||
then shift
|
||||
if PATH=$OPATH $* <$obj 2>/dev/null
|
||||
then echo "The $1 monster devours your $obj."
|
||||
if rm -f $obj # >&- 2>&-
|
||||
then obs=`ash_rm "$obs" "$obj"`
|
||||
else echo 'But he spits it back up.'
|
||||
fi
|
||||
else echo "The $1 monster holds his nose in disdain."
|
||||
fi
|
||||
else echo 'To what?'
|
||||
fi
|
||||
;;
|
||||
*) echo "Feed $obj to what?"
|
||||
;;
|
||||
esac
|
||||
else if ash_lk "$kn" "$obj"
|
||||
then echo 'You must drop it first.'
|
||||
else echo "I see no $obj here."
|
||||
fi
|
||||
fi
|
||||
else echo 'Feed what?'
|
||||
fi
|
||||
;;
|
||||
get|take) if [ "$obj" ]
|
||||
then if [ $obj = all ]
|
||||
then obj="$obs"
|
||||
x=
|
||||
fi
|
||||
for it in $obj $x
|
||||
do if ash_lk "$obs $hobs" "$it"
|
||||
then if ash_lk "$kn" "$it"
|
||||
then echo 'You already have one.'
|
||||
else if mv $it $HOME/$KNAP/$it # >&- 2>&-
|
||||
then echo "$it: taken."
|
||||
kn="$it $kn"
|
||||
obs=`ash_rm "$obs" "$it"`
|
||||
else echo "The $it is too heavy."
|
||||
fi
|
||||
fi
|
||||
else echo "I see no $it here."
|
||||
fi
|
||||
done
|
||||
else echo 'Get what?'
|
||||
fi
|
||||
;;
|
||||
gripe|bug) echo 'Please describe the problem and your situation at the time it failed.\nEnd the bug report with a line containing just a Ctrl-D.'
|
||||
cat | mail $MAINT -s 'ash bug'
|
||||
echo 'Thank you!'
|
||||
;;
|
||||
help) ash_help
|
||||
;;
|
||||
inventory|i) if [ "$kn" ]
|
||||
then echo 'Your knapsack contains:'
|
||||
ash_pr $kn
|
||||
else echo 'You are poverty-stricken.'
|
||||
fi
|
||||
;;
|
||||
kill|destroy) if [ "$obj" ]
|
||||
then if [ $obj = all ]
|
||||
then x=
|
||||
if ask "Do you really want to attempt to $verb them all?"
|
||||
then obj=`echo $obs`
|
||||
else echo 'Chicken!'
|
||||
obj=
|
||||
fi
|
||||
fi
|
||||
for it in $obj $x
|
||||
do if ash_lk "$obs $hobs" "$it"
|
||||
then if mv $it $HOME/$LIM # <&- >&- 2>&-
|
||||
then if [ $verb = kill ]
|
||||
then echo "The $it cannot defend himself; he dies."
|
||||
else echo "You have destroyed the $it; it vanishes."
|
||||
fi
|
||||
obs=`ash_rm "$obs" "$it"`
|
||||
else if [ $verb = kill ]
|
||||
then echo "Your feeble blows are no match for the $it."
|
||||
else echo "The $it is indestructible."
|
||||
fi
|
||||
fi
|
||||
else if ash_lk "$kn" "$it"
|
||||
then echo "You must drop the $it first."
|
||||
found=false
|
||||
else echo "I see no $it here."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else echo 'Kill what?'
|
||||
fi
|
||||
;;
|
||||
look|l) obs=`echo $obs $hobs`
|
||||
hobs=
|
||||
if [ "$obs" ]
|
||||
then echo 'The room contains:'
|
||||
ash_pr $obs
|
||||
else echo 'The room is empty.'
|
||||
fi
|
||||
exs=`echo $exs $hexs`
|
||||
hexs=
|
||||
if [ "$exs" ]
|
||||
then echo 'There are exits plainly labeled:'
|
||||
ash_pr $exs
|
||||
echo 'and a passage directly overhead.'
|
||||
else echo 'The only exit is directly overhead.'
|
||||
fi
|
||||
;;
|
||||
magic) if [ "$obj" = mode ]
|
||||
then if sh -c $cha
|
||||
then echo 'You had your chance and you blew it.'
|
||||
else if ask 'Are you a wizard?'
|
||||
then echo -n 'Prove it! Say the magic word: '
|
||||
read obj
|
||||
if [ "$obj" = armadillo ]
|
||||
then echo 'Yes, master!!'
|
||||
wiz=true
|
||||
else echo "Homie says: I don't think so"
|
||||
cha=true
|
||||
fi
|
||||
else echo "I didn't think so."
|
||||
fi
|
||||
fi
|
||||
else echo 'Nice try.'
|
||||
fi
|
||||
;;
|
||||
open|read) if [ "$obj" ]
|
||||
then if ash_lk "$obs $hobs" "$obj"
|
||||
then if [ -r $obj ]
|
||||
then if [ -s $obj ]
|
||||
then echo "Opening the $obj reveals:"
|
||||
$CAT < $obj
|
||||
if [ $? != 0 ]
|
||||
then echo '-- oops, you lost the contents!'
|
||||
fi
|
||||
else echo "There is nothing inside the $obj."
|
||||
fi
|
||||
else echo "You do not have the proper tools to open the $obj."
|
||||
fi
|
||||
else if ash_lk "$kn" "$obj"
|
||||
then echo 'You must drop it first.'
|
||||
found=false
|
||||
else echo "I see no $obj here."
|
||||
fi
|
||||
fi
|
||||
else echo 'Open what?'
|
||||
fi
|
||||
;;
|
||||
quit|exit) if ask 'Do you really want to quit now?'
|
||||
then if [ "$kn" ]
|
||||
then echo 'The contents of your knapsack will still be there next time.'
|
||||
fi
|
||||
rm -rf $HOME/$LIM
|
||||
echo 'See you later!'
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
resurrect) if [ "$obj" ]
|
||||
then for it in $obj $x
|
||||
do if ash_lk "$obs $hobs" "$it"
|
||||
then echo "The $it is already alive and well."
|
||||
else if mv $HOME/$LIM/$it $it # <&- >&- 2>&-
|
||||
then echo "The $it staggers to his feet."
|
||||
obs=`echo $it $obs`
|
||||
else echo "There are sparks but no $it appears."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else echo 'Resurrect what?'
|
||||
fi
|
||||
;;
|
||||
steal) if [ "$obj" ]
|
||||
then if ash_lk "$obs $hobs" "$obj"
|
||||
then echo 'There is already one here.'
|
||||
else set -- $x
|
||||
case "$1" in
|
||||
from) if [ "$2" ]
|
||||
then shift
|
||||
if PATH=$OPATH $* >$obj 2>/dev/null
|
||||
then echo "The $1 monster drops the $obj."
|
||||
obs=`echo $obj $obs`
|
||||
else echo "The $1 monster runs away as you approach."
|
||||
rm -f $obj # >&- 2>&-
|
||||
fi
|
||||
else echo 'From what?'
|
||||
fi
|
||||
;;
|
||||
*) echo "Steal $obj from what?"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
else echo 'Steal what?'
|
||||
fi
|
||||
;;
|
||||
throw) if [ "$obj" ]
|
||||
then if ash_lk "$obs $hobs" "$obj"
|
||||
then set -- $x
|
||||
case "$1" in
|
||||
at) case "$2" in
|
||||
daemon) if sh -c "lpr -r $obj"
|
||||
then echo "The daemon catches the $obj, turns it into paper,\nand leaves it in the basket."
|
||||
obs=`ash_rm "$obs" "$obj"`
|
||||
else echo "The daemon is nowhere to be found."
|
||||
fi
|
||||
;;
|
||||
*) echo 'At what?'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*) echo "Throw $obj at what?"
|
||||
;;
|
||||
esac
|
||||
else if ash_lk "$kn" "$obj"
|
||||
then echo 'It is in your knapsack.'
|
||||
found=false
|
||||
else echo "I see no $obj here."
|
||||
fi
|
||||
fi
|
||||
else echo 'Throw what?'
|
||||
fi
|
||||
;;
|
||||
u|up) if cd ..
|
||||
then echo 'You pull yourself up a level.'
|
||||
else echo "You can't reach that high."
|
||||
fi
|
||||
;;
|
||||
wake) if [ "$obj" ]
|
||||
then echo "You awaken the $obj monster:"
|
||||
PATH=$OPATH $obj $x
|
||||
echo 'The monster slithers back into the darkness.'
|
||||
else echo 'Wake what?'
|
||||
fi
|
||||
;;
|
||||
w|where) echo "You are in $room."
|
||||
;;
|
||||
xyzzy) if cd
|
||||
then echo 'A strange feeling comes over you.'
|
||||
else echo 'Your spell fizzles out.'
|
||||
fi
|
||||
;;
|
||||
*) if [ "$verb" ]
|
||||
then if sh -c $wiz
|
||||
then PATH=$OPATH $verb $obj $x
|
||||
else echo "I don't know how to \"$verb\"."
|
||||
echo 'Type "help" for assistance.'
|
||||
fi
|
||||
else echo 'Say something!'
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -1,67 +0,0 @@
|
||||
#From: "dennis" <dennis@netstrata.com>
|
||||
#To: <bash-maintainers@gnu.org>
|
||||
#Subject: New example script: bash-hexdump
|
||||
#Date: Mon, 4 Jan 2010 22:48:19 -0700
|
||||
#Message-ID: <6dbec42d$64fcdbd2$4a32cf2d$@com>
|
||||
|
||||
#I've written a script that functions like "hexdump -C" or "hd". If you'd
|
||||
#like to include it in a future distribution of example Bash scripts, I have
|
||||
#included it here:
|
||||
|
||||
#!/bin/bash
|
||||
# bash-hexdump# pure Bash, no externals
|
||||
# by Dennis Williamson - 2010-01-04
|
||||
# in response to
|
||||
http://stackoverflow.com/questions/2003803/show-hexadecimal-numbers-of-a-file
|
||||
# usage: bash-hexdump file
|
||||
saveIFS="$IFS"
|
||||
IFS="" # disables interpretation of \t, \n and space
|
||||
saveLANG="$LANG"
|
||||
LANG=C # allows characters > 0x7F
|
||||
bytecount=0
|
||||
valcount=0
|
||||
printf "%08x " $bytecount
|
||||
while read -d '' -r -n 1 char # -d '' allows newlines, -r allows \
|
||||
do
|
||||
((bytecount++))
|
||||
# for information about the apostrophe in this printf command, see
|
||||
# http://www.opengroup.org/onlinepubs/009695399/utilities/printf.html
|
||||
printf -v val "%02x" "'$char"
|
||||
echo -n "$val "
|
||||
((valcount++))
|
||||
if [[ "$val" < 20 || "$val" > 7e ]]
|
||||
then
|
||||
string+="." # show unprintable characters as a dot
|
||||
else
|
||||
string+=$char
|
||||
fi
|
||||
if (( bytecount % 8 == 0 )) # add a space down the middle
|
||||
then
|
||||
echo -n " "
|
||||
fi
|
||||
if (( bytecount % 16 == 0 )) # print 16 values per line
|
||||
then
|
||||
echo "|$string|"
|
||||
string=''
|
||||
valcount=0
|
||||
printf "%08x " $bytecount
|
||||
fi
|
||||
done < "$1"
|
||||
|
||||
if [[ "$string" != "" ]] # if the last line wasn't full, pad it out
|
||||
then
|
||||
length=${#string}
|
||||
if (( length > 7 ))
|
||||
then
|
||||
((length--))
|
||||
fi
|
||||
(( length += (16 - valcount) * 3 + 4))
|
||||
printf "%${length}s\n" "|$string|"
|
||||
printf "%08x " $bytecount
|
||||
fi
|
||||
echo
|
||||
|
||||
LANG="$saveLANG";
|
||||
IFS="$saveIFS"
|
||||
|
||||
exit 0
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,476 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# this is a line editor using only /bin/sh, /bin/dd and /bin/rm
|
||||
|
||||
# /bin/rm is not really required, but it is nice to clean up temporary files
|
||||
|
||||
PATH=
|
||||
dd=/bin/dd
|
||||
rm=/bin/rm
|
||||
|
||||
# temporary files we might need
|
||||
tmp=/tmp/silly.$$
|
||||
ed=/tmp/ed.$$
|
||||
trap "$rm -f $tmp $tmp.1 $tmp.2 $tmp.3 $tmp.4 $tmp.5 $tmp.6 $ed.a $ed.b $ed.c; exit" 0 1 2 3
|
||||
|
||||
# from now on, no more rm - the above trap is enough
|
||||
unset rm
|
||||
|
||||
# we do interesting things with IFS, but better save it...
|
||||
saveIFS="$IFS"
|
||||
|
||||
# in case "echo" is not a shell builtin...
|
||||
|
||||
Echo () {
|
||||
case "$1" in
|
||||
-n) shift
|
||||
$dd of=$tmp 2>/dev/null <<EOF
|
||||
$@
|
||||
EOF
|
||||
IFS="+"
|
||||
set `$dd if=$tmp bs=1 of=/dev/null skip=1 2>&1`
|
||||
IFS="$saveIFS"
|
||||
$dd if=$tmp bs=1 count=$1 2>/dev/null
|
||||
;;
|
||||
*) $dd 2>/dev/null <<EOF
|
||||
$@
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# this is used to generate garbage files
|
||||
|
||||
true () {
|
||||
return 0
|
||||
}
|
||||
|
||||
false () {
|
||||
return 1
|
||||
}
|
||||
|
||||
zero () {
|
||||
( trap 'go=false' 13
|
||||
go=true
|
||||
while $go
|
||||
do
|
||||
$dd "if=$0"
|
||||
case "$?" in
|
||||
0) ;;
|
||||
*) go=false ;;
|
||||
esac
|
||||
done
|
||||
) 2>/dev/null
|
||||
}
|
||||
|
||||
# arithmetic using dd!
|
||||
|
||||
# add variable n1 n2 n3...
|
||||
# assigns n1+n2+n3+... to variable
|
||||
|
||||
add () {
|
||||
result="$1"
|
||||
shift
|
||||
$dd if=/dev/null of=$tmp bs=1 2>/dev/null
|
||||
for n in "$@"
|
||||
do
|
||||
case "$n" in
|
||||
0) ;;
|
||||
*) zero | $dd of=$tmp.1 bs=1 "count=$n" 2>/dev/null
|
||||
( $dd if=$tmp; $dd if=$tmp.1 ) 2>/dev/null | $dd of=$tmp.2 2>/dev/null
|
||||
$dd if=$tmp.2 of=$tmp 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
done
|
||||
IFS="+"
|
||||
set `$dd if=$tmp bs=1 of=/dev/null 2>&1`
|
||||
IFS="$saveIFS"
|
||||
eval $result='$1'
|
||||
}
|
||||
|
||||
# subtract variable n1 n2
|
||||
# subtracts n2 from n1, assigns result to variable
|
||||
|
||||
subtract () {
|
||||
result="$1"
|
||||
zero | $dd of=$tmp bs=1 "count=$2" 2>/dev/null
|
||||
IFS="+"
|
||||
set `$dd if=$tmp bs=1 of=/dev/null "skip=$3" 2>&1`
|
||||
IFS="$saveIFS"
|
||||
case "$1" in
|
||||
dd*) set 0 ;;
|
||||
esac
|
||||
eval $result='$1'
|
||||
}
|
||||
|
||||
# multiply variable n1 n2
|
||||
# variable = n1 * n2
|
||||
|
||||
multiply () {
|
||||
result="$1"
|
||||
zero | $dd "bs=$2" of=$tmp "count=$3" 2>/dev/null
|
||||
IFS="+"
|
||||
set `$dd if=$tmp bs=1 of=/dev/null 2>&1`
|
||||
IFS="$saveIFS"
|
||||
eval $result='$1'
|
||||
}
|
||||
|
||||
# divide variable n1 n2
|
||||
# variable = int( n1 / n2 )
|
||||
|
||||
divide () {
|
||||
result="$1"
|
||||
zero | $dd bs=1 of=$tmp "count=$2" 2>/dev/null
|
||||
IFS="+"
|
||||
set `$dd if=$tmp "bs=$3" of=/dev/null 2>&1`
|
||||
IFS="$saveIFS"
|
||||
eval $result='$1'
|
||||
}
|
||||
|
||||
# compare variable n1 n2 sets variable to lt if n1<n2, gt if n1>n2, eq if n1==n2
|
||||
|
||||
compare () {
|
||||
res="$1"
|
||||
n1="$2"
|
||||
n2="$3"
|
||||
subtract somename "$n1" "$n2"
|
||||
case "$somename" in
|
||||
0) ;;
|
||||
*) eval $res=gt; return;
|
||||
esac
|
||||
subtract somename "$n2" "$n1"
|
||||
case "$somename" in
|
||||
0) ;;
|
||||
*) eval $res=lt; return;
|
||||
esac
|
||||
eval $res=eq
|
||||
}
|
||||
|
||||
# lt n1 n2 returns true if n1 < n2
|
||||
|
||||
lt () {
|
||||
n1="$1"
|
||||
n2="$2"
|
||||
subtract somename "$n2" "$n1"
|
||||
case "$somename" in
|
||||
0) return 1 ;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
# le n1 n2 returns true if n1 <= n2
|
||||
|
||||
le () {
|
||||
n1="$1"
|
||||
n2="$2"
|
||||
subtract somename "$n1" "$n2"
|
||||
case "$somename" in
|
||||
0) return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
# gt n1 n2 returns true if n1 > n2
|
||||
|
||||
gt () {
|
||||
n1="$1"
|
||||
n2="$2"
|
||||
subtract somename "$n1" "$n2"
|
||||
case "$somename" in
|
||||
0) return 1 ;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
# ge n1 n2 returns true if n1 >= n2
|
||||
|
||||
ge () {
|
||||
n1="$1"
|
||||
n2="$2"
|
||||
subtract somename "$n2" "$n1"
|
||||
case "$somename" in
|
||||
0) return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
# useful functions for the line editor
|
||||
|
||||
# open a file - copy it to the buffers
|
||||
|
||||
open () {
|
||||
file="$1"
|
||||
set `$dd "if=$file" of=/dev/null 2>&1`
|
||||
case "$1" in
|
||||
dd*) return 1
|
||||
esac
|
||||
# copy the first line to $ed.c
|
||||
go=true
|
||||
len=0
|
||||
while $go
|
||||
do
|
||||
case "`$dd "if=$file" bs=1 skip=$len count=1 2>/dev/null`" in
|
||||
?*) go=true ;;
|
||||
*) go=false ;;
|
||||
esac
|
||||
add len 1 $len
|
||||
done
|
||||
# now $len is the length of the first line (including newline)
|
||||
$dd "if=$file" bs=1 count=$len of=$ed.c 2>/dev/null
|
||||
$dd "if=$file" bs=1 skip=$len of=$ed.b 2>/dev/null
|
||||
$dd if=/dev/null of=$ed.a 2>/dev/null
|
||||
lineno=1
|
||||
}
|
||||
|
||||
# save a file - copy the buffers to the file
|
||||
|
||||
save () {
|
||||
# make a backup copy of the original
|
||||
$dd "if=$1" "of=$1.bak" 2>/dev/null
|
||||
# and save
|
||||
( $dd if=$ed.a; $dd if=$ed.c; $dd if=$ed.b ) > "$1" 2>/dev/null
|
||||
}
|
||||
|
||||
# replace n1 n2 bla replaces n2 chars of current line, starting n1-th
|
||||
|
||||
replace () {
|
||||
$dd if=$ed.c of=$tmp.1 bs=1 "count=$1" 2>/dev/null
|
||||
( $dd if=$ed.c "skip=$1" bs=1 | $dd of=$tmp.2 bs=1 "skip=$2" ) 2>/dev/null
|
||||
shift
|
||||
shift
|
||||
( $dd if=$tmp.1; Echo -n "$@"; $dd if=$tmp.2 ) > $tmp.3 2>/dev/null
|
||||
$dd if=$tmp.3 of=$ed.c 2>/dev/null
|
||||
}
|
||||
|
||||
# rstring n s bla
|
||||
# replace the n-th occurence of s with bla
|
||||
|
||||
rstring () {
|
||||
n="$1"
|
||||
shift;
|
||||
# first we have to find it - this is fun!
|
||||
# we have $tmp.4 => text before string, $tmp.5 => text after
|
||||
$dd if=/dev/null of=$tmp.4 2>/dev/null
|
||||
$dd if=$ed.c of=$tmp.5 2>/dev/null
|
||||
string="$1"
|
||||
shift
|
||||
$dd of=$tmp.6 2>/dev/null <<EOF
|
||||
$@
|
||||
EOF
|
||||
while :
|
||||
do
|
||||
case "`$dd if=$tmp.5 2>/dev/null`" in
|
||||
$string*)
|
||||
if lt $n 2
|
||||
then
|
||||
# now we want to replace the string
|
||||
Echo -n "$@" > $tmp.2
|
||||
Echo -n "$string" > $tmp.1
|
||||
IFS="+"
|
||||
set `$dd bs=1 if=$tmp.1 of=/dev/null 2>&1`
|
||||
IFS="$saveIFS"
|
||||
slen=$1
|
||||
IFS="+"
|
||||
( $dd if=$tmp.4; $dd if=$tmp.2; $dd if=$tmp.5 bs=1 skip=$slen ) \
|
||||
2>/dev/null > $tmp
|
||||
$dd if=$tmp of=$ed.c 2>/dev/null
|
||||
return 0
|
||||
else
|
||||
subtract n $n 1
|
||||
( $dd if=$tmp.4; $dd if=$tmp.5 bs=1 count=1 ) > $tmp 2>/dev/null
|
||||
$dd if=$tmp of=$tmp.4 2>/dev/null
|
||||
# and remove it from $tmp.5
|
||||
$dd if=$tmp.5 of=$tmp bs=1 skip=1 2>/dev/null
|
||||
$dd if=$tmp of=$tmp.5 2>/dev/null
|
||||
fi
|
||||
;;
|
||||
?*) # add one more byte...
|
||||
( $dd if=$tmp.4; $dd if=$tmp.5 bs=1 count=1 ) > $tmp 2>/dev/null
|
||||
$dd if=$tmp of=$tmp.4 2>/dev/null
|
||||
# and remove it from $tmp.5
|
||||
$dd if=$tmp.5 of=$tmp bs=1 skip=1 2>/dev/null
|
||||
$dd if=$tmp of=$tmp.5 2>/dev/null
|
||||
;;
|
||||
*) # not found
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# skip to next line
|
||||
next () {
|
||||
add l $lineno 1
|
||||
( $dd if=$ed.a; $dd if=$ed.c ) 2>/dev/null > $tmp.3
|
||||
$dd if=$ed.b of=$tmp.4 2>/dev/null
|
||||
open $tmp.4
|
||||
$dd if=$tmp.3 of=$ed.a 2>/dev/null
|
||||
lineno=$l
|
||||
}
|
||||
|
||||
# delete current line
|
||||
delete () {
|
||||
l=$lineno
|
||||
$dd if=$ed.a 2>/dev/null > $tmp.1
|
||||
$dd if=$ed.b of=$tmp.2 2>/dev/null
|
||||
open $tmp.2
|
||||
$dd if=$tmp.1 of=$ed.a 2>/dev/null
|
||||
lineno=$l
|
||||
}
|
||||
|
||||
# insert before current line (without changing current)
|
||||
insert () {
|
||||
( $dd if=$ed.a; Echo "$@" ) 2>/dev/null > $tmp.1
|
||||
$dd if=$tmp.1 of=$ed.a 2>/dev/null
|
||||
add lineno $lineno 1
|
||||
}
|
||||
|
||||
# previous line
|
||||
prev () {
|
||||
case "$lineno" in
|
||||
1) ;;
|
||||
*) subtract lineno $lineno 1
|
||||
# read last line of $ed.a
|
||||
IFS='+'
|
||||
set `$dd if=$ed.a of=/dev/null bs=1 2>&1`
|
||||
IFS="$saveIFS"
|
||||
size=$1
|
||||
# empty?
|
||||
case "$size" in
|
||||
0) return ;;
|
||||
esac
|
||||
subtract size $size 1
|
||||
# skip final newline
|
||||
case "$size" in
|
||||
0) ;;
|
||||
*) subtract size1 $size 1
|
||||
case "`$dd if=$ed.a bs=1 skip=$size count=1 2>/dev/null`" in
|
||||
?*) ;;
|
||||
*) size=$size1 ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
go=true
|
||||
while $go
|
||||
do
|
||||
case "$size" in
|
||||
0) go=false ;;
|
||||
*) case "`$dd if=$ed.a bs=1 skip=$size count=1 2>/dev/null`" in
|
||||
?*) go=true; subtract size $size 1 ;;
|
||||
*) go=false; add size $size 1 ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# now $size is the size of the first n-1 lines
|
||||
# add $ed.c to $ed.b
|
||||
( $dd if=$ed.c; $dd if=$ed.b ) 2>/dev/null > $tmp.5
|
||||
$dd if=$tmp.5 of=$ed.b 2>/dev/null
|
||||
# move line to ed.c
|
||||
case "$size" in
|
||||
0) $dd if=$ed.a of=$ed.c 2>/dev/null
|
||||
$dd if=/dev/null of=$tmp.5 2>/dev/null
|
||||
;;
|
||||
*) $dd if=$ed.a of=$ed.c bs=1 skip=$size 2>/dev/null
|
||||
$dd if=$ed.a of=$tmp.5 bs=1 count=$size 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
# move rest to ed.a
|
||||
$dd if=$tmp.5 of=$ed.a 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# goes to a given line
|
||||
goto () {
|
||||
rl="$1"
|
||||
compare bla "$rl" $lineno
|
||||
case "$bla" in
|
||||
eq) return
|
||||
;;
|
||||
gt) while gt "$rl" $lineno
|
||||
do
|
||||
next
|
||||
done
|
||||
;;
|
||||
lt) while lt "$rl" $lineno
|
||||
do
|
||||
prev
|
||||
done
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
lineout () {
|
||||
Echo -n "$lineno: "
|
||||
$dd if=$ed.c 2>/dev/null
|
||||
}
|
||||
|
||||
state=closed
|
||||
name=
|
||||
autoprint=true
|
||||
|
||||
while true
|
||||
do
|
||||
Echo -n '> '
|
||||
read cmd arg
|
||||
case "$cmd:$state" in
|
||||
open:open) Echo "There is a file open already" ;;
|
||||
open:*) if open "$arg"
|
||||
then state=open; name="$arg"; $autoprint
|
||||
else Echo "Cannot open $arg"
|
||||
fi
|
||||
;;
|
||||
new:open) Echo "There is a file open already" ;;
|
||||
new:*) open "$arg"
|
||||
state=open
|
||||
name="$arg"
|
||||
$autoprint
|
||||
;;
|
||||
close:changed) Echo "Use 'discard' or 'save'" ;;
|
||||
close:closed) Echo "Closed already" ;;
|
||||
close:*) state=closed ;;
|
||||
save:closed) Echo "There isn't a file to save" ;;
|
||||
save:*) case "$arg" in
|
||||
?*) save "$arg" ;;
|
||||
*) save "$name" ;;
|
||||
esac
|
||||
state=open
|
||||
;;
|
||||
discard:changed) Echo "Your problem!"; state=closed ;;
|
||||
discard:*) state=closed ;;
|
||||
print:closed) Echo "No current file" ;;
|
||||
print:*) lineout ;;
|
||||
goto:closed) Echo "No current file" ;;
|
||||
goto:*) goto "$arg"; $autoprint ;;
|
||||
next:closed) Echo "No current file" ;;
|
||||
next:*) next; $autoprint ;;
|
||||
prev:closed) Echo "No current file" ;;
|
||||
prev:*) prev; $autoprint ;;
|
||||
name:closed) Echo "No current file" ;;
|
||||
name:*) name="$arg" ;;
|
||||
replace:closed) Echo "No current file" ;;
|
||||
replace:*) if rstring 1 $arg
|
||||
then state=changed; $autoprint
|
||||
else Echo "Not found"
|
||||
fi
|
||||
;;
|
||||
nreplace:closed) Echo "No current file" ;;
|
||||
nreplace:*) if rstring $arg
|
||||
then state=changed; $autoprint
|
||||
else Echo "Not found"
|
||||
fi
|
||||
;;
|
||||
delete:closed) Echo "No current file" ;;
|
||||
delete:*) delete; state=changed; $autoprint ;;
|
||||
insert:closed) Echo "No current file" ;;
|
||||
insert:*) insert "$arg"; prev; state=changed; $autoprint ;;
|
||||
quit:changed) Echo "Use 'save' or 'discard'" ;;
|
||||
quit:*) Echo "bye"; exit;;
|
||||
autoprint:*) autoprint="lineout" ;;
|
||||
noprint:*) autoprint="" ;;
|
||||
:*) ;;
|
||||
*) Echo "Command not understood" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
|
||||
# Newsgroups: comp.unix.shell,comp.os.linux.misc
|
||||
# Subject: GNU Bash Script to fix filenames
|
||||
# Date: 28 Mar 1996 14:54:43 -0800
|
||||
# Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
|
||||
#
|
||||
#This is a script which takes a list of directories, descends through each one
|
||||
#and ``corrects'' filenames that:
|
||||
#
|
||||
# - contain filename globbing characters: * ? [ ]
|
||||
# - quote characters: ' "
|
||||
# - control characters: 0-31 (127 is not dealt with---oops)
|
||||
# - - or + as the first character
|
||||
#
|
||||
# The GNU version of 'tr' is required. Also requires 'sed'.
|
||||
#
|
||||
# Script to process a given list of directories recursively
|
||||
# and rename each file to something that is reasonable.
|
||||
#
|
||||
# The rules are:
|
||||
#
|
||||
# 1. replace each space, [, ], *, ", and ' character in the name with a
|
||||
# period.
|
||||
# 2. replace each control character 1..31 with a printable character obtained
|
||||
# by adding 64 to the ascii value. ^A becomes A, ^B becomes B and so on.
|
||||
# 3. replace a - or + occuring at the beginning of the name with a #
|
||||
#
|
||||
# 4. if the resulting name has been changed in any way, then
|
||||
# 5. if a file of the new name already exists, then
|
||||
# 6. add a . to the new name and goto step 5.
|
||||
# 7. rename the old name to the new name
|
||||
#
|
||||
# written by Kaz Kylheku <kaz@cafe.net>
|
||||
# March 1996
|
||||
# Vancouver, Canada
|
||||
#
|
||||
# requires GNU 'bash', GNU 'tr', and some sort of 'sed' program.
|
||||
#
|
||||
# minimal conversion to bash v2 syntax done by Chet Ramey
|
||||
|
||||
processfile()
|
||||
{
|
||||
new_name="`echo -n $1 | tr '\173\175\052\077\042\047 ' '.......' |
|
||||
tr '[\000-\037]' '[\100-\137]' |
|
||||
sed -e 's/^-/#/' -e 's/+/#/'`"
|
||||
if [ "$new_name" != "$1" ] ; then
|
||||
while [ -e "$new_name" ] ; do
|
||||
new_name="${new_name}."
|
||||
done
|
||||
echo changing \"$1\" to \"$new_name\" in `pwd`
|
||||
mv -- "$1" "$new_name"
|
||||
fi
|
||||
}
|
||||
|
||||
processdir()
|
||||
{
|
||||
set -f
|
||||
local savepwd="$PWD"
|
||||
if cd "$1" ; then
|
||||
set +f
|
||||
for file in * ; do
|
||||
set -f
|
||||
if [ "$file" != "." ] && [ "$file" != ".." ] ; then
|
||||
if [ -L "$file" ] ; then
|
||||
echo "skipping symlink" $file in `pwd`
|
||||
elif [ -d "$file" ] ; then
|
||||
processdir "$file"
|
||||
elif [ -f "$file" ] ; then
|
||||
processfile "$file"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
cd "$savepwd"
|
||||
fi
|
||||
}
|
||||
|
||||
shopt -s nullglob dotglob
|
||||
|
||||
if [ $# = 0 ] ; then
|
||||
echo "$0: must specify a list of directories" >&2
|
||||
echo "$0: usage: $0 directory [directory ...]" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
while [ $# != 0 ] ; do
|
||||
processdir "$1"
|
||||
shift
|
||||
done
|
||||
|
||||
exit 0
|
||||
@@ -1,21 +0,0 @@
|
||||
# Towers of Hanoi in bash
|
||||
#
|
||||
# cribbed from the ksh93 book, example from exercises on page 85
|
||||
#
|
||||
# Chet Ramey
|
||||
# chet@po.cwru.edu
|
||||
|
||||
hanoi() # n from to spare
|
||||
{
|
||||
typeset -i nm1=$1-1
|
||||
((nm1>0)) && hanoi $nm1 $2 $4 $3
|
||||
echo "Move disc $2 to $3"
|
||||
((nm1>0)) && hanoi $nm1 $4 $3 $2
|
||||
}
|
||||
|
||||
case $1 in
|
||||
[1-9])
|
||||
hanoi $1 1 2 3;;
|
||||
*) echo "${0##*/}: Argument must be from 1 to 9"
|
||||
exit 1;;
|
||||
esac
|
||||
@@ -1,74 +0,0 @@
|
||||
# Originally
|
||||
#
|
||||
# From: bsh20858@news.fhda.edu (Brian S Hiles)
|
||||
# Newsgroups: comp.unix.shell
|
||||
# Subject: Re: getting random numbers
|
||||
# Date: 23 Jan 1997 23:27:30 GMT
|
||||
# Message-ID: <5c8s52$eif@tiptoe.fhda.edu>
|
||||
|
||||
# @(#) krand Produces a random number within integer limits
|
||||
# "krand" Korn shell script generates a random number in a
|
||||
# specified range with an optionally specified ``seed'' value.
|
||||
# Author: Peter Turnbull, May 1993
|
||||
# Modified by: Becca Thomas, January 1994
|
||||
|
||||
# changed the optional third argument to a -s option, converted to
|
||||
# bash v2 syntax -- chet@po.cwru.edu
|
||||
|
||||
PROGNAME=${0##*/}
|
||||
USAGE="usage: $PROGNAME [-s seed] lower-limit upper-limit"
|
||||
|
||||
Seed=$$ # Initialize random-number seed value with PID
|
||||
|
||||
usage()
|
||||
{
|
||||
echo ${PROGNAME}: "$USAGE" >&2
|
||||
}
|
||||
|
||||
errexit()
|
||||
{
|
||||
echo ${PROGNAME}: "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Process command-line arguments:
|
||||
while getopts "s:" opt; do
|
||||
case "$opt" in
|
||||
s) Seed=$OPTARG ;;
|
||||
*) usage ; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $(($OPTIND - 1))
|
||||
|
||||
case $# in
|
||||
2) Lower=$1; Upper=$2 ;;
|
||||
*) usage ; exit 2;;
|
||||
esac
|
||||
|
||||
# Check that specified values are integers:
|
||||
expr "$Lower" + 0 >/dev/null 2>&1
|
||||
[ $? -eq 2 ] && { errexit "lower ($Lower) not an integer"; }
|
||||
expr "$Upper" + 0 >/dev/null 2>&1
|
||||
[ $? -eq 2 ] && { errexit "upper ($Upper) not an integer"; }
|
||||
expr "$Seed" + 0 >/dev/null 2>&1
|
||||
[ $? -eq 2 ] && { errexit "seed ($Seed) not an integer"; }
|
||||
|
||||
# Check that values are in the correct range:
|
||||
if (( "$Lower" < 0 )) || [ ${#Lower} -gt 5 ]; then
|
||||
errexit "lower limit ($Lower) less than zero"
|
||||
fi
|
||||
if (( "$Upper" > 32767 )) || [ ${#Upper} -gt 5 ]; then
|
||||
errexit "upper limit ($Upper) greater than 32767"
|
||||
fi
|
||||
if (( "$Seed" < 0 )) || (( "$Seed" > 32767 )) || [ ${#Seed} -gt 5 ]; then
|
||||
errexit "seed value ($Seed) out of range (0 to 32767)"
|
||||
fi
|
||||
(( "$Upper" <= "$Lower" )) && errexit "upper limit ($Upper) <= lower limit ($Lower)"
|
||||
|
||||
# Seed the random-number generator:
|
||||
RANDOM=$Seed
|
||||
# Compute value, scaled within range:
|
||||
let rand="$RANDOM % ($Upper - $Lower + 1) + $Lower"
|
||||
# Report result:
|
||||
echo $rand
|
||||
@@ -1,184 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
#From: kaz@cafe.net (Kaz Kylheku)
|
||||
#Newsgroups: comp.unix.shell
|
||||
#Subject: Funky little bash script
|
||||
#Message-ID: <6mspb9$ft2@espresso.cafe.net>
|
||||
#Date: Thu, 25 Jun 1998 06:11:39 GMT
|
||||
|
||||
#Here is something I wrote a few years ago when I was bored one day.
|
||||
#Warning: this contains control characters.
|
||||
|
||||
# Line input routine for GNU Bourne-Again Shell
|
||||
# plus terminal-control primitives.
|
||||
#
|
||||
# by Kaz Kylheku
|
||||
# June 1996, Vancouver, Canada
|
||||
|
||||
|
||||
#
|
||||
# Function to disable canonical input processing.
|
||||
# Terminal modes are saved into variable "savetty"
|
||||
#
|
||||
#
|
||||
|
||||
function raw
|
||||
{
|
||||
savetty=$(stty -g)
|
||||
stty -icanon -isig -echo -echok -echonl inlcr
|
||||
}
|
||||
|
||||
#
|
||||
# Function to restore terminal settings from savetty variable
|
||||
#
|
||||
|
||||
function restore
|
||||
{
|
||||
stty $savetty
|
||||
}
|
||||
|
||||
#
|
||||
# Set terminal MIN and TIME values.
|
||||
# If the input argument is a zero, set up terminal to wait for
|
||||
# a keystroke indefinitely. If the argument is non-zero, set up
|
||||
# an absolute timeout of that many tenths of a second. The inter-keystroke
|
||||
# timer facility of the terminal driver is not exploited.
|
||||
#
|
||||
|
||||
function settimeout
|
||||
# $1 = tenths of a second
|
||||
{
|
||||
if [ "$1" = "0" ] ; then
|
||||
min=1
|
||||
timeout=0
|
||||
else
|
||||
min=0
|
||||
timeout="$1"
|
||||
fi
|
||||
|
||||
stty min $min time $timeout
|
||||
|
||||
unset min timeout
|
||||
}
|
||||
|
||||
#
|
||||
# Input a single key using 'dd' and echo it to standard output.
|
||||
# Launching an external program to get a single keystroke is a bit
|
||||
# of a pig, but it's the best you can do! Maybe we could convince the
|
||||
# GNU guys to make 'dd' a bash builtin.
|
||||
#
|
||||
|
||||
function getkey
|
||||
{
|
||||
eval $1="\"\$(dd bs=1 count=1 2> /dev/null)\""
|
||||
}
|
||||
|
||||
#
|
||||
# Input a line of text gracefully.
|
||||
# The first argument is the name of a variable where the input line is
|
||||
# to be stored. If this variable is not empty, its contents are printed
|
||||
# and treated as though the user had entered them.
|
||||
# The second argument gives the maximum length of the input line; if it
|
||||
# is zero, the input is unlimited (bad idea).
|
||||
# ^W is used to delete words
|
||||
# ^R redraws the line at any time by backspacing over it and reprinting it
|
||||
# ^U backspaces to the beginning
|
||||
# ^H or ^? (backspace or del) delete a single character
|
||||
# ^M (enter) terminates the input
|
||||
# all other control keys are ignored and cause a beep when pressed
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
function getline
|
||||
{
|
||||
settimeout 0 # No keystroke timeout.
|
||||
save_IFS="$IFS" # Save word delimiter and set it to
|
||||
IFS="" # to null so ${#line} works correctly.
|
||||
eval line=\${$1} # Fetch line contents
|
||||
echo -n "$line" # and print the existing line.
|
||||
while [ 1 ] ; do
|
||||
getkey key # fetch a single keystroke
|
||||
case "$key" in
|
||||
| ) # BS or DEL
|
||||
if [ ${#line} != 0 ] ; then # if line not empty
|
||||
echo -n " " # print destructive BS
|
||||
line="${line%%?}" # chop last character
|
||||
else # else if line empty
|
||||
echo -n # beep the terminal
|
||||
fi
|
||||
;;
|
||||
) # kill to line beg
|
||||
while [ ${#line} != 0 ] ; do # while line not empty
|
||||
echo -n " " # print BS, space, BS
|
||||
line="${line%?}" # shorten line by 1
|
||||
done
|
||||
;;
|
||||
) # redraw line
|
||||
linesave="$line" # save the contents
|
||||
while [ ${#line} != 0 ] ; do # kill to line beg
|
||||
echo -n " "
|
||||
line="${line%?}"
|
||||
done
|
||||
echo -n "$linesave" # reprint, restore
|
||||
line="$linesave"
|
||||
unset linesave # forget temp var
|
||||
;;
|
||||
)
|
||||
while [ "${line% }" != "$line" ] && [ ${#line} != 0 ] ; do
|
||||
echo -n " "
|
||||
line="${line%?}"
|
||||
done
|
||||
while [ "${line% }" = "$line" ] && [ ${#line} != 0 ] ; do
|
||||
echo -n " "
|
||||
line="${line%?}"
|
||||
done
|
||||
;;
|
||||
| | | | | | | | | | |
|
||||
)
|
||||
echo -n # ignore various control characters
|
||||
;; # with an annoying beep
|
||||
| | | | | | | | | | | | )
|
||||
echo -n
|
||||
;;
|
||||
' ' | | | | | )
|
||||
echo -n
|
||||
;;
|
||||
'' ) # Break out of loop on carriage return.
|
||||
echo # Send a newline to the terminal.
|
||||
break # (Also triggered by NUL char!).
|
||||
;;
|
||||
* ) # Append character to the end of the line.
|
||||
# If length is restricted, and the line is too
|
||||
# long, then beep...
|
||||
|
||||
if [ "$2" != 0 ] && [ $(( ${#line} >= $2 )) = 1 ] ; then
|
||||
echo -n
|
||||
else # Otherwise add
|
||||
line="$line$key" # the character.
|
||||
echo -n "$key" # And echo it.
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
eval $1=\"\$line\"
|
||||
IFS="$save_IFS"
|
||||
unset line save_IFS
|
||||
}
|
||||
|
||||
# uncomment the lines below to create a standalone test program
|
||||
#
|
||||
echo "Line input demo for the GNU Bourne-Again Shell."
|
||||
echo "Hacked by Kaz Kylheku"
|
||||
echo
|
||||
echo "Use ^H/Backspace/Del to erase, ^W to kill words, ^U to kill the"
|
||||
echo "whole line of input, ^R to redraw the line."
|
||||
echo "Pass an argument to this program to prime the buffer contents"
|
||||
raw
|
||||
echo -n "go: "
|
||||
if [ ${#1} != 0 ] ; then
|
||||
LINE=$1
|
||||
fi
|
||||
getline LINE 50
|
||||
restore
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
#
|
||||
# BASH VERSION OF nohup COMMAND
|
||||
#
|
||||
ctype()
|
||||
{
|
||||
path=$(builtin type -p $cmd | sed 1q)
|
||||
if [ -n "$path" ]; then
|
||||
echo "$path"
|
||||
return 0
|
||||
else
|
||||
case "$cmd" in
|
||||
*/*) [ -x "$cmd ] && { echo "$cmd" ; return 0; } ;;
|
||||
*) case "$(builtin type -t $cmd)" in
|
||||
"") return 1;;
|
||||
*) echo "$cmd" ; return 0;;
|
||||
esac ;;
|
||||
esac
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
trap '' HUP # ignore hangup
|
||||
command=$(ctype "$1")
|
||||
oldmask=$(umask)
|
||||
umask u=rw,og= # default mode for nohup.out
|
||||
exec 0< /dev/null # disconnect input
|
||||
if [ -t 1 ]; then # redirect output if necessary
|
||||
if [ -w . ]; then
|
||||
echo 'Sending output to nohup.out'
|
||||
exec >> nohup.out
|
||||
else echo "Sending output to $HOME/nohup.out"
|
||||
exec >> $HOME/nohup.out
|
||||
fi
|
||||
fi
|
||||
|
||||
umask "$oldmask"
|
||||
|
||||
# direct unit 2 to a file
|
||||
if [ -t 2 ]; then
|
||||
exec 2>&1
|
||||
fi
|
||||
|
||||
# run the command
|
||||
case $command in
|
||||
*/*) exec "$@"
|
||||
;;
|
||||
time) eval "$@"
|
||||
;;
|
||||
*) "$@"
|
||||
;;
|
||||
esac
|
||||
@@ -1,75 +0,0 @@
|
||||
# @(#)precedence_test 1.0 91/07/24 Maarten Litmaath
|
||||
# test of relative precedences for `&&' and `||' operators
|
||||
|
||||
echo "\`Say' echos its argument. Its return value is of no interest."
|
||||
case `echo -n` in
|
||||
'') Say () { echo -n "$*" ; } ;;
|
||||
*) Say () { echo "$*\c" ; } ;;
|
||||
esac
|
||||
|
||||
echo "\`Truth' echos its argument and returns a TRUE result."
|
||||
Truth () {
|
||||
Say $1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
echo "\`False' echos its argument and returns a FALSE result."
|
||||
False () {
|
||||
Say $1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
echo ""
|
||||
|
||||
cmd1='$open $test1 && $test2 $close || $test3'
|
||||
cmd2='$test1 || $open $test2 && $test3 $close'
|
||||
|
||||
grouping_sh=
|
||||
grouping_C='( )'
|
||||
|
||||
test3='Say 3'
|
||||
|
||||
for i in 1 2
|
||||
do
|
||||
eval proto=\$cmd$i
|
||||
|
||||
for test1 in 'Truth 1' 'False 1'
|
||||
do
|
||||
for test2 in 'Truth 2' 'False 2'
|
||||
do
|
||||
for precedence in sh C
|
||||
do
|
||||
eval set x \$grouping_$precedence
|
||||
shift
|
||||
open=${1-' '}
|
||||
close=${2-' '}
|
||||
eval cmd=\""$proto"\"
|
||||
Say "$cmd output="
|
||||
output=`eval "$cmd"`
|
||||
Say "$output"
|
||||
read correct || { echo 'Input fubar. Abort.' >&2; exit 1; }
|
||||
test "X$output" = "X$correct" || echo " correct=$correct"
|
||||
echo ''
|
||||
done
|
||||
|
||||
echo ''
|
||||
done
|
||||
done
|
||||
done << EOF
|
||||
12
|
||||
12
|
||||
123
|
||||
123
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
1
|
||||
13
|
||||
1
|
||||
123
|
||||
123
|
||||
12
|
||||
12
|
||||
EOF
|
||||
@@ -1,18 +0,0 @@
|
||||
# The following prints a random card from a card deck.
|
||||
#
|
||||
# cribbed from the ksh93 book, example from page 70
|
||||
#
|
||||
# chet@po.cwru.edu
|
||||
#
|
||||
declare -i i=0
|
||||
|
||||
# load the deck
|
||||
for suit in clubs diamonds hearts spades; do
|
||||
for n in ace 2 3 4 5 6 7 8 9 10 jack queen king; do
|
||||
card[i]="$n of $suit"
|
||||
i=i+1 # let is not required with integer variables
|
||||
done
|
||||
done
|
||||
|
||||
# and print a random card
|
||||
echo ${card[RANDOM%52]}
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# scrollbar - display scrolling text
|
||||
#
|
||||
# usage: scrollbar args
|
||||
#
|
||||
# A cute hack originally from Heiner Steven <hs@bintec.de>
|
||||
#
|
||||
# converted from ksh syntax to bash v2 syntax by Chet Ramey
|
||||
|
||||
WIDTH=${COLUMNS:-80}
|
||||
WMINUS=$(( $WIDTH - 1 ))
|
||||
|
||||
[ $# -lt 1 ] && set -- TESTING
|
||||
|
||||
# use the bash-2.02 printf builtin
|
||||
Text=$(printf "%-${WIDTH}s" "$*")
|
||||
Text=${Text// /_}
|
||||
|
||||
while :
|
||||
do
|
||||
printf "%-.${WIDTH}s\r" "$Text"
|
||||
LastC=${Text:${WMINUS}:1}
|
||||
Text="$LastC""${Text%?}"
|
||||
done
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# scrollbar - display scrolling text
|
||||
#
|
||||
# usage: scrollbar args
|
||||
#
|
||||
# A cute hack originally from Heiner Steven <hs@bintec.de>
|
||||
#
|
||||
# converted from ksh syntax to bash v2 syntax by Chet Ramey
|
||||
|
||||
WIDTH=${COLUMNS:-80}
|
||||
WMINUS=$(( $WIDTH - 1 ))
|
||||
|
||||
[ $# -lt 1 ] && set -- TESTING
|
||||
|
||||
# use the bash-2.02 printf builtin
|
||||
Text=$(printf "%-${WIDTH}s" "$*")
|
||||
|
||||
while :
|
||||
do
|
||||
printf "%-.${WIDTH}s\r" "$Text"
|
||||
LastC=${Text:${WMINUS}:1}
|
||||
Text="$LastC""${Text%?}"
|
||||
done
|
||||
@@ -1,9 +0,0 @@
|
||||
# self-reproducing script (except for these comment lines -- remove them)
|
||||
# i got this from the ksh93 faq:
|
||||
# http://www.kornshell.com/doc/faq.html
|
||||
#
|
||||
n="
|
||||
" q="'" x="cat <<-!" y=! z='n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$y'
|
||||
cat <<-!
|
||||
n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$yb
|
||||
!
|
||||
@@ -1,53 +0,0 @@
|
||||
#Newsgroups: comp.unix.shell
|
||||
#From: gwc@root.co.uk (Geoff Clare)
|
||||
#Subject: Re: Determining permissions on a file
|
||||
#Message-ID: <Dr79nw.DtL@root.co.uk>
|
||||
#Date: Fri, 10 May 1996 17:23:56 GMT
|
||||
|
||||
#Here's a bit of Korn shell that converts the symbolic permissions produced
|
||||
#by "ls -l" into octal, using only shell builtins. How to create a script
|
||||
#combining this with an "ls -l" is left as an exercise...
|
||||
#
|
||||
#
|
||||
# Converted to Bash v2 syntax by Chet Ramey <chet@po.cwru.edu>
|
||||
#
|
||||
# usage: showperm modestring
|
||||
#
|
||||
# example: showperm '-rwsr-x--x'
|
||||
#
|
||||
|
||||
[ -z "$1" ] && {
|
||||
echo "showperm: usage: showperm modestring" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
tmode="$1"
|
||||
|
||||
typeset -i omode sbits
|
||||
typeset pmode
|
||||
|
||||
# check for set-uid, etc. bits
|
||||
sbits=0
|
||||
case $tmode in
|
||||
???[sS]*) (( sbits += 8#4000 )) ;; # set-uid
|
||||
??????[sSl]*) (( sbits += 8#2000 )) ;; # set-gid or mand. lock
|
||||
?????????[tT]*) (( sbits += 8#1000 )) ;; # sticky
|
||||
esac
|
||||
|
||||
omode=0
|
||||
while :
|
||||
do
|
||||
tmode=${tmode#?}
|
||||
case $tmode in
|
||||
"") break ;;
|
||||
[-STl]*) (( omode *= 2 )) ;;
|
||||
[rwxst]*) (( omode = omode*2 + 1 )) ;;
|
||||
*) echo "$0: first letter of \"$tmode\" is unrecognized" >&2
|
||||
(( omode *= 2 ))
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
(( omode += sbits ))
|
||||
|
||||
printf "0%o\n" $omode
|
||||
@@ -1,53 +0,0 @@
|
||||
#Newsgroups: comp.unix.admin,comp.unix.solaris,comp.unix.shell
|
||||
#From: gwc@root.co.uk (Geoff Clare)
|
||||
#Subject: Re: timeout -t <sec> <unix command> (Re: How to give rsh a shorter timeout?)
|
||||
#Message-ID: <EoBxrs.223@root.co.uk>
|
||||
#Date: Fri, 13 Feb 1998 18:23:52 GMT
|
||||
|
||||
#
|
||||
# Conversion to bash v2 syntax done by Chet Ramey <chet@po.cwru.edu
|
||||
# UNTESTED
|
||||
#
|
||||
|
||||
prog=${0##*/}
|
||||
usage="usage: $prog [-signal] [timeout] [:interval] [+delay] [--] <command>"
|
||||
|
||||
SIG=-TERM # default signal sent to the process when the timer expires
|
||||
timeout=60 # default timeout
|
||||
interval=15 # default interval between checks if the process is still alive
|
||||
delay=2 # default delay between posting the given signal and
|
||||
# destroying the process (kill -KILL)
|
||||
|
||||
while :
|
||||
do
|
||||
case $1 in
|
||||
--) shift; break ;;
|
||||
-*) SIG=$1 ;;
|
||||
[0-9]*) timeout=$1 ;;
|
||||
:*) EXPR='..\(.*\)' ; interval=`expr x"$1" : "$EXPR"` ;;
|
||||
+*) EXPR='..\(.*\)' ; delay=`expr x"$1" : "$EXPR"` ;;
|
||||
*) break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
case $# in
|
||||
0) echo "$prog: $usage" >&2 ; exit 2 ;;
|
||||
esac
|
||||
|
||||
(
|
||||
for t in $timeout $delay
|
||||
do
|
||||
while (( $t > $interval ))
|
||||
do
|
||||
sleep $interval
|
||||
kill -0 $$ || exit
|
||||
t=$(( $t - $interval ))
|
||||
done
|
||||
sleep $t
|
||||
kill $SIG $$ && kill -0 $$ || exit
|
||||
SIG=-KILL
|
||||
done
|
||||
) 2> /dev/null &
|
||||
|
||||
exec "$@"
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Author: P@draigBrady.com
|
||||
# V1.0 : Nov 3 2006
|
||||
#
|
||||
# Execute a command with a timeout.
|
||||
# If the timeout occurs the exit status is 128
|
||||
#
|
||||
# Note there is an asynchronous equivalent of this
|
||||
# script packaged with bash (under /usr/share/doc/ in my distro),
|
||||
# which I only noticed after writing this.
|
||||
|
||||
if [ "$#" -lt "2" ]; then
|
||||
echo "Usage: `basename $0` timeout_in_seconds command" >&2
|
||||
echo "Example: `basename $0` 2 sleep 3 || echo timeout" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cleanup()
|
||||
{
|
||||
kill %1 2>/dev/null #kill sleep $timeout if running
|
||||
kill %2 2>/dev/null && exit 128 #kill monitored job if running
|
||||
}
|
||||
|
||||
set -m #enable job control
|
||||
trap "cleanup" 17 #cleanup after timeout or command
|
||||
timeout=$1 && shift #first param is timeout in seconds
|
||||
sleep $timeout& #start the timeout
|
||||
"$@" #start the job
|
||||
@@ -1,92 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# The Bash script executes a command with a time-out.
|
||||
# Based on the Bash documentation example.
|
||||
#
|
||||
# Upon time-out expiration SIGTERM (15) is sent to the process. If the signal
|
||||
# is blocked, then the subsequent SIGKILL (9) terminates it.
|
||||
# Dmitry V Golovashkin (E-mail: dvg@ieee.org)
|
||||
#
|
||||
script_name="${0##*/}"
|
||||
|
||||
# Default values.
|
||||
readonly param_timeout=5
|
||||
readonly param_interval=1
|
||||
readonly param_delay=1
|
||||
|
||||
declare -i timeout=param_timeout
|
||||
declare -i interval=param_interval
|
||||
declare -i delay=param_delay
|
||||
|
||||
blue="$(tput setaf 4)"
|
||||
bold_red="$(tput bold; tput setaf 1)"
|
||||
off="$(tput sgr0)"
|
||||
|
||||
function print_usage() {
|
||||
cat <<EOF
|
||||
|
||||
Synopsis: $script_name [-t timeout] [-i interval] [-d delay] command
|
||||
|
||||
Executes the command with a time-out. Upon time-out expiration SIGTERM (15) is
|
||||
sent to the process. If SIGTERM signal is blocked, then the subsequent SIGKILL
|
||||
(9) terminates it.
|
||||
|
||||
$blue-t timeout$off
|
||||
Number of seconds to wait for command completion.
|
||||
Default value: $param_timeout seconds. In some practical situations
|
||||
this value ${bold_red}must$off be increased (for instance -t 180) to allow
|
||||
the command to complete.
|
||||
|
||||
$blue-i interval$off
|
||||
Interval between checks if the process is still alive.
|
||||
Positive integer, default value: $param_interval seconds.
|
||||
Default value is OK for most situations.
|
||||
|
||||
$blue-d delay$off
|
||||
Delay between posting the SIGTERM signal and destroying the process by
|
||||
SIGKILL. Default value: $param_delay seconds.
|
||||
Default value is OK for most situations.
|
||||
|
||||
As of today, Bash does not support floating point arithmetic (sleep does),
|
||||
therefore all time values must be integers.
|
||||
Dmitry Golovashkin (E-mail: dvg@ieee.org)
|
||||
EOF
|
||||
exit 1 # No useful work was done.
|
||||
}
|
||||
|
||||
# Options.
|
||||
while getopts ":t:i:d:" option; do
|
||||
case "$option" in
|
||||
t) timeout=$OPTARG ;;
|
||||
i) interval=$OPTARG ;;
|
||||
d) delay=$OPTARG ;;
|
||||
*) print_usage ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
# $# should be at least 1 (the command to execute), however it may be strictly
|
||||
# greater than 1 if the command itself has options.
|
||||
if (($# == 0 || interval <= 0)); then
|
||||
print_usage
|
||||
fi
|
||||
|
||||
# kill -0 pid Exit code indicates if a signal may be sent to "pid" process.
|
||||
(
|
||||
((t = timeout))
|
||||
|
||||
while ((t > 0)); do
|
||||
sleep $interval
|
||||
kill -0 $$ || exit 0
|
||||
((t -= interval))
|
||||
done
|
||||
|
||||
# Be nice, post SIGTERM first.
|
||||
# The 'exit 0' below will be executed if any preceeding command fails.
|
||||
kill -s SIGTERM $$ && kill -0 $$ || exit 0
|
||||
sleep $delay
|
||||
kill -s SIGKILL $$
|
||||
) 2> /dev/null &
|
||||
|
||||
exec "$@"
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# vtree - make a tree printout of the specified directory, with disk usage
|
||||
# in 1k blocks
|
||||
#
|
||||
# usage: vtree [-a] [dir]
|
||||
#
|
||||
# Original posted to Usenet sometime in February, 1996
|
||||
# I believe that the original author is Brian S. Hiles <bsh29256@atc.fhda.edu>
|
||||
#
|
||||
usage()
|
||||
{
|
||||
echo "vtree: usage: vtree [-a] [dir]" >&2
|
||||
}
|
||||
|
||||
while getopts a opt
|
||||
do
|
||||
case "$opt" in
|
||||
a) andfiles=-a ;;
|
||||
*) usage ; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
export BLOCKSIZE=1k # 4.4 BSD systems need this
|
||||
|
||||
[ $# -eq 0 ] && set .
|
||||
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
cd "$1" || { shift; [ $# -ge 1 ] && echo >&2; continue; }
|
||||
echo -n "$PWD"
|
||||
|
||||
du $andfiles | sort -k 2f | sed \
|
||||
-e 's/\([^ ]*\) \(.*\)/\2 (\1)/' \
|
||||
-e "s#^$1##" \
|
||||
-e 's#[^/]*/\([^/]*\)$#|____\1#' \
|
||||
-e 's#[^/]*/#| #g'
|
||||
|
||||
[ $# -gt 1 ] && echo
|
||||
shift
|
||||
done
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user