edit-and-execute-command is appropriately named, weird

2011-05-24 Thread David Thomas
Hi all,

In using bash over the years, I've been quite happy to be able to hit
ctrl-x ctrl-e to pull up an editor when my input has grown too
complicated.

When using read -e for input, however, the behavior I find makes a lot
less sense: the input line is still opened in an editor, but the
result is not processed by read - it is executed by bash.  While a
means to escape to the shell can certainly be useful it seems like it
should generally be done in a more controlled environment.  It is much
harder to reason about my scripts when arbitrary variables might be
overwritten just because I asked for input.  In any case I'm not sure
it makes sense to conflate this with the "open this line in an editor"
command.

I'm curious as to the reasoning was behind this behavior (if it was
intentional), and whether I'm likely to break anything if I "fix" it.

Thanks!



Re: Document what's allowed in function names

2011-05-24 Thread Stephane CHAZELAS
2011-04-11, 09:51(-04), Chet Ramey:
>> Machine Type: i686-pc-linux-gnu
>> 
>> Bash Version: 4.2
>> Patch Level: 8
>> Release Status: release
>> 
>> Description:
>>  man bash is currently lacking information on what is allowed for 
>> function
>>  names. It implies name with name () compound-command [redirection] and
>>  at the start of the manual there is:
>> 
>>  name   A word consisting only of alphanumeric characters and 
>> underscores,
>>  and beginning with an alphabetic character or an underscore.  Also 
>> referred
>>  to as an identifier.
>> 
>>  In reality the rules for function names are much more loose. For example
>>  hyphen and forward slash are allowed. But there are still some 
>> restrictions:
>>  bash: `aa\'foo': not a valid identifier
>
> It was a mistake to allow such characters in function names (`unset' doesn't
> work to unset them without forcing -f, for instance).  We're stuck with them
> for backwards compatibility, but I don't have to encourage their use.
[...]

Why would you put any restriction on the allowed name of a function?

At calling time, it's the same namespace as an argv[0] so any
arg so could be any string.

In zsh, any string is allowed including the empty string (and
allowing the NUL character as that is allowed in arguments to
functions or built-in commands).

$ ''()echo foo
$ ""
foo
$ /bin/ls() echo bar
$ /bin/ls
bar

-- 
Stephane


Re: bash trap techniques for group-command in a pipeline

2011-05-24 Thread john.ruckstuhl
Solution... this works nicely:

# print opening html
echo ""

# on error, print msg and exit $STATUS
trap myERRhandler ERR
myERRhandler () {
local STATUS=$?
printf "Trouble: trapped ERR, exiting %s\n" $STATUS >& 2
exit $STATUS
}

# on exit, print closing html
trap myEXIThandler EXIT
myEXIThandler () {
echo ""
}

mySubshellERRhandler () {
local STATUS=$?
exit $STATUS
}

myreturn() { return $1; }

echo cmd1

set -o pipefail
{
trap mySubshellERRhandler ERR
echo cmd2
echo "cmd3 (with exit code 6)"; myreturn 6
echo cmd4
} | tr a-z A-Z

echo cmd5

Regards,
John Ruckstuhl


