Imported from ../bash-2.0.tar.gz.
This commit is contained in:
parent
726f63884d
commit
ccc6cda312
502 changed files with 91988 additions and 69123 deletions
29
examples/scripts.noah/PERMISSION
Normal file
29
examples/scripts.noah/PERMISSION
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
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. :-)
|
||||
|
||||
24
examples/scripts.noah/README
Normal file
24
examples/scripts.noah/README
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
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
|
||||
prompt.bash a way to set PS1 to some predefined strings
|
||||
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'
|
||||
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 that changes readline bindings too
|
||||
y_or_n_p.bash prompt for a yes/no/quit answer
|
||||
44
examples/scripts.noah/aref.bash
Normal file
44
examples/scripts.noah/aref.bash
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# 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
|
||||
28
examples/scripts.noah/bash.sub.bash
Normal file
28
examples/scripts.noah/bash.sub.bash
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# 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
|
||||
42
examples/scripts.noah/bash_version.bash
Normal file
42
examples/scripts.noah/bash_version.bash
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# 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
|
||||
37
examples/scripts.noah/meta.bash
Normal file
37
examples/scripts.noah/meta.bash
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# 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
|
||||
66
examples/scripts.noah/mktmp.bash
Normal file
66
examples/scripts.noah/mktmp.bash
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# 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
|
||||
185
examples/scripts.noah/number.bash
Normal file
185
examples/scripts.noah/number.bash
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
# 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}" != '.' -a ".${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
|
||||
40
examples/scripts.noah/prompt.bash
Normal file
40
examples/scripts.noah/prompt.bash
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# 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
|
||||
71
examples/scripts.noah/remap_keys.bash
Normal file
71
examples/scripts.noah/remap_keys.bash
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# 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
|
||||
182
examples/scripts.noah/require.bash
Normal file
182
examples/scripts.noah/require.bash
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
# 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
|
||||
140
examples/scripts.noah/send_mail.bash
Normal file
140
examples/scripts.noah/send_mail.bash
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# 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
|
||||
49
examples/scripts.noah/shcat.bash
Normal file
49
examples/scripts.noah/shcat.bash
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# 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
|
||||
63
examples/scripts.noah/source.bash
Normal file
63
examples/scripts.noah/source.bash
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# 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
|
||||
226
examples/scripts.noah/string.bash
Normal file
226
examples/scripts.noah/string.bash
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
# 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}" -o "${3}" -le "0" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ ${3} -ge ${#1} -a ${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
|
||||
64
examples/scripts.noah/stty.bash
Normal file
64
examples/scripts.noah/stty.bash
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# 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
|
||||
78
examples/scripts.noah/y_or_n_p.bash
Normal file
78
examples/scripts.noah/y_or_n_p.bash
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue