2

D

Я сталкиваюсь с проблемой в ls(1), что я почти уверен, что это глупая вещь, которую я просто пропускаю. В любом случае, я не могу понять, почему это не работает.

Я использую Bash для Cygwin (не спрашивайте, почему ... Мне просто нужно :() Вот полный (значимый) вывод --version:GNU bash, version 4.4.12(3)-release (x86_64-unknown-cygwin)

Я возился с cygpath, чтобы преобразовать пути Unix / Windows для себя, так что я могу оставаться большую часть времени на терминале и в то же время иметь возможность получать пути Windows и наоборот.

Пока все хорошо ... но досадно в NT то, что на многих путях есть пробелы и другие символы, которые не совсем соответствуют путям, например ( ) . Чтобы помочь мне с этим, я только что написал сценарий oneliner, чтобы избежать всех путей с обратными слешами, поэтому у меня будет правильный путь, независимо от того, какие окна сумасшествия на них наложены.

Пока все еще хорошо ... Но потом я столкнулся с проблемой, что ls(1) запутался в путях, это довольно сложно объяснить, поэтому приведу несколько примеров!

## Lets imagine that I want to get the "unix" version of C:\Program Files (x86)
## And for sake of simplicty I'll call the oneliner sript as unix_path.

unix_path "C:\Program Files (x86)"
##  prints /cygdrive/c/Program\ Files\ \(x86\)

my_path=$(unix_path "C:\Program Files (x86)");
echo $my_path;
##  prints /cygdrive/c/Program\ Files\ \(x86\)

## Until now, we're good!
## But the next commands really bugs me...

ls $my_path;
##  ls: cannot access '/cygdrive/c/Program\': No such file or directory
##  ls: cannot access 'Files\': No such file or directory
##  ls: cannot access '\(x86\)': No such file or directory

ls $(unix_path "C:\Program Files (x86)")
##  Same as before...
##  ls: cannot access '/cygdrive/c/Program\': No such file or directory
##  ls: cannot access 'Files\': No such file or directory
##  ls: cannot access '\(x86\)': No such file or directory

ls "$my_path";
##  ls: cannot access '/cygdrive/c/Program\ Files\ \(x86\)': No such file or directory

## Now is very crazy, let's imagine that I type /cygdrive/c/Program\ Files\ \(x86\)
## by hand or just paste it.
ls /cygdrive/c/Program\ Files\ \(x86\)
##   I'll not post but the listing are correct!

Я действительно не понимаю, почему ls(1) не правильно, когда я вызываю его с помощью $() или $var_name_here но все же правильно, когда я набираю путь. Обратите внимание, что путь одинаков для обоих способов!

Любая помощь здесь будет отличной! Спасибо!

1 ответ1

2

Так как

ls $my_path;

становится

ls /cygdrive/c/Program Files (x86)

поскольку обратная косая черта не является частью пути, это всего лишь уловка в "литералах" bash.

Таким образом, ls дается три разных имени файла /cygdrive/c/Program , Files и (x86) . Чтобы ls видел одно имя файла с пробелами внутри, используйте:

ls "$my_path"

На практике в bash вы помещаете двойные кавычки вокруг всех строк, которые могут содержать пробелы и которые вы хотите видеть как единое целое. $ -подстановка все еще происходит внутри двойных кавычек (но не происходит внутри одинарных кавычек)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .