public inbox for cygwin-talk@cygwin.com
 help / color / mirror / Atom feed
* bash scripting nightmare.
@ 2006-08-10 17:54 Dave Korn
  2006-08-10 19:49 ` mwoehlke
  2006-08-10 23:10 ` Scripting fun! :-) (was Re: bash scripting nightmare. ( ) Linda A. Walsh
  0 siblings, 2 replies; 6+ messages in thread
From: Dave Korn @ 2006-08-10 17:54 UTC (permalink / raw)
  To: '"\"${AAAARRRRRGGHHHH}\""'


    Hey all, who's any good at bash scripting?

  I've been trying for two-and-a-half hours now to make a fairly simple shell
script work, and I've been through every imaginable combination of quoting,
and nothing I've tried works.  The bash FAQ doesn't have anything to say on
the matter, nor could I figure it out from the Advanced Bash-Scripting Guide.

  I'm not a proud man, so I don't mind begging for help.  The trouble is that
I want to:

a) declare a variable which contains the date in ANSI format, then 
b) concatenate that variable and a few others into another variable, then
c) pass that other variable to a function, then finally
d) invoke the command line specified in the variable within the function.

  Sounds easy, you think?  Not quite.  There's a catch: the date string
contains a space in it.  And I can't find any way at all to get that date
string passed to the command line from within the function without that space
breaking things totally.  If I don't try and quote it, the time part of the
datestamp is taken as a separate command line argument and cvs doesn't
understand it.  If I do try and quote it, bash mangles the variable into
gibberish.  Let me demonstrate:


--------------------------------<snip>--------------------------------
#!/bin/bash
function runCvsCommand()
{
# Execute a cvs command, logging appropriately and handling errors.
echo "CVS: ${1}"

# this can take some time
echo "(cd .; ${1})"
(cd .; ${1})
RET=$?

if [ $RET -ne 0 ]
then
	echo "CAN'T '$1' STATUS $RET"
	exit 12
fi

echo "CHECKOUT $1 TO DIRECTORY $NEWDIR OK"
}

CVSCOM="cvs co"
CVSDATE="`date +'%Y-%m-%d %H:00:00'`"

CVSOPTS="-D \"${CVSDATE}\" -P" # CVSDATE has a space so must be quoted.

CVSFILES1="ieee usb"
CVSFILES2="pci wimedia"

CVSCMD1="${CVSCOM} ${CVSOPTS} ${CVSFILES1}"
CVSCMD2="${CVSCOM} ${CVSOPTS} ${CVSFILES2}"

echo "OK... CMD1 IS ${CVSCMD1} "
runCvsCommand "${CVSCMD1}"
echo "OK;; CMD2 IS ${CVSCMD2} "
runCvsCommand "${CVSCMD2}"
--------------------------------<snip>--------------------------------

  And here's what I see:

--------------------------------<snip>--------------------------------
OK... CMD1 IS cvs co -D "2006-08-10 18:00:00" -P ieee usb
CVS: cvs co -D "2006-08-10 18:00:00" -P ieee usb
(cd .; cvs co -D "2006-08-10 18:00:00" -P ieee usb)
cvs [checkout aborted]: Can't parse date/time: "2006-08-10
CAN'T 'cvs co -D "2006-08-10 18:00:00" -P ieee usb' STATUS 1
--------------------------------<snip>--------------------------------

  If I remove the escapes on the quotes in the CVSOPTS assignment, or remove
the quotes altogether, I get

--------------------------------<snip>--------------------------------
OK... CMD1 IS cvs co -D 2006-08-10 18:00:00 -P ieee usb
CVS: cvs co -D 2006-08-10 18:00:00 -P ieee usb
(cd .; cvs co -D 2006-08-10 18:00:00 -P ieee usb)
cvs server: cannot find module `18:00:00' - ignored
cvs server: cannot find module `-P' - ignored
cvs server: cannot find module `ieee' - ignored
cvs server: cannot find module `usb' - ignored
cvs [checkout aborted]: cannot expand modules
CAN'T 'cvs co -D 2006-08-10 18:00:00 -P ieee usb' STATUS 1
--------------------------------<snip>--------------------------------

  I've tried about a million combinations now and I'm getting nowhere.  I even
tried replacing the in the date with "__space__" and using "${1//__space__/ }"
in the function invocation but that didn't help either.

  I'm just not getting it.  Can anyone explain it to me?



    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: bash scripting nightmare.
  2006-08-10 17:54 bash scripting nightmare Dave Korn
@ 2006-08-10 19:49 ` mwoehlke
  2006-08-10 20:25   ` Dave Korn
  2006-08-10 23:10 ` Scripting fun! :-) (was Re: bash scripting nightmare. ( ) Linda A. Walsh
  1 sibling, 1 reply; 6+ messages in thread
From: mwoehlke @ 2006-08-10 19:49 UTC (permalink / raw)
  To: cygwin-talk

Dave Korn wrote:
>     Hey all, who's any good at bash scripting?
> 
>   I've been trying for two-and-a-half hours now to make a fairly simple shell
> script work, and I've been through every imaginable combination of quoting,
> and nothing I've tried works.  The bash FAQ doesn't have anything to say on
> the matter, nor could I figure it out from the Advanced Bash-Scripting Guide.
> 
>   I'm not a proud man, so I don't mind begging for help.  The trouble is that
> I want to:
> 
> a) declare a variable which contains the date in ANSI format, then 
> b) concatenate that variable and a few others into another variable, then
> c) pass that other variable to a function, then finally
> d) invoke the command line specified in the variable within the function.
> 
>   Sounds easy, you think?  Not quite.  There's a catch: the date string
> contains a space in it.  And I can't find any way at all to get that date
> string passed to the command line from within the function without that space
> breaking things totally.  If I don't try and quote it, the time part of the
> datestamp is taken as a separate command line argument and cvs doesn't
> understand it.  If I do try and quote it, bash mangles the variable into
> gibberish.  Let me demonstrate:
> [snip examples]

It sounds like you want to read up on arrays and "$@" (quotes included).

Here is a guess:

 > a) declare a variable which contains the date in ANSI format

MY_DATE="`data <format>`"

 > b) concatenate that variable and a few others into another variable

Don't do this. Pass in multiple parameters instead (see below).

 > c) pass that other variable to a function, then finally

myFunction "$MY_CMD" "${OPTIONS1[@]}" "$MY_DATE" $OPTIONS2

OPTIONS1 is an array that will be split and passed as positional 
parameters such that each parameter ($2, $3, etc) is exactly an item in 
the array. I.e. if the array is {foo, "bar none", cat}, then you will 
get positional parameters e.g. $2=foo, $3="bar none", $4=cat. OPTIONS2 
will be split as usual, i.e. each word will be a positional parameter.

Obviously, you could make OPTION2 an array, or OPTION1 flat, or omit one 
or both, depending on your needs.

 > d) invoke the command line specified in the variable in the function.

echo "Now running '$@':"
"$@"

If you need non-command-line parameters to the function I would pass 
them in first, copy them to 'local's, and then 'shift'.

Does that help?

-- 
Matthew
vIMprove your life! Now on version 7!

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: bash scripting nightmare.
  2006-08-10 19:49 ` mwoehlke
@ 2006-08-10 20:25   ` Dave Korn
  2006-08-10 20:40     ` mwoehlke
  0 siblings, 1 reply; 6+ messages in thread
From: Dave Korn @ 2006-08-10 20:25 UTC (permalink / raw)
  To: 'The Cygwin-Talk Maiming List'

On 10 August 2006 20:49, mwoehlke wrote:


>> [snip examples]
> 
> It sounds like you want to read up on arrays and "$@" (quotes included).

> Does that help?

  I haven't had time to try it yet, but yes, I'm sure that'll do the trick.
Thanks a bundle for the hints!


    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: bash scripting nightmare.
  2006-08-10 20:25   ` Dave Korn
@ 2006-08-10 20:40     ` mwoehlke
  2006-08-10 20:58       ` Igor Peshansky
  0 siblings, 1 reply; 6+ messages in thread
From: mwoehlke @ 2006-08-10 20:40 UTC (permalink / raw)
  To: cygwin-talk

Dave Korn wrote:
> On 10 August 2006 20:49, mwoehlke wrote:
> 
> 
>>> [snip examples]
>> It sounds like you want to read up on arrays and "$@" (quotes included).
> 
>> Does that help?
> 
>   I haven't had time to try it yet, but yes, I'm sure that'll do the trick.
> Thanks a bundle for the hints!

Glad to help!

(If you don't need the arrays, you can still be portable, too; I'm 
fairly sure "$@" is required by POSIX which means even most of the 
cruddy shells should support it. At any rate, I know *we* use it in 
portable scripts, and we run into a lot of cruddy shells :-).)

-- 
Matthew
vIMprove your life! Now on version 7!

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: bash scripting nightmare.
  2006-08-10 20:40     ` mwoehlke
