Re: workaround to make korn shell aliases that can take parameters



2006-10-1, 10:04(+01), Stephane CHAZELAS:
2006-09-30, 11:41(-07), DaveG:
hi,

I had been annoyed about this for a while and then I realized the apply
command could be used to do it.

It does require the apply command (in BSD since '94), but other seems
fairly general.
[...]

By the way, below is a reimplementation of the apply(1) that can
be in NetBSD with the same bugs and limitations:
- only 9 arguments supported
- apply(1) replaces the %1, %2... with the arguments provided
as shell code!! That means that:
apply 'mv %1 /dest' *
will for instance remove your home directory if one of the
files in the current directory is called
`rm -rf "$HOME"`
- it prepends the command line with "exec " so that
apply 'echo will remove %1; rm -f %1' *
doesn't work. Can be worked around though:
apply '3>&-; echo will remove %1; rm -f %1' *
apply '= echo will remove %1; rm -f %1' *
(assuming your shell is Bourne like).
[...]

A more reliable apply(1) (so different from the BSD one):

$ ./apply 'echo %1' 'a `echo rm HOME > /dev/tty`'
rm HOME
a
$ ./apply2 'echo %1' 'a `echo rm HOME > /dev/tty`'
a `echo rm HOME > /dev/tty`


#! /path/to/posix/sh -

progname=$0

usage() {
printf >&2 \
'usage: %s [-a magic] [-0123456789] command arguments ...\n' "$progname"
exit 1
}

die() {
printf >&2 '%s: ' "$progname"
printf >&2 "$@"
printf >&2 '\n'
exit 1
}

magic=% nargs=
while getopts a:01234567890 opt
do
case $opt in
([0-9])
[ -z "$nargs" ] ||
die 'only one -# argument may be specified.'
nargs=$opt
;;
(a)
magic=${OPTARG%"${OPTARG#?}"}
[ -n "$magic" ] ||
die 'illegal magic character specification.'
;;
(*)
usage
;;
esac
done

shift "$((OPTIND - 1))"

[ "$#" -ge 1 ] || usage

cmdfmt=$1
shift

case $cmdfmt in
(*"$magic"9*) nargs=9;;
(*"$magic"8*) nargs=8;;
(*"$magic"7*) nargs=7;;
(*"$magic"6*) nargs=6;;
(*"$magic"5*) nargs=5;;
(*"$magic"4*) nargs=4;;
(*"$magic"3*) nargs=3;;
(*"$magic"2*) nargs=2;;
(*"$magic"1*) nargs=1;;
(*)
i=1
while [ "$i" -le "${nargs:=1}" ]
do
cmdfmt="$cmdfmt $magic$i"
i=$(($i + 1))
done
[ "$nargs" -eq 0 ] && nargs=1
;;
esac

NL='
'

case $magic in
("$NL") magic='\n';;
([][^.*$\\/]) magic=\\$magic;;
esac

shell=${SHELL:-/bin/sh}

case ${shell##*/} in
(csh | tcsh)
repl='${a\1:q}'
;;
(rc | es | akanga | zsh)
repl='${a\1}'
;;
(fish)
repl='{$a\1}'
;;
(*)
repl='"${a\1}"'
;;
esac

cmdfmt=$(
printf '%s\n' "$cmdfmt" |
sed '
:1
$!{
N
b1
}
s/'"$magic"'\([1-9]\)/'"$repl"'/g
'
)

rval=0
while [ "$#" -gt 0 ]
do
if [ "$#" -lt "$nargs" ]
then
eval "lastarg=\${$#}"
printf >&2 \
'%s: expecting additional argument%.*s after "%s"\n' \
"$progname" "$(($nargs - $# > 1))" s "$lastarg"
exit 1
fi

i=1
while [ "$i" -le "$nargs" ]
do
eval "export a$i=\"\${$i}\""
i=$(($i + 1))
done

"$shell" -c "$cmdfmt" || rval=1

shift "$nargs"
done
exit "$rval"


--
Stéphane
.



Relevant Pages

  • Re: workaround to make korn shell aliases that can take parameters
    ... It does require the apply command, ... printf>&2 '\n' ... shift "$)" ...
    (comp.unix.shell)
  • SUMMARY: help for a script
    ... because i will use his command in ... my first mail was not so clear, i want to automatically kill process ... --version print the version and exit ...
    (SunManagers)
  • How to determine is variable has value?
    ... I have function that parses the command line and loads each -? ... printf "$1 is a required switch!\n"; ...
    (comp.unix.shell)
  • Re: Most dependable way to run system commands
    ... Eventually I'd like to bring the execution of a few system commands ... specific execution issue (it dealt more with executing Perl code)). ... Unix and many similar systems, the exit status is an integer, with 0 ... variable after running a command via system or backticks. ...
    (perl.beginners)
  • Re: very slow cursor in CMD window w/Text editor?
    ... REM MS-DOS-based application, Windows runs COMMAND.COM. ... To run CMD.EXE, the Windows command prompt, ... The exit command is an internal command part of command.com or cmd.exe. ...
    (microsoft.public.windowsxp.general)