scripting tip needed

View: New views
7 Messages — Rating Filter:   Alert me  

scripting tip needed

by Alexandre Vieira :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi folks,

I'm having a little problem.

For exambe in ksh:

$ z=0
$ y=1
$ x=aaaa
$ eval `echo MACHINE_DISK$z[$y]`=$x
$ echo ${MACHINE_DISK0[1]}
aaaa

My problem is getting back the value of the variable using variables to
refer to the variable name (confusing). I.e $MACHINE_DISK$z[$y] .

Using ${} works great when you only have a simple array but adding a
variable in the middle of the variable name seems to ruin it.

$ echo ${MACHINE_DISK0[$y]}
aaaa
$ echo ${MACHINE_DISK$z[$y]}
ksh: ${MACHINE_DISK$z[$y]}: bad substitution

Thanks in advance for any tip
Cheers
_______________________________________________
freebsd-questions@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscribe@..."

Re: scripting tip needed

by Giorgos Keramidas :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 1 Jul 2009 18:40:00 +0100, Alexandre Vieira <nullpt@...> wrote:

> Hi folks,
>
> I'm having a little problem.
>
> For exambe in ksh:
>
> $ z=0
> $ y=1
> $ x=aaaa
> $ eval `echo MACHINE_DISK$z[$y]`=$x
> $ echo ${MACHINE_DISK0[1]}
> aaaa
>
> My problem is getting back the value of the variable using variables to
> refer to the variable name (confusing). I.e $MACHINE_DISK$z[$y] .
>
> Using ${} works great when you only have a simple array but adding a
> variable in the middle of the variable name seems to ruin it.
>
> $ echo ${MACHINE_DISK0[$y]}
> aaaa
> $ echo ${MACHINE_DISK$z[$y]}
> ksh: ${MACHINE_DISK$z[$y]}: bad substitution

My own short piece of (slightly off-topic) advice is:

  ``If you find yourself using arrays in bash, ksh or another shell,
  now is a *very* good time to consider a more advanced scripting
  language, like Perl or Python.''

Trying to coerce shell quoting to do a sensible thing with array syntax
is error-prone, annoying and --very often-- a waste of your time:

Using an interactive language like Python you can actually *test* the
code as you are writing it.  This is a major win most of the time.

_______________________________________________
freebsd-questions@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscribe@..."

Re: scripting tip needed

by Wojciech Puchar-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>
> $ echo ${MACHINE_DISK0[$y]}
> aaaa
> $ echo ${MACHINE_DISK$z[$y]}
> ksh: ${MACHINE_DISK$z[$y]}: bad substitution
>
> Thanks in advance for any tip

install bash :)
_______________________________________________
freebsd-questions@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscribe@..."

Re: scripting tip needed

by Wojciech Puchar-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Using an interactive language like Python you can actually *test* the
> code as you are writing it.  This is a major win most of the time.

could you explain what you mean? You can and you have to test a code on
any language be it bash, ksh python or C
_______________________________________________
freebsd-questions@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscribe@..."

Re: scripting tip needed

by Giorgos Keramidas :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 1 Jul 2009 22:02:48 +0200 (CEST), Wojciech Puchar <wojtek@...> wrote:
>> Using an interactive language like Python you can actually *test* the
>> code as you are writing it.  This is a major win most of the time.
>
> could you explain what you mean? You can and you have to test a code on
> any language be it bash, ksh python or C

Yes.  I mean that one can directly interact with the interpret in a REPL
prompt, doing stuff like:

    >>> import re
    >>> devre = re.compile(r'(/dev/\S+)\s+(\S+)\s.*$')
    >>> devre
    <_sre.SRE_Pattern object at 0x28462780>
    >>> devre.match('/dev/ad0s1d 1012974 390512 541426 42% /var')
    <_sre.SRE_Match object at 0x28432e78>
    >>> devre.match('/dev/ad0s1d 1012974 390512 541426 42% /var').groups()
    ('/dev/ad0s1d', '1012974')
    >>> devre =
    >>> re.compile(r'(/dev/\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*$')
    >>> devre.match('/dev/ad0s1d 1012974 390512 541426 42% /var').groups()
    ('/dev/ad0s1d', '1012974', '390512', '541426', '42%', '/var')

See how I am 'refining' the initial regular expression without ever
leaving the Python prompt?  That sort of interactivity is entirely lost
when you have to edit a file, save it, switch screen(1) windows or type
^Z to background the editor, run a script, watch it fail and repeat.

Then I can keep testing bits and pieces of code:

    >>> from subprocess import Popen, PIPE
    >>> pipe = Popen(['df', '-k'], shell=False, stdout=PIPE).stdout
    >>> for l in pipe:
    ...     m = devre.match(l)
    ...     if m:
    ...         print "device %s, size %ld KB" % (m.group(1), long(m.group(2)))
    ...
    device /dev/ad0s1a, size 1012974 KB
    device /dev/ad0s1d, size 1012974 KB
    device /dev/ad0s1e, size 2026030 KB
    device /dev/ad0s1f, size 10154158 KB
    device /dev/ad0s1g, size 284455590 KB
    device /dev/md0, size 19566 KB
    >>>