@ 2006-08-10 20:58       ` Igor Peshansky
  0 siblings, 0 replies; 6+ messages in thread
From: Igor Peshansky @ 2006-08-10 20:58 UTC (permalink / raw)
  To: The Cygwin-Talk Maiming List

On Thu, 10 Aug 2006, mwoehlke wrote:

> Dave Korn wrote:
> > On 10 August 2006 20:49, mwoehlke wrote:
> >
> > > > [snip examples]
> > > It sounds like you want to read up on arrays and "$@" (quotes
> > > included).
> >
> > > Does that help?
> >
> >   I haven't had time to try it yet, but yes, I'm sure that'll do the
> > trick. Thanks a bundle for the hints!
>
> Glad to help!
>
> (If you don't need the arrays, you can still be portable, too; I'm
> fairly sure "$@" is required by POSIX which means even most of the
> cruddy shells should support it. At any rate, I know *we* use it in
> portable scripts, and we run into a lot of cruddy shells :-).)

I was also initially thinking "arrays", but supposing that you *do* need
to embed everything in one parameter, the eval builtin is your friend.
HTH,
	Igor
-- 
				http://cs.nyu.edu/~pechtcha/
      |\      _,,,---,,_	    pechtcha@cs.nyu.edu | igor@watson.ibm.com
ZZZzz /,`.-'`'    -.  ;-;;,_		Igor Peshansky, Ph.D. (name changed!)
     |,4-  ) )-,_. ,\ (  `'-'		old name: Igor Pechtchanski
    '---''(_/--'  `-'\_) fL	a.k.a JaguaR-R-R-r-r-r-.-.-.  Meow!

"Las! je suis sot... -Mais non, tu ne l'es pas, puisque tu t'en rends compte."
"But no -- you are no fool; you call yourself a fool, there's proof enough in
that!" -- Rostand, "Cyrano de Bergerac"

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Scripting fun! :-) (was Re: bash scripting nightmare. ( )
  2006-08-10 17:54 bash scripting nightmare Dave Korn
  2006-08-10 19:49 ` mwoehlke
@ 2006-08-10 23:10 ` Linda A. Walsh
  1 sibling, 0 replies; 6+ messages in thread
From: Linda A. Walsh @ 2006-08-10 23:10 UTC (permalink / raw)
  To: The Cygwin-Talk Maiming List

Dave Korn wrote:
>     Hey all, who's any good at bash scripting?
>   
---
    You are doing correctly, mostly. The simplest way to get from
where you are, to where you want to be, is, well think of this:
You have created a "command line" all stuffed into 1 variable, right?
    Ala:  VAR="cvs co -D \"2006-08-10 15:00:00\" -P pci wimedia"
The value of VAR (putting everything between two vertical bars) is:
    |cvs co -D "2006-08-10 15:00:00" -P pci wimedia|
You have a "literal" expression in "VAR", meaning the quotes are stored
as literals and have no special meaning.  If you just try to use "execute"
the literal, the arguments are passed in literally. 

    What you want is for the quotes to regain their special meaning, which
you can do by telling the shell to run it's "eval"uator over the expression
again before executing, as in "eval $VAR".  In line 9 of your code below,
just add an "eval" before the argument.
> 1  #!/bin/bash
> 2  function runCvsCommand()
> 3  {
> 4  # Execute a cvs command, logging appropriately and handling errors.
> 5  echo "CVS: ${1}"
> 6
> 7  # this can take some time
> 8  echo "(cd .;${1})" 
> 9  (cd .; eval ${1}
> 10 RET=$?
Linda

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-08-10 23:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-08-10 17:54 bash scripting nightmare Dave Korn
2006-08-10 19:49 ` mwoehlke
2006-08-10 20:25   ` Dave Korn
2006-08-10 20:40     ` mwoehlke
2006-08-10 20:58       ` Igor Peshansky
2006-08-10 23:10 ` Scripting fun! :-) (was Re: bash scripting nightmare. ( ) Linda A. Walsh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).