Unix Shell - "canonical" approach to writing wrapper scripts

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > January 2006 > "canonical" approach to writing wrapper scripts





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author "canonical" approach to writing wrapper scripts
Timothy Larson

2006-01-19, 8:11 am

I've been searching for the "one true way" to write a good wrapper
script, but instead of find lots of different suggestions that seem to
have parts of the answer.

My current task is to write a wrapper that sets up the environment (via
an extra argument) before calling the original command with the
remaining arguments. However I'd like to write it in the best form
possible, rather than just hacking it together.

The logic for setting up my environment has been easy. It's figuring
out how to write a _good_ wrapper in the general case that's got me
stumped.

I'm pretty sure I can walk the arguments and drop my "extra" one before
calling the original command. But will this affect the approach I would
use in the general case?

Any/all assistance appreciated. I'm using bash, but if it's
Bourne-compatible so much the better.


Thanks,
Tim
Stephane Chazelas

2006-01-19, 6:24 pm

On Thu, 19 Jan 2006 08:10:36 -0600, Timothy Larson wrote:
> I've been searching for the "one true way" to write a good wrapper
> script, but instead of find lots of different suggestions that seem to
> have parts of the answer.
>
> My current task is to write a wrapper that sets up the environment (via
> an extra argument) before calling the original command with the
> remaining arguments. However I'd like to write it in the best form
> possible, rather than just hacking it together.
>
> The logic for setting up my environment has been easy. It's figuring
> out how to write a _good_ wrapper in the general case that's got me
> stumped.
>
> I'm pretty sure I can walk the arguments and drop my "extra" one before
> calling the original command. But will this affect the approach I would
> use in the general case?

[...]

depends what you want to do exactly. You may need for instance
to parse the command arguments exactly the same way as the
command would do in some cases.

If your question is just how to call the real application in the
wrapper, then it's:

exec "$REALCOMMAND" "$@"

at the end of the script.

For parsing arguments, you can use getopts or getopts_long
(http://stchaz.free.fr/getopts_long.sh), depending on whether
the real command uses getopt or getopt_long. You can do a
strings real-command, to find out the getopt argument. For
instance:

strings on vi gives:

[...]
VLc:vt:rlw:xRCsS
Usage: %s [- | -s] [-l] [-L] [-wn] [-R] [-S] [-r [file]] [-t tag]
[-v] [-V] [-x] [-C] [+cmd | -c cmd] file...
[...]

So you can use getopts with that VLc:vt:rlw:xRCsS to parse the
command line options.

--
Stephane
bsh

2006-01-22, 6:10 pm


Timothy Larson wrote:
> The logic for setting up my environment has been easy. It's figuring
> out how to write a _good_ wrapper in the general case that's got me
> stumped.


It's hard to give the "right" answer -- which is usually the general
solution -- to a generic query, but at least since your criterion is
a robust option parser, why not at least cheat and first investigate
the [debugged] scripting libraries & templates provided by others?

*CASE,"ADE.{ksh,pl}",0.10.0,http://dione.no-ip.org/~alexis/;htt...p.org/svn/ade/,$0,"Alexis's
Development Environment","Alexis Huxley" <ahuxley@gmx.net>
*CASE,"epto.sh",0.8.16,http://sourceforge.net/projects/epto/,"shellscript
programming library","Jonas Mo:lsa:"
<jonasmolsa@users.sourceforge.net,jbm@nada.kth.se>
CASE,"mkscript.bash",1.1,http://cfaj.freeshell.org/src/scripts/mkscript-sh,$0,"","Chris
F.A. Johnson" <cfaj@freeshell.org,c.f.a.johnson@home.com>
CASE,"new.???",,http://www.flyn.org/projects/new/,$0,"template","W.
Michael Petullo" <mike@flyn.org>
CASE,"new_script.bash;new_function.bash",1.5;1.2,http://freshmeat.net/projects/new_s...ew_script.html,$0,"template
generator","William Shotts, Jr."
<bshotts@clark.net,bshotts@users.sourceforge.net>
*CASE,"scriptt.sh
(sync)",1.20.0,http://home.arcor.de/bnsmb/public/h...ris/templates/,$0,"template
with predefined variables and functions (e.g. for string handling, user
id handling, log file handling, house keeping
routines, trap handler, single step debugger","Bernd Schemmer"
<bnsmbW@online.de,Bernd.Schemmer@gmx.de>
CASE,"template.ksh",2005-03-04,http://www.evilcoder.org/content/view/20/33/,$0,"template","Rick
Rosbag", "Remko Lodder" <remko@elvandar.org>
CASE,"template.bash",0.1,http://shellscripts.org/projects/t/...emplate_0.1.sh,$0,"template","Benjamin
'blindcoder' Schieder" <blindcoder@shellscripts.org>

The templates most applicable for what I understand is your problem
are preceded with an asterisk.

=Brian

Timothy Larson

2006-01-24, 6:23 pm

Stephane Chazelas wrote:
> depends what you want to do exactly. You may need for instance
> to parse the command arguments exactly the same way as the
> command would do in some cases.
>
> If your question is just how to call the real application in the
> wrapper, then it's:
>
> exec "$REALCOMMAND" "$@"
>
> at the end of the script.
>
> For parsing arguments, you can use getopts or getopts_long
> (http://stchaz.free.fr/getopts_long.sh), depending on whether
> the real command uses getopt or getopt_long. You can do a
> strings real-command, to find out the getopt argument. For
> instance:
>
> strings on vi gives:
>
> [...]
> VLc:vt:rlw:xRCsS
> Usage: %s [- | -s] [-l] [-L] [-wn] [-R] [-S] [-r [file]] [-t tag]
> [-v] [-V] [-x] [-C] [+cmd | -c cmd] file...
> [...]
>
> So you can use getopts with that VLc:vt:rlw:xRCsS to parse the
> command line options.


This is GREAT info, thanks! Can I modify $@ before sending it to the
program I'm wrapping? The point of my wrapper is to process one extra
argument, but I'll need to remove it from the arg list before I execute
the program.


Tim
Stephane CHAZELAS

2006-01-24, 6:23 pm

2006-01-24, 06:19(-06), Timothy Larson:
[...]
>
> This is GREAT info, thanks! Can I modify $@ before sending it to the
> program I'm wrapping? The point of my wrapper is to process one extra
> argument, but I'll need to remove it from the arg list before I execute
> the program.

[...]

Yes, you can use "set" and "shift" to modify "$@".

For instance, to insert at the begginning:

set -- "$additional_argument" "$@"

at the end:

set -- "$@" "$additional_argument"

to remove the first 3 arguments:

shift 3

It may be more tricky to insert in the middle or to remove at
the end.

To remove the last one, you can do for instance:

cmdline='set --'

i=1; while [ "$i" -lt "$#" ]; do
cmdline="$cmdline \"\${$i}\""
i=$(($i + 1))
done

eval "$cmdline"

Note that you can sometimes make use of the fact that functions
have a "$@" of their own which may help if you want to make
temporary modifications to "$@" (calling myfunc "$@" allows
myfunc to do things on its own copy of "$@").
--
Stéphane
Timothy Larson

2006-01-25, 8:38 am

This is all great stuff, too. I've been using Unix for years, but still
don't know all the tricks I can do with the shell.

Is "$@" treated as an array? If so, can I just remove the element(s) I
don't need and pass the modified "$@" to my function/program?


Tim
Stephane Chazelas

2006-01-29, 9:30 pm

On Wed, 25 Jan 2006 07:49:07 -0600, Timothy Larson wrote:
> This is all great stuff, too. I've been using Unix for years, but still
> don't know all the tricks I can do with the shell.
>
> Is "$@" treated as an array? If so, can I just remove the element(s) I
> don't need and pass the modified "$@" to my function/program?

[...]

Standard Unix shell syntax doesn't have arrays. However "$@" can
be considered as a kind of array as it contains a list of
strings that can be accessed individually via $1, $2...

If your shell follows the standard Unix shell syntax (which
allows it to be interpreted by any conformant shell (such as
/the/ sh of conformant Unix systems, bash, ksh, recent ash...),
only shift and set can be used to modify that array.

some shells like bash, ksh and zsh have support for arrays of
different shapes.

$@ is often then considered as some sort of array, but in a
special way. Only zsh has a 1 to 1 mapping to an array, as it's
the only one that implements arrays as arrays, whose shape can
be mapped to $@.

It's also the only one to allow you to assign elements
individually. In zsh you can do:

1=foo
or
argv[1]=foo

argv[3,5]=(1 2 3)

argv=("$@[1,3]" "$@[5,-1]") # remove 4th element.

--
Stephane
Maarten

2006-01-29, 9:30 pm

Timothy Larson wrote:
> This is all great stuff, too. I've been using Unix for years, but still
> don't know all the tricks I can do with the shell.


May I kindly recommend the book "Classic Shell Scripting"? Highly
readable, good overview of "The unix way", and a bunch of tricks that
is quite unbelievable.

Maarten

Webpage of said book:
http://www.oreilly.com/catalog/shellsrptg/

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com