So piping df output to a Python bit of code works!  That's nice.  Then
once I have a 'rough idea' of how I want the script to work, I can
refactor a bit the repetitive bits:

    >>> def devsize(line):
    ...     m = devre.match(line)
    ...     if m:
    ...         return (m.group(1), m.group(2))
    ...
    >>> devsize('/dev/ad0s1d 1012974 390512 541426 42% /var')
    ('/dev/ad0s1d', '1012974')

So here's a short function to return a nice 2-item tuple with two values
(device name, number of 1 KB blocks).  Can we pipe df output through it?

    >>> pipe = Popen(['df', '-k'], shell=False, stdout=PIPE).stdout
    >>> pipe = Popen(['df', '-k'], shell=False, stdout=PIPE).stdout
    >>> map(devsize, pipe.readlines())
    [ None, ('/dev/ad0s1a', '1012974'), None, ('/dev/ad0s1d', '1012974'),
      ('/dev/ad0s1e', '2026030'), ('/dev/ad0s1f', '10154158'),
      ('/dev/ad0s1g', '284455590'), None, None, None, None, None, None,
      None, None, None, None, None, None, None, None,
      ('/dev/md0', '19566'), None]
    >>>

It looks we can do that too, but the tuple list may be more useful if we
trim the null items in the process:

    >>> pipe = Popen(['df', '-k'], shell=False, stdout=PIPE).stdout
    >>> [t for t in map(devsize, pipe.readlines()) if t]
    [ ('/dev/ad0s1a', '1012974'), ('/dev/ad0s1d', '1012974'),
      ('/dev/ad0s1e', '2026030'), ('/dev/ad0s1f', '10154158'),
      ('/dev/ad0s1g', '284455590'), ('/dev/md0', '19566') ]

So there it is.  A nice structure, supported by the core of the
language, using a readable, easy syntax, and listing all the /dev nodes
of my laptop along with their sizes in KBytes.

The entire thing was built 'piece by piece', in the same Python session,
and I now have not only a 'rough idea' of how the code should work, but
also a working copy of the code in my history.

Note the complete *lack* of care about how to append to a list, how to
create dynamic pairs of devicename-size tuples, how to map all elements
of a list through a function, and more importantly the complete and
utter lack of any sort of '"${[]}"' quoting for variable names, values,
nested expansions, and so on.

That's what I am talking about.  Shell scripts are nice, but if we are
not constrained for some reason to use only /bin/sh or ksh, there's no
excuse for wasting hours upon hours to decipher cryptic quoting rules
and exceptional edge-cases of "black quoting magic", just to get a short
job done.  Being able to _easily_ use higher level structures than a
plain 'stream of bytes' is nice :)


_______________________________________________
freebsd-questions@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscribe@..."

Re: scripting tip needed

by Alexandre Vieira :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Jul 1, 2009 at 10:07 PM, Giorgos Keramidas <keramida@...
> wrote:

