ls (1) действует странно, когда input является переменной / подкомандой или просто напечатан

252
n2omatt

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но все же правильно, когда я набираю путь. Обратите внимание, что путь одинаков для обоих способов!

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

2

1 ответ на вопрос

2
xenoid

Так как

ls $my_path; 

становится

ls /cygdrive/c/Program Files (x86) 

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

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

ls "$my_path" 

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

Привет, @xenoid, спасибо за ответ; я понимаю твои рассуждения, но они все еще не работают, как ты можешь видеть на моем посте, второй пример, который уже включает в себя переменную в кавычках. У тебя есть другая идея, и еще раз спасибо; D n2omatt 6 лет назад 0
@ n2omatt Вы должны иметь двойные кавычки вокруг ссылки на переменную и НЕ иметь экранирования в значении переменной. Попробуйте `my_path = '/ cygdrive / c / Program Files (x86)'; ls "$ my_path" `. Так что вы написали, чтобы добавить побег? Не используйте это, это часть проблемы. Gordon Davisson 6 лет назад 2

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