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
не будет работать как ожидалось.
Что я могу сделать для очистки того полного пути, таким образом, он будет работать с другими командами?
В первую очередь, всегда заключайте свои переменные в кавычки. То, что Вы пытаетесь сделать, хорошо работает, если Вы заключаете его в кавычки правильно:
$ pwd
/home/terdon/foo/\e[92mM@r|< +'|'|_e|\|\|0rth [`-_-"]
$ ls
pullingATerdon
Я сохранил странное имя файла, которое Вы выбрали (хотя я понятия не имею, почему Вы выбрали его) ради непротиворечивости.
Теперь, давайте присвоим путь pullingATerdon
к переменной и затем пытаются открыть файл:
$ bacon="$(realpath pullingATerdon)"
$ echo "$bacon"
/home/terdon/foo/\e[92mM@r|< +'|'|_e|\|\|0rth [`-_-"]/pullingATerdon
$ ls $bacon
ls: cannot access '+'\''|'\''|_e|\|\|0rth': No such file or directory
ls: cannot access '[`-_-"]/pullingATerdon': No such file or directory
'/home/terdon/foo/\e[92mM@r|<':
Это перестало работать, как ожидалось. Но, если мы теперь заключаем его в кавычки правильно:
$ ls -l "$bacon"
-rw-r--r-- 1 terdon terdon 0 Mar 14 23:15 '/home/terdon/foo/\e[92mM@r|< +'\''|'\''|_e|\|\|0rth [`-_-"]/pullingATerdon'
Это работает как ожидалось. И да, можно также открыть путь в (надлежащем) редакторе: emacs "$bacon"
будет работать просто великолепно. Хорошо, так будет vim
и что-либо еще. Ваш выбор редактора, хотя неудачный, не релевантен.
Быстрый способ проследить, что на самом деле произошло в Вашем случае, состоит в том, чтобы использовать set -x
(выключите его снова с set +x
), который заставляет оболочку печатать каждую команду, которую она выполнит прежде, чем выполнить его. включите сообщения отладки оболочки с set -x
:
$ set -x
$ /bin/ls $bacon
+ ls '/home/terdon/foo/\e[92mM@r|<' '+'\''|'\''|_e|\|\|0rth' '[`-_-"]/pullingATerdon'
ls: cannot access '+'\''|'\''|_e|\|\|0rth': No such file or directory
ls: cannot access '[`-_-"]/pullingATerdon': No such file or directory
'/home/terdon/foo/\e[92mM@r|<':
Это показывает нам это ls
был выполнен с тремя отдельными аргументами: '/home/terdon/foo/\e[92mM@r|<'
, '+'\''|'\''|_e|\|\|0rth'
и '[`-_-"]/pullingATerdon'
. Это происходит, потому что оболочка выполняет разделение слова и расширение шарика на неупомянутых строках. В этом случае проблемой является разделение слова, так как оболочка видела пробелы в пути и считала каждую разделенную пробелами строку как отдельный аргумент.
mkdir
пример немного отличается, но поэтому Вы показываете нам сообщение об ошибке от второго вызова команды. Я предполагаю, что Вы попробовали его однажды и затем выполнили его во второй раз для получения вывода для вопроса. В первый раз, когда Вы выполнили его, это будет похоже на это:
$ mkdir $(realpath pullingATerdon)
++ realpath pullingATerdon
+ mkdir '/home/terdon/foo/\e[92mM@r|<' '+'\''|'\''|_e|\|\|0rth' '[`-_-"]/pullingATerdon'
mkdir: cannot create directory ‘[`-_-"]/pullingATerdon’: No such file or directory
Снова, это попытается создать три каталога, не один, из-за разделения слова. Во-первых, это создало (успешно) каталог /home/terdon/foo/\e[92mM@r|<
:
$ ls -l /home/terdon/foo/
total 8
drwxr-xr-x 2 terdon terdon 4096 Mar 15 00:20 '\e[92mM@r|<'
drwxr-xr-x 3 terdon terdon 4096 Mar 15 00:20 '\e[92mM@r|< +'\''|'\''|_e|\|\|0rth [`-_-"]'
Это затем, также успешно, создало названный каталог +'|'|_e|\|\|0rth
в Вашем текущем каталоге:
$ ls -l
total 4
drwxr-xr-x 2 terdon terdon 4096 Mar 15 00:37 '+'\''|'\''|_e|\|\|0rth'
-rw-r--r-- 1 terdon terdon 0 Mar 15 00:36 pullingATerdon
И затем, это попыталось создать каталог [`-_-"]/pullingATerdon
. Это перестало работать потому что mkdir
, по умолчанию, не создает подкаталоги (это может при выполнении его с -p
):
$ mkdir baz/bar
mkdir: cannot create directory ‘baz/bar’: No such file or directory
Так как Ваша неупомянутая строка содержала a /
, mkdir
рассмотренный, что путь двух каталогов, которые попробовали для нахождения лучшего, и отказавший.
Вот почему это перестало работать, но что произошло, более сложно. Строка, которую Вы использовали, является на самом деле шариком оболочки, конкретно диапазон шарика, который соответствует всем файлам в текущем каталоге, имя которого является одним из этих 5 символов `
,-
, _
или "
. Так как у Вас нет таких файлов в Вашем текущем каталоге, шарик ничему не соответствует и, как поведение по умолчанию в ударе, возвраты себя:
$ echo "[\`-_-\"]/pullingATerdon" ## some escaping is needed here
+ echo '[`-_-"]/pullingATerdon' ## but it echoes the right thing
[`-_-"]/pullingATerdon ## and matches nothing, so returns itself.
Для разъяснения вот то, что происходит, если Вы даете шарик, который действительно соответствует чему-то:
$ echo [p]* ## any filename starting with a p
pullingATerdon
$ echo "[p]*" ## the string "[p]*"
[p]*
Неупомянутое [p*]
расширен до списка соответствия именам файлов (всего один, в этом случае) и именно это передается echo
. Еще одна причина, почему необходимо заключить все вещи в кавычки.
Наконец, фактическая ошибка, которую Вы показываете, от второго раза, когда Вы выполнили команду, и это перестало работать в первом шаге при попытке создать /home/terdon/foo/\e[92mM@r|<
, потому что предыдущий вызов уже создал тот каталог.
В более общем плане, каждый раз, когда Вы работаете с произвольными именами файлов, всегда используйте шарики оболочки. Вещи как это:
for file in *; do command "$file"; done
Это будет работать на любое имя файла. Независимо от того, что это, оказывается, содержит. В нашем примере выше, Вы, возможно, сделали:
emacs /home/terdon/*92mM*/pullingATerdon
Любой шарик, который определяет конечный файл исключительно, сделает. Тем путем Вы не должны волноваться о специальных символах и можете просто позволить оболочке обработать их.
Некоторые полезные ссылки:
Как я могу найти и безопасно обработать имена файлов, содержащие новые строки, пробелы или обоих?: Один из часто задаваемых вопросов на Wiki превосходного Серого CAT.
Последствия безопасности упущения заключить переменную в кавычки в оболочках удара/POSIX: то же сообщение я сослался в начале этого ответа. Большое и очень подробное объяснение всех вещей, которые могли пойти не так, как надо, если Вам не удается заключить Ваши переменные оболочки в кавычки правильно.
Почему мой сценарий оболочки дросселирует на пробеле или других специальных символах?: все Вы когда-либо хотели знать об обработке произвольных имен файлов в оболочке.
Когда двойное заключение в кавычки необходимо?: Больше о кавычках и переменных, и конкретно нескольких случаях, где Вы не должны заключать им в кавычки