[Parameter Expansion] bug in ${variable% *}
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. I have commented out some code including sleep that sometimes helps make the parameter expansion work. This commented out code also avoids an infinite loop which is triggerable in a normal way with an argument of: command\ filename Thanks, Dashing
Re: [Parameter Expansion] bug in ${variable% *}
On Tue, 12 Feb 2013 14:16:24 +0100 "Greg Wooledge" wrote: >On Mon, Feb 11, 2013 at 06:50:49PM +0100, Dashing wrote: >> $ ./pe 'mplayer foo1\ foo2\ foo3\ 4\ 5\ foo6\ 7' >> :--Mistake--: >> :--Mistake--: > >Whatever you're doing, it's wrong. > >./pe mplayer foo1\ foo2\ foo3\ 4\ 5\ foo6\ 7 > >#!/bin/bash >prog=$1 >shift >exec "$prog" extra args go here "$@" > >THAT is how a wrapper should be done. Do not combine a program >and its >arguments all together into a single argument and then try to >parse it >apart. For my purposes this is irrelevant, because the nature of the script from which my example code derived is tab completion. READLINE_LINE will contain mplayer foo1\ foo2\ etc. The last argument needs to be found and if it contains spaces this is what needs to happen.
Re: [Parameter Expansion] bug in ${variable% *}
On Tue, 12 Feb 2013 14:45:26 +0100 "Greg Wooledge" wrote: >There are no literal backslashes in an argument that is >produced by tab completion. The backslashes are a form >of quoting, and they are removed by the calling shell >during the quote removal phase. When bind -x sets READLINE_LINE backslashes are kept intact. What I meant was that I wrote my own tab completion. >If you believe you have found a bug in parameter expansion, >then simplify the example so that it directly demonstrates >the bug. As I showed in the output, it does not happen all the time. Even the same value of $rest one time works and another time does not. Therefore, looping over a bunch of items is required.
Re: [Parameter Expansion] bug in ${variable% *}
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