简体   繁体   中英

Bashrc script does not change directory on manipulated string that contains space

I'm trying to develop a fast solution to navigate on folders between Windows and Cygwin.

On windows the path looks like this:

C:\Users\foo\my folder\

When I need to get to the same folder on Cygwin I need to use the following format

/cygdrive/c/Users/foo/my\ folder/

Every time I'm on explorer I need to copy the link and edit it.

So I made a simple script for my .bashrc file

It works fine for nonspace containing paths, but when I try to replace the space with '\\ ' , the link does not find the directory.

I tried to echo the path, copied and pasted to the terminal and it works.

But this does not work:

function cdWinPath(){
    if [ `expr index "$1" C:\\` == '1' ] 
    then
        length=`expr length "$1"`
        pathSubs=${1:2:$length}
        cygPath="/cygdrive/c${pathSubs//\\/\/}"

        cygPath="${cygPath// /\\\ }" #piece of code that replaces blank space
        echo "cd $cygPath"

        cd "$cygPath" # shows 'No such file or directory'
    else
        echo "Could not understand path $1"
    fi
}

The shell parses quotes and escapes before expanding variables, so quotes and escapes in variables' values don't get treated as such, just as normal characters. So don't try to embed escapes in the variable, just put double-quotes around the variable reference.

Some other suggestions: Rather than messing around with expr , just use the shell's built-in string manipulation. When you do need to capture output from another program, use $( ) instead of backticks. Finally, the function keyword is nonstandard, just use () after the name to define a function. Something like this:

cdWinPath() {
    local cygPath="${1/#[Cc]:\\//}"    # Replace 'C:\' or 'C:\' prefix with just '/'
    cygPath="${cygPath//\\//}"         # Replace any other '\' with '/'
    cd "$cygPath"
}

Note, however, that this requires the windows path to be passed correctly to the function. That means that backslashes and/or spaces in the path must be properly escaped or quoted (meaning that you must double-quote any variable references).

cdWinPath 'C:\Users\foo\my folder\'     # This works
cdWinPath C:\\Users\\foo\\my\ folder\\  # So does this
cdWinPath C:\Users\foo\my folder\       # This does not work

cdWinPath "$somevar"                    # This works, provided `somevar` is properly set
cdWinPath $somevar                      # This does not work

If you want it to tolerate the path being passed incorrectly, you can make it a little more tollerant by replacing the first line with:

local cygPath="${*/#[Cc]:\\//}"

Using ${*...} instead of $[1...} will take all parameters passed to the function and mash them together with spaces between, on the assumption that they were originally one string that got split on spaces. This will sometimes work, but not always. For example, this command:

cdWinPath C:\Users\foo\my folder\

... will still not work because the shell will interpret the backslashes as escapes before the function even gets the string, and there's no way to fix that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM