Изменить: Это дубликат /programming/998626/meaning-of-tilde-in-linux-bash-not-home-directory/ . У меня нет репутации, чтобы закрыть этот вопрос как дубликат.
Я не имею в виду ~
домашний каталог, а скорее это:
$ ls ~foo/bar
/some/mount/point/foo/bar
Однако, если я попытаюсь сделать это с другой точкой монтирования, например:
$ mount | ag "/dev "
devfs on /dev (devfs, local, nobrowse)
$ ls /dev/stdin
/dev/stdin
$ ls ~stdin
zsh: no such user or named directory: stdin .
# bash has a similar error message:
ls: ~stdin: No such file or directory
Как ~
называется в этом контексте? Как это работает?
Изменить: дополнительная информация на основе некоторых комментариев ниже:
- Я могу подтвердить, что
foo
это не имя пользователя в моей системе. - При попытке автозаполнения
ls -lah ~
отображаются не все параметры. т.е. я могуcd ~qux
, когдаqux
не появляется в автозаполнении. Опятьqux
не пользователь в моей системе. - Если это имеет значение
/some/mount/point
, это сетевой ресурс. - Все детали предполагают некоторую именованную траекторию, особенность оболочки Z для раскрытия пути, но это работает и в bash, которая, очевидно, не поддерживает такие вещи, как именованные пути оболочки Z.
~foo
домашний каталог пользователяfoo
. Если пользователь не указан, по умолчанию используется текущий пользователь./some/mount/point
определенно не мой домашний каталог.cd ~
берет меня на -/Users/$username/
какие матчи$HOME
zsh
также, кажется, использует тильду для обозначения именованных каталогов.bash -c "ls ~foo/bar"
), которая не имеет именованных каталогов. Более того, даже в zsh, если я проверяюenv
, я не вижу ни одного настроенного каталога. Я нахожусь на Mac OS, и я чувствую, что это какая-то особенность, характерная для OS X.~foo
. Возьми реальную строку (не примерfoo
) и сделайgrep "actual username" /etc/passwd
.~text
должен работать только для возможных имен пользователей для входа в систему в соответствии с руководством bash (не обязательно означает, что он действительно может войти в систему; в случае пользователей системы, таких как~lp
, например). Во всех моих тестах это~string
соответствуетstring
имени пользователя.Ответы:
Что такое ~ foo
Цитата из руководства bash (с добавлением акцента):
~foo
расширяется доfoo
домашнего каталога пользователя точно так, как указано в/etc/passwd
. Обратите внимание, что это может включать системные имена пользователей; это не обязательно означает, что пользователи или что они могут войти в систему локально (например, они могут войти через ключи SSH).На самом деле, как отмечено в комментариях ,
bash
будет использоватьсяgetpwnam
функция. Эта функция сама определяется POSIX стандартом, следовательно , должно существовать на большинстве Unix-подобных системах, в том числе MacOS X . Эта функция не ограничивается/etc/passwd
только и ищет другие базы данных, такие как LDAP и NIS. Отдельная выдержка изbash
исходного кода ,tilde.c
файла, начиная со строки 394:Практический пример
Ниже вы можете увидеть тесты с именами пользователей в моей системе. Обратите внимание на соответствующую
passwd
запись и результатls ~username
Даже если, например,
_apt
учетная запись заблокирована, как показано в выводе,passwd -S apt
она все равно отображается как возможное имя для входа:Обратите внимание: это не особенность MacOS, а особенность оболочки.
источник
/etc/shadow
вместе с другой защищенной аутентификационной информацией, такой как пароль. Ссылка наpasswd
это как раз делает пароль недействительным: это не помешает аутентификации другими способами.testuser
и изменением срока действия пароля. Имя пользователя по-прежнему отображается на вкладке «Завершение». Я убрал этот бит из ответаbash
справочную страницу (и, кажется, старая). ОП на самом деле используетzsh
(могло бы быть более понятным), хотя в комментариях упоминается, что онbash
ведет себя так же.getent passwd foo
вместо того,grep foo /etc/password
чтобы следовать тем же механизмам поиска, что и оболочка, возможно, включая сетевые службы каталогов, которые упоминает @Abigail.Вкратце, почему вы ищете что-то
~foo/bar
, это потому, что у вас есть имя пользователяfoo
в системе с папкойbar
в его домашнем каталоге.Посмотрите это решение в другом сообществе, которое объясняет, почему (тильда)
~
- это больше, чем просто «домашний каталог».Если в
bin
вашей системе есть имя пользователя , вы можете просмотреть содержимое домашнего каталога bin с помощью команды:ls ~bin
Еще одна вещь, которую вы можете попробовать, это использовать завершение табуляции после ввода следующего в приглашении (не перевод каретки, просто используйте клавишу табуляции):
ls -lah ~
tabчтобы увидеть список домашних каталогов пользователей, которые
~
будут расширяться, если вы продолжите. Пример (усеченный) вывод вкладки завершенияls -lah ~
tabисточник
/etc/passwd
. Это сразу помогает уточнить, что происходит, если пользователь, конечно, знает имена пользователей в своей системе.~foo
, что я выполнял автозаполнение, я могу подтвердить, чтоfoo
в моей системе нет пользователя (и в действительности его нет/etc/passwd
). Кроме того, все папки / файлы/some/mount/point
отображаются в автозаполнении, что очень интересно.