realpath
и readlink
вернуть абсолютные пути:
+akiva@X230:~$ realpath ZannaIsAwesome
/home/akiva/ZannaIsAwesome
С таким путем легко справиться. Тем не менее, что-то вроде этого будет иметь некоторые проблемы:
Например:
Таким образом, имя, подобное этому, должно быть обработано, чтобы иметь возможность передавать его другим командам. Вариант использования может быть примерно таким:
+a@X230:~/\e[92mM@r|< $hu+'|'|_e|\|\|0rth [`-_-"]$ bacon=$(realpath pullingATerdon)
+a@X230:~$ vim $bacon
Излишне говорить, vim $bacon
что не будет работать, как ожидалось.
Что я могу сделать, чтобы очистить этот абсолютный путь, чтобы он работал с другими командами?
command-line
bash
paths
Акива
источник
источник
vim "$bacon"
Ответы:
Как сделать это правильно
Прежде всего, всегда указывайте свои переменные . То, что вы пытаетесь сделать, работает нормально, если вы цитируете это правильно:
Я сохранил странное имя файла, которое вы выбрали ( хотя я понятия не имею, почему вы выбрали его ) для согласованности.
Теперь давайте назначим путь
pullingATerdon
к переменной, а затем попробуем открыть файл:Это терпит неудачу, как и ожидалось. Но если мы сейчас процитируем это правильно:
Работает как положено. И да, вы также можете открыть путь в (правильном) редакторе: все
emacs "$bacon"
будет работать нормально. ОК, так будетvim
и все остальное. Ваш выбор редактора, хотя и неудачный, не имеет значения.Почему твой провал
Быстрый способ отследить то, что на самом деле произошло в вашем случае, - это использовать
set -x
(выключите его снова с помощьюset +x
), что заставляет оболочку печатать каждую команду, которую она выполнит перед выполнением. включите сообщения отладки оболочки с помощьюset -x
:Это говорит о том , что
ls
была запущена с тремя отдельными аргументами:'/home/terdon/foo/\e[92mM@r|<'
,'+'\''|'\''|_e|\|\|0rth'
и'[`-_-"]/pullingATerdon'
. Это происходит потому, что оболочка выполняет разбиение слов и расширение глобуса для строк без кавычек. В этом случае проблема заключается в разделении слов, поскольку оболочка видит пробелы в пути и считывает каждую разделенную пробелами строку как отдельный аргумент.mkdir
Пример немного отличается , но это потому , что вы показываете нам сообщение об ошибке от второго вызова команды. Я полагаю, вы попробовали это один раз, а затем запустили во второй раз, чтобы получить ответ на свой вопрос. Первый раз, когда вы запустили его, это выглядело бы так:Опять же, это попытается создать три каталога, а не один, из-за разделения слов. Во-первых, он создал (успешно) каталог
/home/terdon/foo/\e[92mM@r|<
:Затем он также успешно создал каталог с именем
+'|'|_e|\|\|0rth
в вашем текущем каталоге:А затем он попытался создать каталог
[`-_-"]/pullingATerdon
. Это не удалось, потому чтоmkdir
по умолчанию не создаются подкаталоги (это возможно, если вы запускаете его с помощью-p
):Поскольку ваша строка без кавычек содержала a
/
,mkdir
считала, что путь из двух каталогов, пыталась найти верхнюю и потерпела неудачу.Вот почему это не удалось, но то, что произошло, сложнее. Строка, используемая на самом деле оболочка Глоба, конкретно диапазон Glob , который соответствует всем файлам в текущем каталоге, имя которого один из 5 символов
`
,-
,_
или"
. Поскольку у вас нет таких файлов в текущем каталоге, глобус ничего не соответствует и, как это принято в bash по умолчанию, возвращает себя:Чтобы уточнить, вот что происходит, если вы даете глобус, который действительно соответствует чему-то:
Без кавычек
[p*]
расширяется до списка совпадающих имен файлов (в данном случае только одно), и это то, что передаетсяecho
. Еще одна причина, почему вы должны цитировать все вещи.Наконец, вы видите фактическую ошибку со второго раза, когда вы запустили команду, и она завершается с ошибкой на первом шаге при попытке создания
/home/terdon/foo/\e[92mM@r|<
, потому что предыдущий вызов уже создал этот каталог.В общем, всякий раз, когда вы работаете с произвольными именами файлов, всегда используйте оболочки оболочки. Вещи как это:
Это будет работать для любого имени файла. Неважно, что это содержит. В нашем примере выше вы могли бы сделать:
Подойдет любой глобус, который однозначно идентифицирует целевой файл. Таким образом, вам не нужно беспокоиться о специальных символах, и вы можете просто позволить оболочке обрабатывать их.
Несколько полезных ссылок:
Как я могу найти и безопасно обрабатывать имена файлов, содержащие переводы строк, пробелы или оба? : Один из часто задаваемых вопросов о превосходном Wiki Grey Cat.
Последствия для безопасности: забыть процитировать переменную в оболочках bash / POSIX : тот же пост, на который я ссылался в начале этого ответа. Отличное и очень подробное объяснение всех вещей, которые могут пойти не так, если вам не удастся правильно процитировать ваши переменные оболочки.
Почему мой сценарий оболочки задыхается от пробелов или других специальных символов? : все, что вы когда-либо хотели знать об обработке произвольных имен файлов в оболочке.
Когда необходимо двойное цитирование? : Подробнее о кавычках и переменных и, в частности, о нескольких случаях, когда вам не нужно их заключать в кавычки
источник