Re: [Parameter Expansion] bug in ${variable% *}

2013-02-12 Thread Bernd Eggink

On 11.02.2013 18:50, Dashing wrote:

Bash version: 4.2.042

I have a script that behaves erratically:
=
#! /bin/bash
last=${1##* }
rest=${1% *}
while [[ ${rest: -1} == '\' ]]; do
last=${rest##* } $last
oldrest=$rest
rest=${rest% *}
if [[ $oldrest == $rest ]]; then
echo :--Mistake--:
#   sleep 0.01
#   rest=${rest% *}
#   if [[ $oldrest == $rest ]]; then
#   echo 'unable to interpret'
#   break
#   fi
fi
done
echo REST:$rest:
echo LAST:$last:
=
$ ./pe 'mplayer foo1\ foo2\ foo3\ 4\ 5\ foo6\ 7'
:--Mistake--:
:--Mistake--:
REST:mplayer:
LAST:foo1\ foo1\ foo1\ foo2\ foo3\ 4\ 5\ foo6\ 7:
=

What happens is that rest=${rest% *} doesn't always update $rest,
even when there are spaces left in $rest.
Meanwhile last=${rest##* } $last works every time.
In the above example it got stuck twice when $rest was mplayer
foo1\. It tends to vary wildly.


The script runs fine if you omit the superfluous blank in the ${rest: 
-1} expression:


while [[ ${rest:-1} == '\' ]]; do

If the script behaves indeterministic, it is probably a bash bug.

Regards,
Bernd



--
www.sudrala.de


Re: [Parameter Expansion] bug in ${variable% *}

2013-02-12 Thread Bernd Eggink

On 12.02.2013 18:50, Dashing wrote:

On Tue, 12 Feb 2013 18:02:05 +0100 Chet Ramey

I've fixed the problem, and the fix will be in the next release.


Thank you, Chet!

On Tue, 12 Feb 2013 10:13:46 +0100 Bernd Eggink

superfluous blank in the ${rest: -1} expression


Bernd, this blank makes a big difference:
${rest: -1} last character of $rest
${rest:-1} $rest or 1 if $rest is empty



You're right, of course. Sigh. Fortunately I've not yet fallen into that 
pithole...


Bernd

--
www.sudrala.de


Re: equivalent of Linux readlink -f in pure bash?

2011-08-11 Thread Bernd Eggink

On 09.08.2011 16:54, Stephane CHAZELAS wrote:

2011-08-09, 09:50(-04), Steven W. Orr:
[...]

*) To remove the trailing slashes, instead of

  while [[ $file == */ ]]
  do
  file=${file%/}
  done

  file=${file##*/}# file name

just say
file=${file%${file##*[!/]}}

[...]

file=${file%${file##*[!/]}}

Same problem with / being changed to  though.


This has been fixed. Also getlink() now outputs paths always in 
normalized form. Any feedback appreciated!


Bernd

--
http://sudrala.de



Re: equivalent of Linux readlink -f in pure bash?

2011-08-10 Thread Bernd Eggink

On 09.08.2011 15:50, Steven W. Orr wrote:

On 8/9/2011 5:29 AM, Bernd Eggink wrote:

On 09.08.2011 03:44, Jon Seymour wrote:

Has anyone ever come across an equivalent to Linux's readlink -f
that is implemented purely in bash?


You can find my version here:

http://sudrala.de/en_d/shell-getlink.html

As it contains some corrections from Greg Wooledge, it should
handle even pathological situations. ;)

Bernd



I'd just like to make a couple of suggestions for your script (I hope
 these are welcome):


You are welcome!


*) You reset OPTIND to 1 but you didn't declare it local. This will
cause any caller of getlink which uses getopts to reset its variable
to 1. (I mention this because it cost me a couple of hours a while
back.)


The reason I didn't declare OPTIND local is that OPTIND is handled 
specially by the shell; there is always exactly _one_ instance of this 
variable. In other words, OPTIND is always global, even if declared 
local (which is indeed pretty weird). Try this:


---
function f
{
local OPTIND=1

echo \$1=$1
}

while getopts abcdefg opt
do
echo opt=$opt
f $opt
done


Calling the sript like this works fine:
script -a -b -c

But calling it like this leads to an endless loop:
script -abc

One could of course save and restore the original:

---
function f
{
local oldind=$OPTIND

OPTIND=1
echo \$1=$1
OPTIND=$oldind
}
---

However, this also loops endlessly. The reason is most likely that bash 
maintains an additional internal variable holding the index of the 
current character, relative to the current word. While this variable is 
not directly accessible by the user, it is set to 0 whenever OPTIND is 
assigned a value.


So the only safe way is to _never_ use getopts within another getopts 
block, but always wait until the first one has finished.



When calling getopts, especially from a function that is intended to
not be used at a top level for processing command line options, you
should declare local copies of OPTIND, OPTARG and OPTERR.

*) To remove the trailing slashes, instead of

while [[ $file == */ ]] do file=${file%/} done

file=${file##*/} # file name

just say file=${file%${file##*[!/]}}


Yes, you can do that, but I find my version a bit more legible. Also, 
for file=/ it returns a single slash, while yours returns an empty 
string. (Hmm... the next statement in my script also creates an empty 
string, but this is a bug and will be fixed).



*) Instead of

[[ ! -d $dir ]]  { ret=1 break }

how about this for slightly cleaner?

[[ -d $dir ]] || { ret=1 break }


I think that's just a matter of taste.

Greetings,
Bernd

--
http://sudrala.de



Re: equivalent of Linux readlink -f in pure bash?

2011-08-09 Thread Bernd Eggink

On 09.08.2011 03:44, Jon Seymour wrote:

Has anyone ever come across an equivalent to Linux's readlink -f that
is implemented purely in bash?


You can find my version here:

http://sudrala.de/en_d/shell-getlink.html

As it contains some corrections from Greg Wooledge, it should handle 
even pathological situations. ;)


Bernd

--
http://sudrala.de



Re: Bash-4.2-rc2 available for FTP

2011-02-02 Thread Bernd Eggink

Am 02.02.2011 14:56, schrieb Chet Ramey:

The second release candidate of bash-4.2 is now available with the URL

ftp://ftp.cwru.edu/pub/bash/bash-4.2-rc2.tar.gz


Thanks. Unfortunately, this version is incredibly slow. For example, it 
needs 20 seconds (!) to source the bash_completion file, as opposed to 
0.2 seconds with 4.1-9. Counting from 1 to 1 is about 20 times 
slower. Maybe due to heavy debugging?


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de



Re: Issues when func name is the same with an alias

2010-08-04 Thread Bernd Eggink

Am 04.08.2010 12:39, schrieb Clark J. Wang:

I was testing the precedence between functions and aliases so I tried like
this (with bash 4.1.5):

$ cat rc
alias foo='echo this is the alias'

foo()
{
 builtin echo 'this is the function'
}

foo
$ source rc
bash: confusing-aliases-2.sh: line 4: syntax error near unexpected token `('
bash: confusing-aliases-2.sh: line 4: `foo()'
$

Seems like I must explicitly use the `function' keyword to define foo() for
this scenario. Is that the correct behavior?


The man page says The first word of a simple command, if unquoted, is 
checked to see if has an alias. Therefore 'foo' in your function 
declaration is replaced by 'echo this is the alias'. Unfortunately, you 
can't quote the function name in the declaration, so you have to either 
use 'function' or say unalias foo first.


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de



Re: Issues when func name is the same with an alias

2010-08-04 Thread Bernd Eggink

Am 04.08.2010 15:13, schrieb Eric Blake:

On 08/04/2010 05:03 AM, Marc Herbert wrote:

Le 04/08/2010 11:39, Clark J. Wang a écrit :


Seems like I must explicitly use the `function' keyword to define foo() for
this scenario. Is that the correct behavior?


The correct behaviour is simply not to use aliases, since they bring nothing
to the table compared to functions.


Not _quite_ true - there are a few things aliases can do that functions
cannot, and when combined, you can get some cool interactive effects
(although I don't recommend relying on this in scripts):
http://www.chiark.greenend.org.uk/~sgtatham/aliases.html


Interesting article. One thing not mentioned there is declarations.

alias assoc='declare -A '
assoc x y z

Not particularly useful, but you can't replace that with a function (as 
long as there is no 'global' option for declare).


Bernd

--
Bernd Eggink
http://sudrala.de



Re: Issues when func name is the same with an alias

2010-08-04 Thread Bernd Eggink

Am 04.08.2010 16:38, schrieb Clark J. Wang:

On Wed, Aug 4, 2010 at 8:27 PM, Bernd Egginkmono...@sudrala.de  wrote:


Am 04.08.2010 12:39, schrieb Clark J. Wang:

  I was testing the precedence between functions and aliases so I tried like

this (with bash 4.1.5):

$ cat rc
alias foo='echo this is the alias'

foo()
{
 builtin echo 'this is the function'
}

foo
$ source rc
bash: confusing-aliases-2.sh: line 4: syntax error near unexpected token
`('
bash: confusing-aliases-2.sh: line 4: `foo()'
$

Seems like I must explicitly use the `function' keyword to define foo()
for
this scenario. Is that the correct behavior?



The man page says The first word of a simple command, if unquoted, is
checked to see if has an alias. Therefore 'foo' in your function
declaration is replaced by 'echo this is the alias'. Unfortunately, you
can't quote the function name in the declaration, so you have to either use
'function' or say unalias foo first.


Function definitions are not simple commands. Actually, func definition
syntax is listed under the *Compound Commands* section in bash2.05b's man
page and in bash3+ it's been moved to a separate section.


The function *body* as part of the definition is a compound command. The 
definition as a whole constitutes a simple comand. You can see that 
function definitions are not listed under compound commands, but 
adhere to the definition of simple commands:


A  simple  command is a sequence of optional variable assignments 
followed by blank-separated words and redirections, and terminated by a 
control operator.


Some lines above '(' is listed as a control operator.

The only questionable term is ...a sequence of optional variable 
assignments followed by..., as it appears that variable assignments are 
not allowed before a function definition.


I suppose that is just a documentation issue. Can anybody comment on this?

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de



Re: RFE? request for an undefined attribute for functions

2010-08-02 Thread Bernd Eggink

Am 02.08.2010 03:10, schrieb Linda Walsh:




I had(have) several functions that I don't use on a regular basis (rarely), that
I had put into a subdir func_lib under my local-definitions directory.
This came from ksh, which allows you to define functions with an undef 
attribute,
and at runtime, the first time these functions were referenced,

Is this something that might have been considered for bash?  It seems like it
could have some usefulness?


If you are concerned about memory usage, you could use a mechanism like 
this:


#-
function undef
{
local name

for name
do
eval function $name
{
source $FUNCDIR/$name
$name \\...@\
}
done
}
#-

The call

undef f1 f2 f3

(corresponding to 'autoload f1 f2 f3' in ksh) creates small placeholder 
functions f1, f2, and f3. The first call to any of these functions will 
replace its definition by the one found in $FUNCDIR, and also call the 
latter.
I'm not sure, however, if this is guaranteed to work in any case (and in 
any bash version).


Greetings,
Bernd

--
Bernd Eggink
http://sudrala.de



Re: RFE? request for an undefined attribute for functions

2010-08-02 Thread Bernd Eggink

Am 02.08.2010 19:15, schrieb Andreas Schwab:

Bernd Egginkmono...@sudrala.de  writes:


 eval function $name


Don't use function, use $name () instead.


What's wrong with function??

Bernd

--
Bernd Eggink
http://sudrala.de



Re: RFE? request for an undefined attribute for functions

2010-08-02 Thread Bernd Eggink

Am 02.08.2010 20:16, schrieb Eric Blake:

On 08/02/2010 12:15 PM, Bernd Eggink wrote:

Am 02.08.2010 19:15, schrieb Andreas Schwab:

Bernd Egginkmono...@sudrala.de   writes:


  eval function $name


Don't use function, use $name () instead.


What's wrong with function??


'function name' is a bash extension while 'name()' is POSIX.  If you use
standard POSIX instead of bash extensions, then your approach will more
easily port to other POSIX shells.


It's not just a bash extension. Ksh and zsh also have the 'function' 
keyword, probably other shells as well. I prefer it in ksh because it 
makes locally declared variables really local, while with the name() 
syntax they are shared with the environment. That's one reason why it 
became a habit. The other is that 'function' is clear and 
self-explaining, while 'name()' wrongly suggests that function 
parameters should be surrounded by parentheses.
Apart from that, I can't see why I should care for POSIX when writing 
bash-specific hacks.


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de



Re: weird behaviour of ((count++)) when using , , to change to lower case

2010-08-01 Thread Bernd Eggink

Am 01.08.2010 13:06, schrieb Andrew Benton:


Also good. Now try converting it to lower case with ,,

andy:~$ count=0
andy:~$ echo ${days[${count}],,}, ${days[$((count++))],,}, 
${days[$((count++))],,}
monday, tuesday, thursday

What happened to wednesday?


I'd rather expect this to print monday, monday, tuesday, since you 
left out the ++ in the first term.


I think the problem is that the ,, operator causes each expression to be 
evaluated twice. That would explain this behaviour, and it's a bug IMHO.


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de



Indirect expansion and arrays

2010-07-29 Thread Bernd Eggink

It seems that indirect expansion doesn't work with arrays:

$ a=(x y z)
$ b=a
$ echo ${!b[0]} ${!b[1]} ${!b[2]}
x

Is that intended? The documentation isn't explicit about it.

IMHO it would be very desirable to have a indirect expansion facility 
for arrays. Otherwise there is only a choice between passing all 
elements to a function, which is time-consuming, or using eval, which is 
cumbersome and error-prone.


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de



Re: function grammar

2010-07-19 Thread Bernd Eggink

Am 19.07.2010 08:30, schrieb Ken Irving:

On Sun, Jul 18, 2010 at 11:53:02AM -0700, Linda Walsh wrote:


from man bash, to define a function use;

function namecompound-command
  OR
name ()compound-command

right?

And Compound Commands are:

  (list)
   {list; )
  (( expression ))
  [[ expression ]]
...et al

so why do I get a syntax error for

function good_dir [[ -n $1  -d $1  -r $1  -x $1 ]]

bash: syntax error near unexpected token `[['


I see this in bash(1):

 SHELL GRAMMAR
 ...
 Shell Function Definitions
 ...
 [ function ] name () compound-command [redirection]

and do not see the version you show without the parens.


It's there. Look at the 3rd sentence:

If the function reserved word is supplied,  the  parentheses  are 
optional.


Bernd

--
Bernd Eggink
http://sudrala.de



Re: [bash-bug] parsing error with heredoc and command substitution

2010-07-15 Thread Bernd Eggink

Am 15.07.2010 10:35, schrieb Andreas Schwab:

Dr. Werner Finkwer...@suse.de  writes:


a=$((/bin/cat|wc -l)EOF
a
b
EOF
)


Useless subshell.

a=$({ /bin/cat | wc -l; }EOF
a
b
EOF
)


...and useless cat:

a=$(wc -l EOF
a
b
EOF
)

Nevertheless, IMHO the OP's version should work. It works in ksh, for 
example.


Bernd

--
Bernd Eggink
http://sudrala.de



Wrong alignment in select lists

2010-05-31 Thread Bernd Eggink
Select lists are sometimes displayed with incorrect vertical alignment 
if an item contains one or more German umlauts. Examples:


select x in äöü blah{1..20}; do :; done # wrong
select x in amöbe blah{1..20}; do :; done   # wrong
select x in amöb blah{1..20}; do :; done# wrong
select x in amö blah{1..20}; do :; done # OK

Bash version is 4.1.7(1)-release, LANG is de_DE.UTF-8.

Bernd

--
Bernd Eggink
http://sudrala.de



Re: create array in loop with variable in array's name

2010-05-29 Thread Bernd Eggink

Am 29.05.2010 01:04, schrieb pikta:


Hi all,
I'm just a beginer and I got stucked  I'm trying to create multiple
array with variable in array's name. I would expect to have 3 arrays and
each of them would contain 3 elements like array1=(a b c)  array2=(a b c )
array3=(a b c) ; what means that first element of array1[0]=a and for
example third element of array3[2]=c. This is the way how I do it :

for (( n=1; n4; n++ ))
do
array$n=(a b c)
done

...but there is syntax error


That's because array$n isn't a valid name. Use eval:

eval array$n=(a b c)

Bernd

--
Bernd Eggink
http://sudrala.de



Re: Is there a special variable for the directory where the script is in?

2010-02-12 Thread Bernd Eggink

Am 12.02.2010 15:39, schrieb Greg Wooledge:

On Fri, Feb 12, 2010 at 02:53:39PM +0100, Bernd Eggink wrote:

I once wrote a more generic shell function for this purpose, see:
   http://sudrala.de/en_d/shell-getlink.html


You note that it doesn't handle names containing -, which is true.
I'll get back to that at the end.

It also won't handle any name that ls -l will refuse to print out
correctly on any given system.

Also, there are three more cases that it can't handle.  The first is
due to missing quotes in your command:

 echo ${link##*-  }

Without quotes, this will mangle all leading, trailing or repeated
whitespace.  Easily fixed by adding the quotes.  (There are a few
other cases of missing quotes too.)


Thanks. I knew there were some missing cases, but when I wrote it, I 
didn't consider hardening the function against insane filenames worth 
the effort.
However, it now begins to interest me if this is common practice. How 
big is the probability to stumble upon such filenames is in real life?


Bernd

--
Bernd Eggink
http://sudrala.de




Re: add a way to declare global variables

2009-12-14 Thread Bernd Eggink

Am 12/14/09 13:37, schrieb Marc Herbert:

Bernd Eggink a écrit :

To avoid misunderstandings, let me add that you are right (only) with
respect to variables being used _without_ declaration.


OK, but not having to explicitly declare variables is a feature that
most people expect from dynamic languages, so you can hardly blame them
for doing this all the time in shell.


I don't blame anybody. I'm talking about the fact that associative 
arrays are an exception from what most people expect from dynamic 
languages, as they _have_ to be explicitly declared. This doesn't 
bother me, but I would prefer to have a choice between local and global 
declaration anyway.


--
Bernd Eggink
http://sudrala.de




Re: add a way to declare global variables

2009-12-12 Thread Bernd Eggink

Am 12.12.2009 02:11, schrieb Matthew Woehlke:

konsolebox wrote:

I hope the development team will also consider adding a way in bash to
declare global variables inside a function perhaps either with an
option in typeset or declare like -g (same as zsh) and/or a builtin
function like global as similar to local.


I thought variables in functions were /always/ global unless declared
local?


It's the other way round. Regarding typeset and declare, the man page 
says:  When used in a function, makes  each name local, as with the 
local command.  So within a function, typeset, declare, and local are 
synonyms. Using 'local' outside a function is an error, so IMHO this 
command is completely redundant. It _would_ make some sense, however, if 
its counterpart 'global' existed, as it could help clarify the intended 
usage of the variable.


Bernd

--
Bernd Eggink
http://sudrala.de




Re: add a way to declare global variables

2009-12-12 Thread Bernd Eggink

Am 10.12.2009 10:40, schrieb konsolebox:


I hope the development team will also consider adding a way in bash to
declare global variables inside a function perhaps either with an
option in typeset or declare like -g (same as zsh) and/or a builtin
function like global as similar to local.


I second that. I'm missing this feature badly. Presently, you can only 
get around this restriction by using a lot of ugly and dangerous 'eval's.


Bernd

--
Bernd Eggink
http://sudrala.de




Re: add a way to declare global variables

2009-12-12 Thread Bernd Eggink

Am 12.12.2009 11:24, schrieb Bernd Eggink:

Am 12.12.2009 02:11, schrieb Matthew Woehlke:

konsolebox wrote:

I hope the development team will also consider adding a way in bash to
declare global variables inside a function perhaps either with an
option in typeset or declare like -g (same as zsh) and/or a builtin
function like global as similar to local.


I thought variables in functions were /always/ global unless declared
local?


It's the other way round. Regarding typeset and declare, the man page
says:  When used in a function, makes each name local, as with the
local command.  So within a function, typeset, declare, and local are
synonyms.


To avoid misunderstandings, let me add that you are right (only) with 
respect to variables being used _without_ declaration. The problem is 
that associative arrays are the only kind of variables that _must_ be 
declared, since something like a[foo]=bar without a preceding 
declaration would create an indexed array (and set a[0] to bar).


Bernd

--
Bernd Eggink
http://sudrala.de




Re: add a way to declare global variables

2009-12-12 Thread Bernd Eggink

Am 12.12.2009 21:41, schrieb Chet Ramey:

On 12/12/09 5:28 AM, Bernd Eggink wrote:

Am 10.12.2009 10:40, schrieb konsolebox:


I hope the development team will also consider adding a way in bash to
declare global variables inside a function perhaps either with an
option in typeset or declare like -g (same as zsh) and/or a builtin
function like global as similar to local.


I second that. I'm missing this feature badly. Presently, you can only
get around this restriction by using a lot of ugly and dangerous 'eval's.


OK.  I'm interested in use cases for this feature.  What are you trying
to do that you're missing it badly?


One example is introducing some kind of data encapsulation in bash, or 
even a modest form of object orientation. You may laugh at it, but I 
think it might be useful in complex scripts. I experimented a little and 
came up with 'classes' consisting of a function, and 'objects' 
consisting of a function (representing the interface) plus an equally 
named associative array (containing the data). The difficulties arise if 
you want to create an object 'a' of class X by saying


   X create a

You can declare a function 'a' dynamically within function X (using 
eval), but you can't declare a (global) associative array 'a' there. So 
that's where a global declaration would be desirable. The alternative is 
to print the declarations and eval the whole thing in the current 
environment, but that is very inconvenient and can cause nasty quoting 
problems.


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: Use of pipe in $( filename | program) returns null

2009-11-28 Thread Bernd Eggink

Am 28.11.2009 06:35, schrieb r...@saturn.syslang.net:


Description:
use of $(  filename | program) does not work. It either should or it 
should be properly documented.
The problem also happens on bash4.

Repeat-By:

qq=$(  /etc/passwd | grep sys)
echo $qq
# result is null

Fix:
Either fix the docs to tell people that a pipe is not allowed or fix 
the code to allow it.


The problem is not the pipe but the fact that 'filename' is an empty 
command which does nothing. If you want 'program' to read from 'file', 
use 'programfile'.


Bernd

--
Bernd Eggink
http://sudrala.de




Re: Wrong 'declare -A' causes segfault

2009-11-26 Thread Bernd Eggink

Am 26.11.2009 01:47, schrieb Chet Ramey:

Bernd Eggink wrote:

GNU bash, version 4.0.35(1)-release (i686-pc-linux-gnu)

The following syntactically wrong declaration causes a segmentation fault:

 declare -A x=y

It should issue an error message instead.


It's not actually a syntax error.


Hm, but the man page says, Indexed  array  assignments  do not require 
the bracket and subscript. This sounds like the syntax above is valid 
for indexed arrays, but not for associative arrays. Maybe the 
documentation should be corrected then.


Bernd

--
Bernd Eggink
http://sudrala.de




Re: Strange compgen behaviour

2009-09-25 Thread Bernd Eggink

Mathias Dahl schrieb:

Hm, compgen appears to behave strange if words contain whitespace.
However, you don't need it, as you build the list yourself. Try this:

  _mm2() {
  local cur files
  cur=${COMP_WORDS[COMP_CWORD]}
  files=$(find /home/mathias/Videos/movies/ -iname $cur*.avi -type
f -printf %P\n)
  local IFS=$'\n'
  COMPREPLY=($files)
  }


Ah, you're right of course, I can do the matching myself. I have yet
another version working now (had to change your latest suggestion and
use grep for matching because -name does not like full paths which
becomes the case here):

_mm() {
local cur files
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
files=$(find /home/mathias/Videos/movies/ -iname *.avi -type f -
printf %p\n | grep ${cur})
local IFS=$'\n'
COMPREPLY=(${files})
}
complete -o filenames -F _mm mm

Now, this works almost. The remaining problem is that because `find'
finds file in subdirs (which I want, otherwise I could add the -
maxdepth option) as well, the `-o filenames' argument to `complete'
does not play well with it. I see the names of files in subdirs listed
when I type TAB (without path) but can never pick them without knowing
the name of the folder they are in.


Hm, I can't see any problem here. My version lets you pick any file in 
any subdir by simply typing the name (or part of it) without the 
directory part. After all, 'find -name' matches names, not paths (if you 
want to match full paths, use 'find -path'). I'd also rather use printf 
%P\n (capital P) instead of %p, the results look nicer (IMHO).


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: Strange compgen behaviour

2009-09-24 Thread Bernd Eggink

Mathias Dahl schrieb:

It depends heavily on how the variables IFS and zf are set. From 'man bash':

-W wordlist
The  wordlist is split using the characters in the IFS special
variable as delimiters, and each resultant word is expanded.
The possible completions are the members  of  the  resultant
list which match the word being completed.


I used a newline since the original listing comes from `find'.


You didn't say how you assigned the variable zf. If you simply did
zf=$(ls /home/mathias/Videos/movies/*), the Brazil line will be split
into 4 words instead of 1. However, your output suggest that you somehow
managed to combine all file names to a single word starting with
Harry.Potter.


Yes, that could be the case.


Try this: Choose a character which doesn't appear in any file name,
e.g., ':'.

 list=$(printf %s: /home/mathias/Videos/movies/*)
 IFS=: compgen -W $list -- $zc


That works, thanks! However, I also want files from sub folders to be
found, so I use `find' to list them.

Here is my latest attempt, using the idea of setting IFS to `:':

_mm2() {
local cur files
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
files=$(find /home/mathias/Videos/movies/ -iname '*.avi' -type f -
printf %p:)
OLDIFS=$IFS
IFS=:
COMPREPLY=($(compgen -W ${files} -- ${cur}))
IFS=$OLDIFS
}
complete -o filenames -F _mm2 mm

Looks like it should work but it does not. Typing mmSPCTAB gives
the listing and completes all the way to the path, but if I add B
again it does not match Brazil.


Hm, compgen appears to behave strange if words contain whitespace. 
However, you don't need it, as you build the list yourself. Try this:


 _mm2() {
 local cur files
 cur=${COMP_WORDS[COMP_CWORD]}
 files=$(find /home/mathias/Videos/movies/ -iname $cur*.avi -type 
f -printf %P\n)

 local IFS=$'\n'
 COMPREPLY=($files)
 }

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: Strange compgen behaviour

2009-09-24 Thread Bernd Eggink

Chet Ramey schrieb:
Hm, compgen appears to behave strange if words contain whitespace. 


Well, it splits the argument to -W on $IFS as documented.  What other
strange behavior do you see? 


For example, this:

function _aha
{
local list=a b:c d:e f
COMPREPLY=($(IFS=: compgen -W $list))
}

complete -F _aha aha

Typing aha Tab cycles through 6 items a, b, c, d, e, f, whereas I 
would expect 3 items 'a b', 'c d', 'e f'. It looks like compgen splits 
the argument to -W on $IFS _and_ whitespace. Or am I missing something?


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: Strange compgen behaviour

2009-09-23 Thread Bernd Eggink

Mathias Dahl schrieb:

Hi fellow bashers!

I am trying to add some completion to a command. The completion should
list all movies I have in a certain folder, regardless if I am in that
folder or not. I have kind of got it to work in several variants but
all have some issue. The current problem I am looking at is very
strange. I have isolated it down to a strange behaviour with compgen.
Let's see if I can describe it clearly enough:

zf contains the list of movie file names
zc is the current input, in my case /home/mathias/Videos/movies/H

$ compgen -W ${zf} -- ${zc}

Here is the output:

/home/mathias/Videos/movies/Harry.Potter...
/home/mathias/Videos/movies/Harry.Potter...
/home/mathias/Videos/movies/Harry.Potter...
/home/mathias/Videos/movies/Harry.Potter...
/home/mathias/Videos/movies/Harry.Potter...
/home/mathias/Videos/movies/Brazil (Terry Gilliam, 1985).avi
/home/mathias/Videos/movies/Ice.Age.2...
/home/mathias/Videos/movies/True.Blood.S01...
/home/mathias/Videos/movies/True.Blood.S01...


It depends heavily on how the variables IFS and zf are set. From 'man bash':

-W wordlist
   The  wordlist is split using the characters in the IFS special
   variable as delimiters, and each resultant word is expanded.
   The possible completions are the members  of  the  resultant
   list which match the word being completed.

You didn't say how you assigned the variable zf. If you simply did 
zf=$(ls /home/mathias/Videos/movies/*), the Brazil line will be split 
into 4 words instead of 1. However, your output suggest that you somehow 
managed to combine all file names to a single word starting with 
Harry.Potter.


Try this: Choose a character which doesn't appear in any file name, 
e.g., ':'.


list=$(printf %s: /home/mathias/Videos/movies/*)
IFS=: compgen -W $list -- $zc

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: Help with script - doesn't work properly from cron

2009-07-18 Thread Bernd Eggink

Erik Olof Wahlstrom schrieb:

Hello - I am having a problem with a backup script that I have put together -
when I run it as root from the terminal, it works as expected (with one
caveat); however, when cron runs it, the daily backup folder is created but
no files are deposited into that folder...

Here is the script:

#!/bin/bash
BACKUP_DIR=/media/disk/AUTOMATED_BACKUPS/DB_DAILY

CURRENT_DIR=$BACKUP_DIR/`date +%d`

DATABASES=$(/usr/bin/mysql -uUsername -pPassword -Bse 'show databases')
echo 'Backing up databases: '$DATABASES

if [ -e $CURRENT_DIR ]
then
cd $CURRENT_DIR
/bin/rm *
else
/bin/mkdir $CURRENT_DIR
cd $CURRENT_DIR
fi

for DB in $DATABASES
do
/usr/bin/mysqldump -uroot -pHardAsMySql321 $DB | bzip2 
$DB_`date +%Y-%m-%d_%k.%M`.sql.bz2
done

exit 0

Can any skilled eyes see why this doesn't work when it is run from the roots
crontab?


The reason may be that crontab commands are run with /bin/sh -c 
command (Bourne shell mode). Try changing the crontab entry to 
/bin/bash command.



Additionally, when I run the script as root in the terminal, I get the
following output:

Backing up databases: information_schema db1 db2 db3
/bin/rm: cannot remove `*': No such file or directory

Is there a better way to clear out last months files before making the
current backups?


You could replace the whole if-then-else clause by

mkdir -p $CURRENT_DIR
cd $CURRENT_DIR
rm -f *

provided the options are supported on your system.

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: bash prompt misbehaving - correction.

2009-06-30 Thread Bernd Eggink

Chris Jones schrieb:

...

 After retrieving a command

from the history via a CTRL-R, an ensuing CTRL-A moves the cursor to
somewhere in the middle of the prompt and CTRL-E is short of the
retrieved command's end by some ten characters.
...



PS1=\[\033[0;41m\][\$(date +%T)]...@\h:\w]\\$\[\033[0m\] 


This works correctly with bash 4.0.24.

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: Crash in hashlib.c

2009-04-19 Thread Bernd Eggink

Chet Ramey schrieb:

Bernd Eggink wrote:

Version: GNU bash, Version 4.0.17(1)-release (i686-pc-linux-gnu)
(plus newline-shellmeta patch).

A script which uses, among other things, 3 associative arrays and a
coprocess, crashes reproducibly with an allocation error:

   malloc: hashlib.c:306: assertion botched
   free: called with unallocated block argument
   Abbruch...
   Program received signal SIGABRT, Aborted.
   0xe424 in __kernel_vsyscall ()

Appended is a stack trace. Hope it helps.


Unfortunately not much.  If you could post a portion of the script that
reproduces the error, that would be better.


Well, (un)fortunately after a reboot the crash no longer happens. Maybe 
the memory had been corrupted by some other program (possibly lftp, 
which I used as a co-process).


Bernd

--
Bernd Eggink
http://sudrala.de




Crash in hashlib.c

2009-04-17 Thread Bernd Eggink

Version: GNU bash, Version 4.0.17(1)-release (i686-pc-linux-gnu)
(plus newline-shellmeta patch).

A script which uses, among other things, 3 associative arrays and a 
coprocess, crashes reproducibly with an allocation error:


   malloc: hashlib.c:306: assertion botched
   free: called with unallocated block argument
   Abbruch...
   Program received signal SIGABRT, Aborted.
   0xe424 in __kernel_vsyscall ()

Appended is a stack trace. Hope it helps.

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de
malloc: hashlib.c:306: assertion botched
free: called with unallocated block argument
Abbruch...
Program received signal SIGABRT, Aborted.
0xe424 in __kernel_vsyscall ()
(gdb) bt
#0  0xe424 in __kernel_vsyscall ()
#1  0xb7dc9580 in raise () from /lib/libc.so.6
#2  0xb7dcadb8 in abort () from /lib/libc.so.6
#3  0x08081727 in programming_error (format=0x8117f50 free: called with 
unallocated block argument) at error.c:175
#4  0x080fc81b in xbotch (mem=0x8101558, e=2, s=0x8117f50 free: called with 
unallocated block argument, file=0x81027af hashlib.c, 
line=306) at malloc.c:319
#5  0x080fd347 in internal_free (mem=0x8101558, file=0x81027af hashlib.c, 
line=306, flags=1) at malloc.c:876
#6  0x080fdb7f in sh_free (mem=0x8101558, file=0x81027af hashlib.c, line=306) 
at malloc.c:1202
#7  0x080b841e in sh_xfree (string=0x8101558, file=0x81027af hashlib.c, 
line=306) at xmalloc.c:190
#8  0x0809be16 in hash_flush (table=0x81c7f28, free_data=0) at hashlib.c:306
#9  0x080a703b in assoc_dispose (hash=0x81c7f28) at assoc.c:57
#10 0x0807d8a0 in dispose_variable_value (var=0x81c7a48) at variables.c:2584
#11 0x0807d8f6 in dispose_variable (var=0x81c7a48) at variables.c:2598
#12 0x0807f890 in push_func_var (data=0x81c7a48) at variables.c:3781
#13 0x0809bdd8 in hash_flush (table=0x81c7c28, free_data=0x807f7b8 
push_func_var) at hashlib.c:303
#14 0x0807f904 in pop_var_context () at variables.c:3803
#15 0x0807fbc1 in pop_context () at variables.c:3938
#16 0x0809f43b in unwind_frame_run_internal (tag=0x810114f function_calling, 
ignore=0x0) at unwind_prot.c:291
#17 0x0809f0d2 in without_interrupts (function=0x809f39d 
unwind_frame_run_internal, arg1=0x810114f function_calling, arg2=0x0)
at unwind_prot.c:106
#18 0x0809f14f in run_unwind_frame (tag=0x810114f function_calling) at 
unwind_prot.c:134
#19 0x08078a89 in execute_function (var=0x815b0c8, words=0x8168f28, flags=0, 
fds_to_close=0x8166968, async=0, subshell=0)
at execute_cmd.c:4078
#20 0x08078ef2 in execute_builtin_or_function (words=0x8168f28, builtin=0, 
var=0x815b0c8, redirects=0x0, fds_to_close=0x8166968, flags=0)
at execute_cmd.c:4271
#21 0x08077ffc in execute_simple_command (simple_command=0x818fc68, pipe_in=-1, 
pipe_out=-1, async=0, fds_to_close=0x8166968)
at execute_cmd.c:3724
#22 0x08072ed9 in execute_command_internal (command=0x818fd68, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8166968)
at execute_cmd.c:724
#23 0x08075280 in execute_connection (command=0x818ec68, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8166968)
at execute_cmd.c:2173
#24 0x08073216 in execute_command_internal (command=0x818ec68, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8166968)
at execute_cmd.c:880
#25 0x080731e7 in execute_command_internal (command=0x81a7a08, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8166968)
at execute_cmd.c:872
#26 0x08078a47 in execute_function (var=0x815a488, words=0x8168d28, flags=0, 
fds_to_close=0x8166968, async=0, subshell=0)
at execute_cmd.c:4056
#27 0x08078ef2 in execute_builtin_or_function (words=0x8168d28, builtin=0, 
var=0x815a488, redirects=0x0, fds_to_close=0x8166968, flags=0)
at execute_cmd.c:4271
#28 0x08077ffc in execute_simple_command (simple_command=0x81665a8, pipe_in=-1, 
pipe_out=-1, async=0, fds_to_close=0x8166968)
at execute_cmd.c:3724
#29 0x08072ed9 in execute_command_internal (command=0x8166588, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8166968)
at execute_cmd.c:724
#30 0x080726bb in execute_command (command=0x8166588) at execute_cmd.c:369
#31 0x08076cc5 in execute_if_command (if_command=0x81664a8) at 
execute_cmd.c:3067
#32 0x0807313d in execute_command_internal (command=0x8166488, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8159688)
at execute_cmd.c:832
#33 0x08075280 in execute_connection (command=0x8154608, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8159688)
at execute_cmd.c:2173
#34 0x08073216 in execute_command_internal (command=0x8154608, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8159688)
at execute_cmd.c:880
#35 0x080731e7 in execute_command_internal (command=0x8159a48, asynchronous=0, 
pipe_in=-1, pipe_out=-1, fds_to_close=0x8159688)
at execute_cmd.c:872
#36 0x08078a47 in execute_function (var=0x8159c08, words=0x8164268, flags=0, 
fds_to_close=0x8159688, async=0, subshell=0)
at execute_cmd.c:4056
#37 0x08078ef2 in execute_builtin_or_function