On Apr 2, 12:50 pm, "john.ruckstuhl"  wrote:
> Summary: I don't see the best way to (in bash) trap/handle an ERR
> inside
> a group-command "{}" that is in a pipeline.  I have a way that seems
> to
> work, see "(F)", but little confidence that it's the best way, and
> some
> suspicion that the overall effort is misguided.
>
> Detail:
> I'd like to trap and handle trouble during a bash script.
> By trapping ERR, I am successful handling trouble -- when commands
> are
> simple and not part of a pipeline.
>     (A)
>         cmd1; cmd2; trouble; cmd4; cmd5
>
> But I'd like to also filter the output of these commands...
> My trap scheme successfully handles
>     (B)
>         cmd1; { cmd2; trouble; cmd4; }; cmd5
> but fails to handle
>     (C)
>         cmd1; { cmd2; trouble; cmd4; } | filter; cmd5
>
> (I've also explored killing $$ (see (D)), which exits at the right
> place
> but doesn't return the proper status)
>
> Is this an expected limitation?
> Is there a workaround?
>
> Ahhh, further reading & research informs me of "pipefail", and leads
> me
> to set another trap inside the "{}".
> So, now (F) seems to work for me...
> Any comments will be appreciated -- Is there a better way?
> Or perhaps there are uncaught conditions and I've developed a false
> sense of security?
> See below for simple test script demonstrating implementations A - F,
> with cmd3 returning non-zero (or zero).
>
> My bash is version 3.2.51(24)-release (i686-pc-cygwin)
> Demonstrate as follows...
> 1st arg is the implementation variant,
> 2nd arg is the exit status of the middle command.
>
> # define simple wrapping function for "try" script
>     $ mytry () { ./try $1 $2; echo dbg: script exit status: $?; }
>
> # (A) This works.  The implementation of (A) is:
> #         trap myERRhandler ERR
> #         trap myEXIThandler EXIT
> #         cmd1; cmd2; cmd3; cmd4; cmd5
>
>     $ mytry A 0  # third cmd in series returns 0
>     $ mytry A 6  # third cmd in series returns 6, so abend immediately
>
> # (B) This works.   The implementation of (B) is:
> #         trap myERRhandler ERR
> #         trap myEXIThandler EXIT
> #         cmd1; { cmd2; cmd3; cmd4; }; cmd5
>
>     $ mytry B 0
>     $ mytry B 6
>
> # (C) This doesn't abend when it should.  The implementation of (C)
> is:
> #         trap myERRhandler ERR
> #         trap myEXIThandler EXIT
> #         cmd1; { cmd2; cmd3; cmd4; } | filter; cmd5
>
>     $ mytry C 0
>     $ mytry C 6
>
> # (D) This abends when it should, but on trouble, script exits 0
> #         trap myERRhandler ERR
> #         trap myEXIThandler EXIT
> #         cmd1
> #
> #         trap myERRhandler HUP
> #         { cmd2 && cmd3 && cmd4 || kill -HUP $$; } | filter
> #
> #         cmd5
>
>     $ mytry D 0
>     $ mytry D 6
>
> # (E) This abends when it should, but on trouble, runs myERRhandler
> twice.
> #         trap myERRhandler ERR
> #         trap myEXIThandler EXIT
> #         set -o pipefail
> #         cmd1; { trap myERRhandler ERR; cmd2; cmd3; cmd4; } | filter;
> cmd5
>
>     $ mytry E 0
>     $ mytry E 6
>
> # (F) This seems to work... :)
> #         trap myERRhandler ERR
> #         trap myEXIThandler EXIT
> #         set -o pipefail
> #         cmd1
> #         { trap myOtherERRhandler ERR; cmd2; cmd3; cmd4; } | filter
> #         cmd5
>
>     $ mytry F 0
>     $ mytry F 6
>
> where try contains:
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> #! c:\cygwin\bin\bash
>
> # print opening html
> echo ""
>
> # on error, print msg and exit $STATUS
> trap myERRhandler ERR
> myERRhandler () {
>     STATUS=$?
>     echo "dbg: entered myERRhandler() -- (on error, print msg and exit
> $STATUS)"
>     echo "trouble..."
>     exit $STATUS
>
> }
>
> # on exit, print closing html
> trap myEXIThandler EXIT
> myEXIThandler () {
>     echo "dbg: entered myEXIThandler() -- (on exit, print closing
> html)"
>     echo ""
>
> }
>
> myreturn() { return $1; }
>
> echo cmd1
>
> case $1 in
> A)
>     # THIS WORKS
>     echo cmd2
>     echo "cmd3 (with exit code $2)"; myreturn $2
>     echo cmd4
> ;;
>
> B)
>     # THIS WORKS
>     {
>         echo cmd2
>         echo "cmd3 (with exit code $2)"; myreturn $2
>         echo cmd4
>     }
> ;;
>
> C)
>     # THIS DOESN'T ABEND WHEN IT SHOULD
>     {

Re: Document what's allowed in function names

2011-05-24 Thread Chet Ramey
> 2011-04-11, 09:51(-04), Chet Ramey:
> >> Machine Type: i686-pc-linux-gnu
> >> 
> >> Bash Version: 4.2
> >> Patch Level: 8
> >> Release Status: release
> >> 
> >> Description:
> >>man bash is currently lacking information on what is allowed for 
> >> function
> >>names. It implies name with name () compound-command [redirection] and
> >>at the start of the manual there is:
> >> 
> >>name   A word consisting only of alphanumeric characters and 
> >> underscores,
> >>and beginning with an alphabetic character or an underscore.  Also 
> >> referred
> >>to as an identifier.
> >> 
> >>In reality the rules for function names are much more loose. For example
> >>hyphen and forward slash are allowed. But there are still some 
> >> restrictions:
> >>bash: `aa\'foo': not a valid identifier
> >
> > It was a mistake to allow such characters in function names (`unset' doesn't
> > work to unset them without forcing -f, for instance).  We're stuck with them
> > for backwards compatibility, but I don't have to encourage their use.
> [...]
> 
> Why would you put any restriction on the allowed name of a function?

(Wow, this message took a long time getting here.)

Because Posix does, and because unset without -f has to enforce the variable
name restrictions.  (Though the language has been relaxed in the latest
standard.)

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/