Я пытаюсь написать сценарий, который будет передавать местоположение каталога, перетащенного в окно bash, с помощью инструмента wslpath
при работе в WSL в Windows.
# Drag and drop the directory into the Bash window
IFS = "" read -r input
echo;
# If system is Windows Subsystem for Linux convert Windows paths to Unix paths
if [[ $(uname -r) =~ Microsoft$ ]]; then
input = "$( wslpath "$input" )"
fi
# Use eval to parse spaces in the path as an array
eval "input=( $input )"
# List files and directories
ls -l "${input}"; echo;
Если в имени каталога есть пробелы, он не может найти каталог для списка.
Если я перемещаю строку eval "input=( $input )"
над условной подсистемой Windows для Linux, она находит каталог, если в имени каталога есть пробел, но не находит, если пробела нет.
Если я заменю строку input = "$( wslpath "$input" )"
следующим выражением замены Bash, оно будет работать с пробелами или без них, но буква диска должна быть жестко закодирована input=${input/F:\//mnt/f/}
Я прочитал несколько потоков о порядке оценки кавычек в Bash, передаче аргументов функциям в виде массивов, а затем расширении этих массивов, но я действительно борюсь с этим, и я просто не могу заставить его работа.
Поскольку у вас есть только один путь, вам не нужны массивы. Пробелы внутри путей обрабатываются правильно, пока вы указываете свои переменные.
Actually, splitting the path into an array of words would cause information loss. You would not know if the array (a b)
was originally a b
(one space) or a b
(two spaces). Also, you don't need eval
to split a variable into words. array=($var)
is the way to go.
Проблема здесь в том, что Windows вставляет пути с пробелами, заключая их в двойные кавычки. То есть, если вы перетащите C:\a
, вы получите строку C:\a
, а если перетащите C:\a b
, вы получите "C:\a b"
. Эти кавычки не интерпретируются bash, поскольку они являются только входными данными, а не частью вашего скрипта. wslpath
также не интерпретирует эти цитаты. Вместо этого wslpath '"C:\a b"'
ищет файл с буквальным именем a b"
, находящийся на диске "C:
. Мы должны вручную удалить кавычки, вставленные перетаскиванием Windows.
IFS= read -r input; echo
if [[ "$(uname -r)" =~ Microsoft$ ]]; then
# is path quoted and contains a space?
if [[ "$input" =~ ^\"(.*\ .*)\"$ ]]; then
# remove quotes
input = "${BASH_REMATCH[1]}"
fi
input = "$( wslpath "$input" )"
fi
ls -l "${input}"; echo
Очень рад, что смог помочь.
Он работает отлично! Большое спасибо. Я потратил целый день на гугление проблемы и пытался понять ее, и вы единственный человек, который четко объяснил причину.