Re: Bug: 'case' in command substitution not handled correctly

2009-04-16 Thread Bernd Eggink

Chet Ramey schrieb:

Bernd Eggink wrote:

GNU bash, Version 4.0.17(1)-release (i686-pc-linux-gnu)

The shell doesn't recognize the closing parenthesis of a command
substitution if a 'case' command is included and 'esac' is preceded by
newline. Example:

x=$(case $a in

(1) echo one
esac
)



Try the attached patch.  A newline really is a shell meta-character.


That fixes it, thanks.

Bernd

--
Bernd Eggink
http://sudrala.de




Bug: 'case' in command substitution not handled correctly

2009-04-15 Thread Bernd Eggink

GNU bash, Version 4.0.17(1)-release (i686-pc-linux-gnu)

The shell doesn't recognize the closing parenthesis of a command 
substitution if a 'case' command is included and 'esac' is preceded by 
newline. Example:


x=$(case $a in
 (1) echo one
 esac
 )


You can enter as many ')' as you like, the shell still wants another 
one. This variant works, however:


x=$(case $a in (1) echo one;esac
)

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: feature-request: brief syntax for $(type -p somecommand)

2009-04-02 Thread Bernd Eggink

Mike Coleman schrieb:

On Thu, Apr 2, 2009 at 11:57 AM, Chris F.A. Johnson c...@freeshell.org wrote:

  If that's what you want, you can include it in the function:

