Я думаю, у вашего дистрибутива есть псевдоним или символическая ссылка это. Это нормальное поведение (Debian):
$CD ..
mksh: CD: not found
$ CD ..
bash: CD: command not found
Благодаря помощи @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
}
Да, лишний возврат каретки - это ваша проблема.
Подстановка процесса удаляет последнюю новую строку (перевод строки) из вывода процесса, но в случае, если 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/*/}
. С одним #
он удаляет самый короткий совпадающий префикс.