Re: Compare 2 arrays.

2012-05-30 Thread Greg Wooledge
On Tue, May 29, 2012 at 09:25:02PM -0600, Bill Gradwohl wrote:
> I have no idea what the wget's are supposed to be doing, but here's a
> function that will compare 2 foreign arrays and return true 0 or false 1.
> 
> compareForeignArrays(){
>## $1 and $2 are the names of the arrays to compare.
>## These are characters strings.
> 
>local intermediary
>local sub
> 
>intermediary="${1}[@]"
>local -a leftValue=("${!intermediary}")

Hacks like this are precisely why I stress that such functions *should
not* be written in bash.  If you want to compare two arrays, use a loop,
without wrapping a function around it.  That way you have access to the
arrays directly, by their actual names, in the actual context where they
are defined.

The only Bourne-family shell that can manipulate arrays whose names are
passed to a function is ksh93, with its "nameref" command.  Bash has
nothing analogous to that yet.

I don't know whether the tmp="$1[@]"; x=("${!tmp}") trick is a bug or
a feature.  It's certainly undocumented.  I don't know whether it will
go away in some future version of bash, with or without a notification in
the changelog, since it looks like a bug that people are exploiting.



Re: Red-Hat Bug 825751 - bash-completion fails on environment variables

2012-05-30 Thread DJ Mills
On Tue, May 29, 2012 at 8:34 AM, John E. Malmberg  wrote:
>
> On this platform, file names with $ in them tend to show up as they have
> special meaning.
>
> BASH-4.2$ echo *\$*
> GNV$BASH.DSF GNV$BASH.EXE GNV$BASH.MAP GNV$SHELL.C_FIRST GNV$VERSION.C_FIRST
> gnv$bash_startup.com gnv$main_wrapper gnv$vms_main_link.exe
>
> Regards,
> -John
>

Pathname expansion doesn't perform any escaping... this is a
completely separate thing from the readline tab completion issue.

touch 'foo bar' 'baz blah'; echo *\ *
baz blah foo bar

echo takes its arguments and concatenates them with spaces... using
printf can show that they're properly escaped.
touch 'foo bar' 'baz blah'; printf '<%s> ' *\ *; echo
 



Re: Compare 2 arrays.

2012-05-30 Thread Bill Gradwohl
On Wed, May 30, 2012 at 6:33 AM, Greg Wooledge  wrote:

>
> Hacks like this are precisely why I stress that such functions *should
> not* be written in bash.  If you want to compare two arrays, use a loop,
> without wrapping a function around it.  That way you have access to the
> arrays directly, by their actual names, in the actual context where they
> are defined.
>

The term hack is used when something is in dispute - is it a bug or a
feature? If a bug, has it been declared so and will it get fixed? So many
things in bash are undocumented so the complete feature list is
indeterminate.

So, If I have several arrays to test, I should duplicate the code once for
each array?
I shouldn't put it into a function but instead I should reinvent the wheel
every time I need this?

Admittedly, bash doesn't go out of its way to highlight this technique, but
it does work.

What say you Chet? Bug or feature? There is no middle ground.


> The only Bourne-family shell that can manipulate arrays whose names are
> passed to a function is ksh93, with its "nameref" command.  Bash has
> nothing analogous to that yet.
>

I believe we're quibbling over the officialness of the solution I provided
to the poster. Obviously bash does support a way of manipulating a foreign
array. I'd like it to be more obvious with something like a nameref as you
suggest, but it's not there.

Every disto I know of uses bash as its default. That's why people use it -
because its suggested by the disto assemblers and because it's there. Bash
is part of the GNU family and many people mistakenly think of GNU as Linux.
By extension, bash has tremendous mind share, is prominently featured and
is what people expect. In the 12 years I've used Linux exclusively, I've
never used any shell but bash.

I wish bash had something akin to C pointers and address arithmetic.
I wish it had pass by reference.
I wish it had a C style prototype as a function definition.
I wish I could set a shopt that would fail a script for an undeclared
variable.
I wish it could return more than just an 8 bit return code.
I wish it had a more robust concept of name space so variables wouldn't
bump into each other.
I wish local really meant local and something further on down the call
chain couldn't access it.
I wish sub functions were hidden from the outside world and only accessible
from within the containing function.

I wish bash had lots of things it doesn't, and yet it does a fine job as a
command interpreter. I have to find alternatives for what I want or need,
but they are there.

...there are dark corners in the Bourne shell, and people use all of them.
-- Chet Ramey

I'm just using one of those dark corners.

-- 
Bill Gradwohl


Re: Compare 2 arrays.

2012-05-30 Thread Greg Wooledge
On Wed, May 30, 2012 at 10:14:42AM -0600, Bill Gradwohl wrote:
> What say you Chet? Bug or feature? There is no middle ground.

That's unrealistic.  There are plenty of things that occupy that middle
ground -- unexpected program behaviors.  The programmer can never
anticipate *every* input sequence that users will throw at the software,
so some of them may cause surprises.

The danger of using unexpected program behaviors in your applications
is that the behaviors may change without warning in a future version of
the program.  The programmer may not even be aware that this behavior
exists, let alone that people are using it.  A clean-up of the parser
(or similar change) may make the behavior go away, or change.

http://mywiki.wooledge.org/BashFAQ/006 has this to say on the matter
(right after demonstrating ksh93's nameref):

  We are not aware of any trick that can duplicate that functionality
  in POSIX or Bourne shells (short of using eval, which is extremely
  difficult to do securely). Bash can almost do it -- some indirect
  array tricks work, and others do not, and we do not know whether the
  syntax involved will remain stable in future releases. So, consider
  this a use at your own risk hack.

  # Bash -- trick #1.  Seems to work in bash 2 and up.
  realarray=(...) ref=realarray; index=2
  tmp="$ref[$index]"
  echo "${!tmp}"# gives array element [2]

  # Bash -- trick #2.  Seems to work in bash 3 and up.
  # Does NOT work in bash 2.05b.
  tmp="$ref[@]"
  printf "<%s> " "${!tmp}"; echo# Iterate whole array.

I added that on 2011-05-02 after Buglouse described it on IRC.  I'm fairly
certain that EVERYONE else in the channel at the time was as surprised
by it as I was.



Re: Compare 2 arrays.

2012-05-30 Thread Bill Gradwohl
On Wed, May 30, 2012 at 10:57 AM, Greg Wooledge  wrote:

> There are plenty of things that occupy that middle
> ground -- unexpected program behaviors.  The programmer can never
> anticipate *every* input sequence that users will throw at the software,
> so some of them may cause surprises.
>
> True enough!

Where is it written that this is not legitimate? Where is it written that
it is? In the absence of formal documentation one way or the other, the
product itself arbitrates the matter. In this case bash says its legit
because it works.

Once something has been identified as belonging in that gray area, a
determination has to be made one way or the other as to what to do about
it. Leaving it unresolved adds uncertainty which is never a good thing.

Clearly this "feature" is a needed part of the language. Coding around its
non existence is either impossible in your case or as you say, a hack in
mine. So do we simply stop and hold our collective breath till X number of
releases go by to see what happened or do we get a determination? I would
prefer something cleaner and well documented, but I'll use what is
available till then.

To change bash to search out the existing capability and stop it would be
counter productive. The same effort could probably provide a documented new
feature similar to nameref in ksh. I'd use that feature in an instant if it
were available.

The danger of using unexpected program behaviors in your applications
> is that the behaviors may change without warning in a future version of
> the program.  The programmer may not even be aware that this behavior
> exists, let alone that people are using it.  A clean-up of the parser
> (or similar change) may make the behavior go away, or change.
>
>
You say it's unexpected behavior. I'll agree it's using what the product
provides in a way that isn't obvious, but why is that necessarily bad? If
it goes away in the future, I expect it will do so because something
documented replaced it. Progress demands that the next release should be at
least as capable as the current one and since the current one provides
access to a foreign array as I demonstrated, the next release should also.
Hopefully well documented.

Using the tool you have now and doing something is better than waiting and
doing nothing in the interim.

-- 
Bill Gradwohl


bashref.texi typos

2012-05-30 Thread Andreas Schwab
diff --git a/doc/bashref.texi b/doc/bashref.texi
index 19c56c1..9fa99dc 100644
--- a/doc/bashref.texi
+++ b/doc/bashref.texi
@@ -1795,7 +1795,7 @@ Bash uses the value of the variable formed from the rest 
of
 expanded and that value is used in the rest of the substitution, rather
 than the value of @var{parameter} itself.
 This is known as @code{indirect expansion}.
-The exceptions to this are the expansions of $@{!@var{prefix}@*@}
+The exceptions to this are the expansions of $@{!@var{prefix}*@}
 and $@{!@var{name}[@@]@}
 described below.
 The exclamation point must immediately follow the left brace in order to
@@ -8053,7 +8053,7 @@ which matches @var{pattern} and replaces it with 
@var{replacement} in
 the value of @code{var}, is available (@pxref{Shell Parameter Expansion}).
 
 @item
-The expansion @code{$@{!@var{prefix@}*}} expansion, which expands to
+The expansion @code{$@{!@var{prefix*@}}}, which expands to
 the names of all shell variables whose names begin with @var{prefix},
 is available (@pxref{Shell Parameter Expansion}).
 
-- 
1.7.10.3


Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



Bash-4.2 Official Patch 29

2012-05-30 Thread Chet Ramey
 BASH PATCH REPORT
 =

Bash-Release:   4.2
Patch-ID:   bash42-029

Bug-Reported-by:"Michael Kalisz" 
Bug-Reference-ID:   
<50241.78.69.11.112.1298585641.squir...@kalisz.homelinux.net>
Bug-Reference-URL:  
http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00274.html

Bug-Description:

Bash-4.2 tries to leave completed directory names as the user typed them,
without expanding them to a full pathname.  One effect of this is that
shell variables used in pathnames being completed (e.g., $HOME) are left
unchanged, but the `$' is quoted by readline because it is a special
character to the shell.

This patch introduces two things:

1.  A new shell option, `direxpand', which, if set, attempts to emulate the
bash-4.1 behavior of expanding words to full pathnames during
completion;
2.  A set of heuristics that reduce the number of times special characters
such as `$' are quoted when the directory name is not expanded.

Patch (apply with `patch -p0'):

diff -NrC 2 ../bash-4.2-patched/bashline.c ./bashline.c
*** ../bash-4.2-patched/bashline.c  2011-01-16 15:32:47.0 -0500
--- ./bashline.c2012-05-07 16:27:18.0 -0400
***
*** 122,125 
--- 122,128 
  static int bash_push_line __P((void));
  
+ static rl_icppfunc_t *save_directory_hook __P((void));
+ static void reset_directory_hook __P((rl_icppfunc_t *));
+ 
  static void cleanup_expansion_error __P((void));
  static void maybe_make_readline_line __P((char *));
***
*** 244,251 
--- 247,261 
  int dircomplete_spelling = 0;
  
+ /* Expand directory names during word/filename completion. */
+ int dircomplete_expand = 0;
+ int dircomplete_expand_relpath = 0;
+ 
  static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
  static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
  /* )) */
  
+ static const char *default_filename_quote_characters = " 
\t\n\\\"'@<>=;|&()#$`?*[!:{~";   /*}*/
+ static char *custom_filename_quote_characters = 0;
+ 
  static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
  
***
*** 502,506 
/* Tell the completer that we might want to follow symbolic links or
   do other expansion on directory names. */
!   rl_directory_rewrite_hook = bash_directory_completion_hook;
  
rl_filename_rewrite_hook = bash_filename_rewrite_hook;
--- 512,516 
/* Tell the completer that we might want to follow symbolic links or
   do other expansion on directory names. */
!   set_directory_hook ();
  
rl_filename_rewrite_hook = bash_filename_rewrite_hook;
***
*** 530,534 
  
/* characters that need to be quoted when appearing in filenames. */
!   rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/
  
rl_filename_quoting_function = bash_quote_filename;
--- 540,544 
  
/* characters that need to be quoted when appearing in filenames. */
!   rl_filename_quote_characters = default_filename_quote_characters;
  
rl_filename_quoting_function = bash_quote_filename;
***
*** 565,570 
rl_attempted_completion_function = attempt_shell_completion;
rl_completion_entry_function = NULL;
-   rl_directory_rewrite_hook = bash_directory_completion_hook;
rl_ignore_some_completions_function = filename_completion_ignore;
  }
  
--- 575,582 
rl_attempted_completion_function = attempt_shell_completion;
rl_completion_entry_function = NULL;
rl_ignore_some_completions_function = filename_completion_ignore;
+   rl_filename_quote_characters = default_filename_quote_characters;
+ 
+   set_directory_hook ();
  }
  
***
*** 1280,1283 
--- 1292,1298 
rl_ignore_some_completions_function = filename_completion_ignore;
  
+   rl_filename_quote_characters = default_filename_quote_characters;
+   set_directory_hook ();
+ 
/* Determine if this could be a command word.  It is if it appears at
   the start of the line (ignoring preceding whitespace), or if it
***
*** 1592,1595 
--- 1607,1616 
  else
{
+if (dircomplete_expand && dot_or_dotdot (filename_hint))
+   {
+ dircomplete_expand = 0;
+ set_directory_hook ();
+ dircomplete_expand = 1;
+   }
  mapping_over = 4;
  goto inner;
***
*** 1792,1795 
--- 1813,1819 
   inner:
val = rl_filename_completion_function (filename_hint, istate);
+   if (mapping_over == 4 && dircomplete_expand)
+ set_directory_hook ();
+ 
istate = 1;
  
***
*** 2694,2697 
--- 2718,2767 
  }
  
+ /* Functions to save and restore the appropriate directory hook */
+ /* This is not static so the shopt code can call it */
+ void
+ set_directory_hook ()
+ {
+   if (dircomplete_expand)
+ {
+   rl_director

Re: Segfault on compound assignment to a variable whose name is set in the environment of a declaration builtin.

2012-05-30 Thread Chet Ramey
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 5/18/12 2:08 PM, Dan Douglas wrote:
> Hi Chet, segfault occurs during array assignment if an attempt is made to 
> modify a
> variable of the same name from the environment. It appears to only occur in 
> the global scope.
> I imagine the expected result should be either an error, or to evaluate in a 
> mannar similar to
> `x=1 let "x[x++]=x"', for example.

Thanks for the report.  It only happens in an arithmetic expression
context.

> Thanks again. (not overly anxious for a fix.)

OK, it will be fixed in the next release.

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/
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk/G1KkACgkQu1hp8GTqdKvsdQCeM8MTYW5WM+XbWs6JQ4xIL8le
WjEAnjwBOzLpjUF8XbpzZNRNuwU+Fth4
=1m7x
-END PGP SIGNATURE-



Re: Compare 2 arrays.

2012-05-30 Thread Dan Douglas
On Wed, May 30, 2012 at 4:57 PM, Greg Wooledge  wrote:
>
> On Wed, May 30, 2012 at 10:14:42AM -0600, Bill Gradwohl wrote:
> > What say you Chet? Bug or feature? There is no middle ground.
>
> That's unrealistic.  There are plenty of things that occupy that middle
> ground -- unexpected program behaviors.  The programmer can never
> anticipate *every* input sequence that users will throw at the software,
> so some of them may cause surprises.

Since variable names treated as strings can cause execution of
arbitrary code in Bash, mixing them with user input isn't usually
possible anyway. However, that's irrelevant to whether this kind of
expansion is a bug.

> The danger of using unexpected program behaviors in your applications
> is that the behaviors may change without warning in a future version of
> the program.  The programmer may not even be aware that this behavior
> exists, let alone that people are using it.  A clean-up of the parser
> (or similar change) may make the behavior go away, or change.

That is true, but I don't think this particular thing is unexpected.
Hopefully it doesn't change unless it's replaced by something better,
because it's extremely useful.

> ...
> I added that on 2011-05-02 after Buglouse described it on IRC.  I'm fairly
> certain that EVERYONE else in the channel at the time was as surprised
> by it as I was.
>

I think they shouldn't have been surprised. Here it is described on
stackoverflow prior to that date:
http://stackoverflow.com/a/4017175/495451

I don't understand why you continue to consider this a possible bug.
The manual only has a couple sentences to say about indirect
expansion:

"If the first character of parameter is an exclamation point (!), a
level of variable indirection is introduced.Bash uses the value of
the variable formed from the rest of parameter as the name of the
variable; this variable is then expanded and that value is used in the
rest of the substitution, rather than the value of parameter itself.
This is known as indirect expansion."

And Bash does exactly that. If indirect array expansion is a bug, then
it's a documentation bug, because it's implied by the manual amongst
other things. The question is whether or not values of the form
"arr[n]" are considered valid "parameters" or "variable names". IMO,
they are. "The value of the variable formed from the rest of the
parameter" must itself be a "variable name" in order for these
sentences to make sense. This is consistent with their usage in
several Bash builtins that accept "variable names" as arguments such
as "read", "unset", and "printf". I consider some of those which don't
as bugs, such as "[[ -v". IMO, this should be made consistent. But at
least I've tested "${!x}" extensively in complex situations and it
works as expected every time. It's also not that difficult to
understand.

Still, it's an advanced feature and probably just as well that it's obfuscated.