> On Wed, 1 Jul 2009 22:02:48 +0200 (CEST), Wojciech Puchar <
> wojtek@...> wrote:
> >> Using an interactive language like Python you can actually *test* the
> >> code as you are writing it.  This is a major win most of the time.
> >
> > could you explain what you mean? You can and you have to test a code on
> > any language be it bash, ksh python or C
>
> Yes.  I mean that one can directly interact with the interpret in a REPL
> prompt, doing stuff like:
>
>    >>> import re
>    >>> devre = re.compile(r'(/dev/\S+)\s+(\S+)\s.*$')
>    >>> devre
>    <_sre.SRE_Pattern object at 0x28462780>
>    >>> devre.match('/dev/ad0s1d 1012974 390512 541426 42% /var')
>    <_sre.SRE_Match object at 0x28432e78>
>    >>> devre.match('/dev/ad0s1d 1012974 390512 541426 42% /var').groups()
>    ('/dev/ad0s1d', '1012974')
>    >>> devre =
>    >>> re.compile(r'(/dev/\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*$')
>    >>> devre.match('/dev/ad0s1d 1012974 390512 541426 42% /var').groups()
>    ('/dev/ad0s1d', '1012974', '390512', '541426', '42%', '/var')
>
> See how I am 'refining' the initial regular expression without ever
> leaving the Python prompt?  That sort of interactivity is entirely lost
> when you have to edit a file, save it, switch screen(1) windows or type
> ^Z to background the editor, run a script, watch it fail and repeat.
>
> Then I can keep testing bits and pieces of code:
>
>    >>> from subprocess import Popen, PIPE
>    >>> pipe = Popen(['df', '-k'], shell=False, stdout=PIPE).stdout
>    >>> for l in pipe:
>    ...     m = devre.match(l)
>    ...     if m:
>    ...         print "device %s, size %ld KB" % (m.group(1),
> long(m.group(2)))
>    ...
>    device /dev/ad0s1a, size 1012974 KB
>    device /dev/ad0s1d, size 1012974 KB
>    device /dev/ad0s1e, size 2026030 KB
>    device /dev/ad0s1f, size 10154158 KB
>    device /dev/ad0s1g, size 284455590 KB
>    device /dev/md0, size 19566 KB
>    >>>
>
> So piping df output to a Python bit of code works!  That's nice.  Then
> once I have a 'rough idea' of how I want the script to work, I can
> refactor a bit the repetitive bits:
>
>    >>> def devsize(line):
>    ...     m = devre.match(line)
>    ...     if m:
>    ...         return (m.group(1), m.group(2))
>    ...
>    >>> devsize('/dev/ad0s1d 1012974 390512 541426 42% /var')
>    ('/dev/ad0s1d', '1012974')
>
> So here's a short function to return a nice 2-item tuple with two values
> (device name, number of 1 KB blocks).  Can we pipe df output through it?
>
>    >>> pipe = Popen(['df', '-k'], shell=False, stdout=PIPE).stdout
>    >>> pipe = Popen(['df', '-k'], shell=False, stdout=PIPE).stdout
>    >>> map(devsize, pipe.readlines())
>    [ None, ('/dev/ad0s1a', '1012974'), None, ('/dev/ad0s1d', '1012974'),
>      ('/dev/ad0s1e', '2026030'), ('/dev/ad0s1f', '10154158'),
>      ('/dev/ad0s1g', '284455590'), None, None, None, None, None, None,
>      None, None, None, None, None, None, None, None,
>      ('/dev/md0', '19566'), None]
>    >>>
>
> It looks we can do that too, but the tuple list may be more useful if we
> trim the null items in the process:
>
>    >>> pipe = Popen(['df', '-k'], shell=False, stdout=PIPE).stdout
>    >>> [t for t in map(devsize, pipe.readlines()) if t]
>    [ ('/dev/ad0s1a', '1012974'), ('/dev/ad0s1d', '1012974'),
>      ('/dev/ad0s1e', '2026030'), ('/dev/ad0s1f', '10154158'),
>      ('/dev/ad0s1g', '284455590'), ('/dev/md0', '19566') ]
>
> So there it is.  A nice structure, supported by the core of the
> language, using a readable, easy syntax, and listing all the /dev nodes
> of my laptop along with their sizes in KBytes.
>
> The entire thing was built 'piece by piece', in the same Python session,
> and I now have not only a 'rough idea' of how the code should work, but
> also a working copy of the code in my history.
>
> Note the complete *lack* of care about how to append to a list, how to
> create dynamic pairs of devicename-size tuples, how to map all elements
> of a list through a function, and more importantly the complete and
> utter lack of any sort of '"${[]}"' quoting for variable names, values,
> nested expansions, and so on.
>
> That's what I am talking about.  Shell scripts are nice, but if we are
> not constrained for some reason to use only /bin/sh or ksh, there's no
> excuse for wasting hours upon hours to decipher cryptic quoting rules
> and exceptional edge-cases of "black quoting magic", just to get a short
> job done.  Being able to _easily_ use higher level structures than a
> plain 'stream of bytes' is nice :)
>
>
>
Guys,

I eventually found it with lots of rtfm on variable substitution and such..

[ne@dada~]$ z=0
[ne@dada~]$ y=1
[ne@dada~]$ x=aaa
[ne@dada~]$ eval `echo MACHINE_DISK$z[$y]`=$x
[ne@dada~]$ echo $(eval echo \${MACHINE_DISK$z[$y]})
aaa
[ne@dada~]$

Thanks anyway!


--
Alexandre Vieira - nullpt@...
_______________________________________________
freebsd-questions@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscribe@..."

Re: scripting tip needed

by evuraan::ഏവൂരാന് :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

good thing you found the answer. I am glad you did, and oh, I am more  glad
that you found your solution  on ksh itself and not on "advanced scripting
language, like Perl or Python.''



> Guys,
>
> I eventually found it with lots of rtfm on variable substitution and such..
>
> [ne@dada~]$ z=0
> [ne@dada~]$ y=1
> [ne@dada~]$ x=aaa
> [ne@dada~]$ eval `echo MACHINE_DISK$z[$y]`=$x
> [ne@dada~]$ echo $(eval echo \${MACHINE_DISK$z[$y]})
> aaa
> [ne@dada~]$
>
> Thanks anyway!
>
>
> --
>
_______________________________________________
freebsd-questions@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscribe@..."