Объединение двух переменных искажает их в Windows

Я думаю, у вашего дистрибутива есть псевдоним или символическая ссылка это. Это нормальное поведение (Debian):

$CD ..
mksh: CD: not found

$ CD ..
bash: CD: command not found
2
01.04.2017, 00:50
2 ответа

Благодаря помощи @steeldriver мне удалось это выяснить! Как ни странно, это была проблема с окончанием строки Windows, хотя CMD выводила только одну строку. Решением было преобразовать вывод CMD в стиль Unix, и это решило проблему! Вот мой последний код:

winpath() {
    # get the Windows user path, convert to Unix line endings
    user_path=$(echo "$(/mnt/c/Windows/System32/cmd.exe /C echo %HOMEDRIVE%%HOMEPATH%)" | tr -d "\r")

    # expand the specified path
    target_path=$(readlink -f $1)

    # change ~ to $user_path
    if grep -q "^/home/" <<< $target_path; then
        temp_user_path=$(echo "$user_path" | sed -e 's|\\|/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/mnt/\L\1\E/\2|' -e 's|^M$||')

        # if there was something after ~, add it to the end of the $user_path
        if grep -q "^/home/\(.*\)/\(.*\)" <<< $target_path; then
            target_path=$temp_user_path$(echo "$target_path" | sed -e 's|^/home/*/\(.*\)|/\2|')
        # if there was nothing after ~, $target_path is $user_path
        else
            target_path=$temp_user_path
        fi
    fi

    # check if a Windows path is getting parsed
    if grep -q "^/mnt/[a-z]" <<< $target_path; then
        # swap /mnt/[a-z] with [A-Z]: and / with \
        echo $(echo "$target_path" | sed -e 's|^\(/mnt/\([a-z]\)\)\(.*\)|\U\2:\E\3|' -e 's|/|\\|g')
    else
        # return the user's home directory if a Unix path was parsed
        echo $user_path
    fi
}
1
27.01.2020, 22:03

Да, лишний возврат каретки - это ваша проблема.

Подстановка процесса удаляет последнюю новую строку (перевод строки) из вывода процесса, но в случае, если cmd.exe выводит пару CR-LF, возврат каретки остается в конце user_path. При печати CR заставляет вывод возвращаться к началу строки при печати. Repositories имеет ту же длину, что и /mnt/c/Users, поэтому следующая косая черта выравнивается в несколько логичном месте (вместо того, чтобы выглядеть так, будто какое-то слово было нарушено).

Вы можете удалить косую черту CR внутри Bash с помощью ${user_path%$'\r'}. (${var%pattern} удаляет суффикс, соответствующий шаблону, из переменной)

Также, я думаю, что ваш второй sed ('s|^/home/\(.*\)/\(.*\)|/\2|') немного слишком рьяный, первый . * будет соответствовать самой длинной строке, так что /home/user/foo/bar превратится в /bar вместо /foo/bar. То же самое можно сделать и с расширением параметров: ${target_path#/home/*/}. С одним # он удаляет самый короткий совпадающий префикс.

2
27.01.2020, 22:03

Теги

Похожие вопросы