p()
{
 _p=$( type -p $@ )
 [ -n $_p ]  ls -l $_p
}


This is more or less what I'm doing now, with one function for each
command.  I suppose the command could be an argument, too, so that one
could run

$ p ls somecommand
$ p ldd somecommand
$ p strings somecommand
$ p file somecommand
$ p nm somecommand

though there's no command completion this way.  I guess I could add that, too.

One problem, though, like the wait for slot feature I suggested a
few months ago, is that something like this is quite a bit more useful
when it's available everywhere (without having to drag one's bash
library around).


I have a more universal function (also named p) here:

http://www.sudrala.de/en_d/shell-cmdexp.html

Maybe it is of use for you, too.

Regards,
Bernd


--
Bernd Eggink
http://sudrala.de




Re: reference dir ../common in script

2009-03-06 Thread Bernd Eggink

Jan Schampera schrieb:

OnTheEdge wrote:

I'm trying to check for a directory and create it if it doesn't exist as
follows:

CommonDir=../common
if [ -d ${CommonDir} ]; then
   mkdir ${CommonDir}
fi

It works from the command line, but my script doesn't seem to like it and I
can't figure it out.

Thanks for any help,
Duane


You have a wrong logic. This script will mkdir if it exists.

use

[ ! -d ${CommonDir} ]


Or use

   mkdir -p $CommonDir

Bernd

--
Bernd Eggink
http://sudrala.de





Re: Problem with function cd in bash 4.0

2009-02-24 Thread Bernd Eggink

Chet Ramey schrieb:

Bernd Eggink wrote:

I normally wrap the builtin cd into a function cd, which does some
additional things and then calls the builtin. Example:

   function cd
   {
local list=$(echo *.bui)
# ...
builtin cd $1
   }

I have a PS1 like this:

   PS1=\\w \$ 

With bash 3, this worked well; cd-ing into a directory changed the
prompt immediately. With bash 4, however, the prompt keeps unchanged
after a call to cd and only gets adjusted after the _next_ command. I
noticed that this depends on a subshell being used in the function.
Without that, it behaves as before.

Is that a bug? I can get the intended behaviour by putting

   eval PS1='$PS1'

at the end of the function, but that's a rather ugly workaround.


Yep, it's a bug.  Try the attached patch; it works for me.


Works for me, too. Thanks!

Bernd

--
Bernd Eggink
http://sudrala.de





Re: Behaviour of cd changed?

2009-02-24 Thread Bernd Eggink

Chet Ramey schrieb:

Bernd Eggink wrote:

I'm still having problems with the cd builtin. In bash 3, the commands

   cd
   cd 

