Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <4139AF96.4274702@dessent.net> Date: Sat, 04 Sep 2004 05:05:42 -0700 From: Brian Dessent Organization: My own little world... MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: Problem executing a .bat script in a directory with spaces using bash References: <5c8adab704090207557a3a359a AT mail DOT gmail DOT com> <4137566C DOT 7070203 AT sbcglobal DOT net> <5c8adab704090210405ea696e4 AT mail DOT gmail DOT com> <413760BD DOT 2080504 AT sbcglobal DOT net> <5c8adab70409021123291886c7 AT mail DOT gmail DOT com> <41376CD2 DOT 9090102 AT comcast DOT net> <41376D75 DOT 1060806 AT comcast DOT net> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Reply-To: cygwin AT cygwin DOT com Christopher Cobb wrote: > I use the following shell function cmd() to invoke batch files. It removes > cygwinisms from the PATH and the environment first and does some argument > pre-processing. It also seems to fix the space problem. Interesting function. However, I found that it chokes if the name of the command to run has spaces, even if they are properly quoted on the command line, e.g. $ cmd /cygdrive/c/Program\ Files/something\ with\ a\ space/test.bat 'c:Program' is not recognized as an internal or external command, operable program or batch file. If you enable "set -x" and run it you see that it's ultimately trying to execute: eval /winxp/system32/cmd.exe /c 'c:\Program Files\something with a space\test.bat' ...which then acutally tries to run: /winxp/system32/cmd.exe /c c:Program Filessomething with a spacetest.bat I'm not sure why 'eval' is needed here at all but I assume there's a good reason. I'm no scripting guru and the levels of quoting here are really nasty. However, I found the following version seems to fix the issue for me. It does explicit quoting on the $c part so that the eval line gets $c with shell-quoting already applied, which it then removes. cmd () { ( local c=`cygpath -w "$1"|sed -r 's@([^a-z0-9.:])@\\\\\\1 AT gi'`; shift; local cmd=`cygpath -u $COMSPEC`; while [ $# != 0 ]; do if [ -f "$1" ]; then local args="$args '`cygpath -w $1`'"; else if [ -d "$1" ]; then local args="$args '`cygpath -w $1 | sed 's@\\\\\$@@'`'"; else local args="$args '$1'"; fi; fi; shift; done; PATH=`echo $PATH | tr : '\n' | egrep -vw '^(/usr/local/bin|/usr/bin|/bin|/usr/X11R6/bin)$' | tr '\n' :`; unset BASH_ENV COLORTERM CYGWIN DISPLAY HISTCONTROL MAKE_MODE; unset MANPATH PKG_CONFIG_PATH PS1 PWD SHLVL TERM USER _; unset CVS CVSROOT CVS_RSH GEN_HOME GROOVY_HOME TOMCAT_DIR; eval $cmd /c $c $args ) } This version successfully allows you to do: cmd /posix/path/with\ spaces\ in\ it/file.bat ..and have it work correctly. ----- I've used a simiar function for a while in the past, but both it and this still suffer from one really annoying flaw: if an argument that is meant to be a filename does not exist, the script will not windows-ize it. The context that this comes up is that I would like to be able to run a windows editor, passing it a posix filespec on the command line of a file that does not exist: cmd /cygdrive/c/Program\ Files/UltraEdit/uedit32.exe ~/foo If ~/foo already exists then this is properly translated into: /winxp/system32/cmd.exe /c 'c:\Program Files\UltraEdit\uedit32.exe' 'C:\cygwin\home\brian\foo' However, if ~/foo is a new file that does not exist, then the script will not convert it into a windows path, and the win32 program gets really confused. I guess you could assume all arguments are filenames and "cygpath -w" them, but I'm sure that ends up breaking yet something else. Any ideas? Brian -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/