Search code examples
cygwin

Escape spaces when passing a file path to a command opened with cygstart


The Issue

When running the following command:

cygstart bash "/home/FirstName LastName/bin/script.sh"

The file path being passed to bash is getting cut off at the space, so I get the following error:

/usr/bin/bash: /home/FirstName: No such file or directory

What I've tried:

1.

cygstart bash "/home/FirstName LastName/bin/script.sh"

2.

FILE_PATH="/home/FirstName LastName/bin/script.sh"
cygstart bash "$FILE_PATH"

3.

FILE_PATH="/home/FirstName LastName/bin/script.sh"
cygstart bash "${FILE_PATH}"

4.

FILE_PATH="/home/FirstName LastName/bin/script.sh"
cygstart bash ${FILE_PATH}

5.

FILE_PATH="/home/FirstName LastName/bin/script.sh"
MY_COMM=$(cygstart bash "$FILE_PATH")
eval $MY_COMM

Along with half a dozen other variations that I can't recall at the moment, including all of the above with a backslash to escape the space. The error is always the same.

What am I missing, or is there even a way to solve this?

UPDATE: The reason I am using cygstart in this case is to take advantage of it's --action=runas option. The script I am calling renames a file, but it has to be run with admin privileges to do so. The idea is that I can just call the script and then enter in the appropriate credentials.


Solution

  • For a test, I created a script in ~/Test Dir/test.sh. Here's what worked for me:

    cygstart bash \"/home/cxw/Test\ Dir/test.sh\"
    

    The \" at the beginning and end are freestanding double-quotes, which will wrap what's between them to keep it together as one argument.

    The issue is that the parameters are being put into the Windows ShellExecute function, which winds up splitting args at whitespace. To see the exact command being run, use cygstart -v.

    The result of the above is a ShellExecute call like this:

    ShellExecute(NULL, "(null)", "bash", ""/home/cxw/Test Dir/test.sh"", "(null)", 1)
    

    Note the paired double-quotes: the outer quotes are printed by cygstart -v, and the inner are the \" to keep the script name together.

    I listed /home/cxw instead of ~ because ~ didn't work for me. You can use cygpath -a to get absolute paths if you need them.