delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2009/12/25/00:04:52

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=BAYES_00,SARE_MSGID_LONG40,SPF_PASS
X-Spam-Check-By: sourceware.org
MIME-Version: 1.0
In-Reply-To: <20091225031926.GA8496@panix.com>
References: <20091225031926 DOT GA8496 AT panix DOT com>
Date: Fri, 25 Dec 2009 00:04:36 -0500
Message-ID: <a13b5a590912242104m1900a9e5q58f69019b6c0edb1@mail.gmail.com>
Subject: Re: bash expands $1 in strange new way
From: Robert Pendell <shinji AT elite-systems DOT org>
To: arnstein AT pobox DOT com, cygwin AT cygwin DOT com
X-IsSubscribed: yes
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Unsubscribe: <mailto:cygwin-unsubscribe-archive-cygwin=delorie DOT com AT cygwin DOT com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

On Thu, Dec 24, 2009 at 10:19 PM, David Arnstein wrote:
> I have a bash shell script named xplo that worked as desired under
> cygwin 1.5. It fails under cygwin 1.7. Specifically, the shell expands
> the expression
> =C2=A0 =C2=A0 =C2=A0 =C2=A0$1
> in a way that I simply cannot understand. This expression expanded to
> the first shell script argument in cygwin 1.5. Not any more.
>
> Here is the script xplo in its entirety:
> #!/bin/bash
> if [ $# -gt 1 ]
> then
> =C2=A0 =C2=A0 =C2=A0 =C2=A0echo "Usage: xplo path-or-file"
> =C2=A0 =C2=A0 =C2=A0 =C2=A0exit 1
> else
> =C2=A0 =C2=A0 =C2=A0 =C2=A0set EXPLOR=3D'/cygdrive/c/windows/explorer.exe'
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if [ $# -eq 0 ]
> =C2=A0 =C2=A0 =C2=A0 =C2=A0then
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0cygstart ${EXPLOR}=
 /e,.
> =C2=A0 =C2=A0 =C2=A0 =C2=A0elif [ -f "$1" ]
> =C2=A0 =C2=A0 =C2=A0 =C2=A0then
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0cygstart ${EXPLOR}=
 /e,/select,`cygpath -w "$1"`
> =C2=A0 =C2=A0 =C2=A0 =C2=A0else
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0cygstart ${EXPLOR}=
 /e,`cygpath -w "$1"`
> =C2=A0 =C2=A0 =C2=A0 =C2=A0fi
> fi
>
> I cd to a directory that contains an ordinary file named wongo, as
> well as the shell script xplo. I execute the command
> =C2=A0 =C2=A0 =C2=A0 =C2=A0bash -x ./xplo wongo
>
> I expect to get an instance of Windows Explorer, with folders showing,
> and the file wongo selected (highlighted). This does not occur. The
> text output from the above bash -x looks like this:
> + '[' 1 -gt 1 ']'
> + set EXPLOR=3D/cygdrive/c/windows/explorer.exe
> + '[' 1 -eq 0 ']'
> + '[' -f EXPLOR=3D/cygdrive/c/windows/explorer.exe ']'
> ++ cygpath -w EXPLOR=3D/cygdrive/c/windows/explorer.exe
> + cygstart '/e,EXPLOR=3D\cygdrive\c\windows\explorer.exe'
> Unable to start 'E:\cygwin\e,EXPLOR=3D\cygdrive\c\windows\explorer.exe':
> The specified file was not found.
>
> I have attached the output from cygcheck -s -v -r. Thanks for any
> advice.
>

The problem isn't bash nor how $1 is expanded.  In fact $1 never gets
used in your test case when no parameters are given.  Take the
following test case which does the essence of your script without the
use of cygpath or cygcheck (those are not the issue here).

#!/bin/bash
set VAR=3D"outside"
echo ${VAR}
if [ true ]
then
   set VAR2=3D"inside"
   echo ${VAR}
   echo ${VAR2}
fi
echo ${VAR2}

If you are to run the above script the output is 4 blank lines.  The
set command works differently within shell scripts than it does
outside of them.  Inside shell scripts you either use export or you
don't use either one.  So either replacing set with export or removing
it will fix the script completely for you.  I can't test it on debian
with that change because your script uses cygcheck and cygpath but I
did test it locally and once that change was made it worked just fine.
 The main difference between using export and not using it is that
export allows child processes to use the variables as well.  If you
don't use it then child processes won't be able to access them.  This
doesn't change parent processes at all.

*After checking man pages*

Ok.  I just checked the man pages again and this is a "by design"
issue in how you are using set. Per the following quote for set in the
bash man page.

"The remaining N arguments are positional parameters and are assigned,
in order, to $1, $2, ... $N. The special parameter # is set to N."
Source: http://www.gnu.org/software/bash/manual/bashref.html#The-Set-Builtin
(yes... this is quoted from online docs -- cygwin has a similar quote)

This test case has the same behavior on debian and cygwin so if it is
a bug then it is in bash itself and not a cygwin issue at all.  I
highly doubt it is a bug though based on the above text.

#!/bin/bash
set PARM1=3Done PARM2=3Dtwo PARM3=3Dthree
echo '$PARM1' is $PARM1
echo '$PARM2' is $PARM2
echo '$PARM3' is $PARM3
echo '$1' is $1
echo '$2' is $2
echo '$3' is $3

It should output something like the following and yes that is correct.
 You may be able to understand your script behavior better now.

$PARM1 is
$PARM2 is
$PARM3 is
$1 is PARM1=3Done
$2 is PARM2=3Dtwo
$3 is PARM3=3Dthree

Robert Pendell
shinji AT elite-systems DOT org
CAcert Assurer
"A perfect world is one of chaos."

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019