both changed to the user's home directory. In bash 4 (with patch
save-current-token applied)

   cd 

does nothing. Bug or feature?


I get the same behavior from bash-3.2.48 and bash-4.0: canonicalizing 
(since it's not an absolute pathname) results in $PWD, and the cd has no
effect.  If you run cd -P  to avoid canonicalization, you get an error.
Make sure you're running `builtin cd' when you test to avoid the effect of
any function you've defined.


Sorry, my mistake. In a moment of mental absence I had changed
builtin cd @
to
builtin cd *
This caused the change in behaviour and is wrong, of course.

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de





Problem with function cd in bash 4.0

2009-02-23 Thread Bernd Eggink
I normally wrap the builtin cd into a function cd, which does some 
additional things and then calls the builtin. Example:


   function cd
   {
local list=$(echo *.bui)
# ...
builtin cd $1
   }

I have a PS1 like this:

   PS1=\\w \$ 

With bash 3, this worked well; cd-ing into a directory changed the 
prompt immediately. With bash 4, however, the prompt keeps unchanged 
after a call to cd and only gets adjusted after the _next_ command. I 
noticed that this depends on a subshell being used in the function. 
Without that, it behaves as before.


Is that a bug? I can get the intended behaviour by putting

   eval PS1='$PS1'

at the end of the function, but that's a rather ugly workaround.

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de





Re: echo $s{2,3}

2008-12-13 Thread Bernd Eggink

jida...@jidanni.org schrieb:

What happened to 2,3? Poof, gone.
$ s=a; echo $s{ $s{} $s} $s{1} $s{2,3} ${s}{4,5}
a{ a{} a} a{1} a4 a5


As the manual says, brace expansion is performed before any other 
expansions. So $s{2,3} expands to $s2 $s3, and that expands to nothing 
if neither s2 nor s3 are set.


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: implementing flow control in bash

2008-10-21 Thread Bernd Eggink

Tony Zanella schrieb:

Hello all,
I'm sure this isn't a bug, but just my inability to wrap my head
around enough of bash flow control:
I wrote the following shell script to find all gifs in a directory.
Then use identify from imagemagick to grab the gif width. Then,
print the image name and width to a file.

  for i in `find . -name \*gif`; do identify -format $i %w $i; done

results.txt


Then, I used a ruby script to cull only those images with a width over
570 pixels. So, problem solved, but I wanted to see if I could do it
all in bash.
More specifically, (if this makes sense) I want to do identify
-format $i %w $i only for those $i %w where %w is  570.

The above script will give me output like:

  image1.gif 360
  image2.gif 780

But I want it to give me:

  image1.gif 360

In pseudo-code, I want something like:

  for i in `find . -name \*gif`; do identify -format $i %w $i if [%w

570]; done  results.txt


for i in $(find -name '*.gif')
do
w=$(identify -format %w $i)
(( w  570 ))  echo $i $w
done

Hope that helps,
Bernd

--
Bernd Eggink
http://sudrala.de




Re: Bash prints syntax error when command in $(...) contains case-esac

2008-09-30 Thread Bernd Eggink

Juergen Gohlke schrieb:

Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: cygwin
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash.exe' -DCONF_HOSTTYPE='i686' 
-DCONF_OSTYPE='cygwin' -DCONF_MACHTYPE='i686-pc-cygwin' 
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' 
-DSHELL -DHAVE_CONFIG_H -DRECYCLES_PIDS   -I.  
-I/home/eblake/bash-3.2.9-11/src/bash-3.2 
-I/home/eblake/bash-3.2.9-11/src/bash-3.2/include 
-I/home/eblake/bash-3.2.9-11/src/bash-3.2/lib   -O2 -pipe
uname output: CYGWIN_NT-5.0 JONA 1.5.24(0.156/4/2) 2007-01-31 10:57 i686 
Cygwin

Machine Type: i686-pc-cygwin

Bash Version: 3.2
Patch Level: 9
Release Status: release

Description:
   If a command in $(...) contains a case-esac construction, the 
bash prints a syntax error instead

   of executing the code:
   bash: syntax error near unexpected token `;;'

Repeat-By:
   A simple example is: x=$(a=4; case $a in 3) echo a=3;; 4) echo 
a=4;; esac)

   (typed in an interactive shell or being part of a shell script).
   The same error has been seen on Windows Vista, Windows XP and 
Windows2000.
   The same error has been seen with an earlier version of bash, 
i.e. 2.05b.0(8)-release

   If $(...) is replaced by `...`, it works.


The problem is caused by the semi-parenthesized case labels 3) and 4). 
Bash matches the first unpaired right paren (after the 3) with the last 
unpaired left paren (in $( ). Using (3) and (4) instead makes the 
example work.

Unpaired parens are hideous anyway, IMHO.

Regards,
Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Expanding an undefined array

2008-09-24 Thread Bernd Eggink

Is the following difference intentional, a bug, or do I miss something?

  unset a
  set -- [EMAIL PROTECTED]
  echo $#

Output: 0

  typeset a
  set -- [EMAIL PROTECTED]
  echo $#

Output: 1

The man page says, If the word is double-quoted, ... [EMAIL PROTECTED] expands 
each element of name to a separate word. When there are no array 
members, [EMAIL PROTECTED] expands  to  nothing. It doesn't mention a 
difference between an empty and an unset variable in this context. As a 
quoted 'nothing' normally counts 1 word, the 'nothing' in the first 
example appears to be some kind of 'super-nothing'.


Regards,
Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Re: PATH value doesn't get updated

2008-05-18 Thread Bernd Eggink

Peter Volkov schrieb:



Better way to check if shell is login is:

 $ shopt | grep login_shell
login_shell on


You don't even have to call an external program:

[[ $(shopt -p login_shell) == *-s* ]]

Regards,
Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Re: Which Bash

2008-02-24 Thread Bernd Eggink

Charlse Darwin schrieb:

$ echo $BASH_VERSION
2.05b.0(1)-release
$ bash --version
GNU bash, version 3.2.33(1)-release (powerpc-apple-darwin8.11.0)
Copyright (C) 2007 Free Software Foundation, Inc.
$ which bash
/opt/local/bin/bash
$
# Which bash is being used by the system; 3.2.33(1)-release or 
2.05b.0(1)-release?


Looks like there are at least 2 versions on your system: Your login 
shell is probably bash-2.05b, while /opt/local/bin/bash (the latest 
version) is found via $PATH. Check your account data and PATH setting to 
verify it.


Regards,
Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Re: Bash 3.2.25 not expanding subscript...

2008-02-12 Thread Bernd Eggink

Brad Diggs schrieb:


In short the bug is the result of failure to expand the
subscript of an array if the subscript is a variable.
The following script should return a list of files with a 
preceding (File #: ).  However, it does not work that 
way because the integer variable (${d}) used in the subscript
of the array statement (FileList[${d}]=${File}) does not get 
properly expanded.


#!/bin/bash
declare -a FileList=('')
declare -i d=0

ls -1| while read File
do
   FileList[${d}]=${File}
   d=$((10#${d}+1))
done


This is normal bash behaviour, see FAQ E4. As bash executes _all_ parts 
of a pipe in subshells (in contrast to ksh, where the last component is 
executed in the current shell), the variable 'FileList' being assigned 
here is local to the subshell. After the loop the variable 'FileList' 
declared in line 1 (which happens to have the same name, but that 
doesn't matter) is unchanged.


Try this instead:

while read File
do
   FileList[d]=$File
   (( d=d+1 ))
done $(ls -1)

Greetings,
Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Re: Bash string substitution bug (?)

2008-01-11 Thread Bernd Eggink

Dmitry V Golovashkin schrieb:


Description:
   unexpected bad substitution:
   enter the following simple list:

prompt:  CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME%%.*}}
output:   1 2

   the idea of the above line is to remove short HOSTNAME (without the 
trailing domain)
 from the CLUSTER - works fine (CLUSTER was assigned a dummy 
value - irrelevant)
   however the same operation with slash results in a bad substitution 
error.

   the substitution appears to be a valid one.

  prompt: CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME/.*}}
  output: -bash: ${HOSTNAME: bad substitution


Apparently bash interprets this as  ${parameter/pattern/string}
where pattern = ${HOSTNAME. Looks like a bug; it works in ksh.

As a workaround, you could use:

H=${HOSTNAME/.*}
echo ${CLUSTER/$H}

Regards,
Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Re: Bash string substitution bug (?)

2008-01-11 Thread Bernd Eggink

Chet Ramey schrieb:

Bernd Eggink wrote:


  prompt: CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME/.*}}
  output: -bash: ${HOSTNAME: bad substitution


Apparently bash interprets this as  ${parameter/pattern/string}
where pattern = ${HOSTNAME. Looks like a bug; it works in ksh.


That is, in fact, what is happening.  I'm not sure you can call it
a bug, though -- bash is behaving exactly as documented.


Where exactly is that documented? The only statement I can find in the 
documentation referring to this problem is:


When braces are used, the matching ending brace is the first `}' not 
escaped by a backslash or within a quoted string,  and  not
within an embedded arithmetic expansion, command substitution, or 
parameter expansion.


I may be wrong, but to me this means that the first opening brace 
matches the last closing one, and that the token ${HOSTNAME/.*} is a 
correct parameter expansion.


Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Re: regexp matching broken in bash-3.2.x?

2007-10-27 Thread Bernd Eggink

Pavel Gorshkov schrieb:


Description:
Regexp matching seems to be broken since 3.2.0.
Repeat-By:
The following used to work in bash-3.1:
$ [[ test =~ 't.*t' ]]; echo $?
1


It works without the quotes. Looks like they are taken literally instead of 
being removed. I, too, think it's a bug, as according to  the docs, quote 
removal should be performed on the words between [[ and ]].


Regards,
Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de