Считается ли тильда относительным путем?

Я пытаюсь извлечь другую часть установщика библиотеки nvidia cuda. Я использую следующую команду:

mkdir ~/Downloads/nvidia_installers
./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers

И я получаю следующее сообщение:

ERROR: extract: path must be absolute.

И когда я набираю команду с буквальным адресом моего дома, она отлично работает.

./cuda_6.5.14_linux_64.run -extract=/home/likewise-open/XXX/username/Downloads/nvidia_installers

Я запутался, не должно ли ~ быть то же самое из /home/likewise-open/XXX/username?

Проверено:

./cuda_6.5.14_linux_64.run -extract=$HOME/Downloads/nvidia_installers

и это работает, но я не знаю, почему это не позволяет ~

4 ответа

Решение

Bash расширяет только ~, если это начало слова. Вы можете увидеть это между следующими командами:

$ echo -extract=~/test
-extract=~/test

oli@bert:~$ echo -extract ~/test
-extract /home/oli/test

Bash ищет автономный ~ персонажи и ~/ для этой замены. Никакая другая комбинация или цитируемая версия не будут работать.

$HOME работает, потому что переменные замены более устойчивы ($ это специальный символ, тогда как ~ очень намного меньше)

$ echo Thisisastring${HOME}awrawr
Thisisastring/home/oliawrawr

Пока мы говорим о ~, у него на самом деле есть другая пара замен:

  • ~+ текущий рабочий каталог (читать из $PWD)
  • ~- предыдущий рабочий каталог (читать из $OLDPWD)

Как с равниной ~они могут иметь дополнительные пути, прикрепленные в конце, и опять же, они должны быть префиксом слова, иначе Bash их проигнорирует.

Вы можете прочитать больше об этом в man bash | less -p ' Tilde'

Просто исправляю

Эта команда показывает сообщение об ошибке "ОШИБКА: извлечение: путь должен быть абсолютным":

./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers

Ошибка не помогает - программа уже слишком запуталась.
Вы уже знаете, ошибка от ~ как это работает с $HOME вместо.

Эта проблема: ~ заменяется только в начале слова.

Например, это работает с тильдой:

echo -extract ~/Downloads

Если вам нужен синтаксис опции с =, используя $HOME вместо ~ самое чистое решение;

echo -extract=$HOME/Downloads

Практика

То, что вы должны знать:

Есть особые случаи, когда ~ get расширяется, когда не в начале слова: как часть присваивания переменной, сразу после =, Что, конечно, сбивает с толку.

Другой важный особый случай - использование с такими переменными, как PATH. В переменных назначениях, ~ также расширяется после : вроде после первого =,

$ dir=~ sh -c 'echo D2: $dir'
D2: /home/user
$ sh -c 'echo D2: $dir' dir=~
D2: 
$ echo Dir: $dir
Dir:
$ dir=~; sh -c 'echo D2: $dir'
D2: 
$ echo Dir: $dir
Dir: /home/user
$ sh -c 'echo D2: $dir'; d3=~
D2: 
$ echo d3: $d3
d3: /home/user

Смысл тильды

В оболочке, ~ Тильда, на самом деле не путь. Это только заменено путем, $HOME, несколько раз.

Это что-то вроде сокращения или сокращения, предоставляемого оболочкой.
Его нельзя использовать как путь в целом, оболочка "расширяет" его до пути только в очень особых местах.
И даже если он расширен, он может быть чем-то другим, кроме домашнего каталога.

  • Он раскрывается только в начале слова или в присваивании переменной после : или же =
  • Расширяется только если не в кавычках
  • Расширяется только до $HOME если в слове нет следующих символов перед /

Проблема в командной строке

В соответствии с этим, проблема в вашей команде заключается в том, что тильда в

-extract=~/Downloads/nvidia_installers

не раскрывается, потому что это не один из перечисленных случаев. Это все.

Решение может заключаться в том, чтобы сделать тильду первым символом слова без кавычек, без другого символа перед следующим / - это именно то, что вы получаете, когда используете опцию с пробелом перед аргументом опции:

-extract ~/Downloads/nvidia_installers

Другое решение было бы использовать $HOME вместо. В сценарии это обычно лучший выбор.

-extract=$HOME/Downloads/nvidia_installers

Сообщение об ошибке

Но как работает сообщение об ошибке
"ERROR: extract: path must be absolute."?
вписаться во все это?

Мы знаем, что тильда не расширилась. Это означает, что программа получила текст аргумента, включая ~, но без /home/auser как путь. Этот путь ~/Downloads/nvidia_installers - но сейчас нет раковины, поэтому тильда не имеет особого значения. Это просто нормальное имя каталога. И как любой другой путь формы foo/bar/baz это относительный путь

Другое использование

Если после ~, как в ~alice - со всеми другими правилами выше применения - и есть имена пользователей alice, который расширяется до домашнего каталога alice вместо этого, скажем home/alice,
Кроме того, если вы bob, ~ будет расширяться до /home/bob, а также ~bob расширится к тому же.

Вариант ~+ разворачивается в текущий каталог, $PWD

Для ссылки на предыдущий каталог, где вы были до последнего cd, ты можешь использовать ~-, который расширяется до $OLDPWD,

Если вы используете pushd а также popd, вместо cd, вы уже будете знать, что стек каталогов можно получить как ~-2,

подробности

Все случаи, когда ~ Расширяется до пути , обработанного оболочкой. Для других программ ~ это просто обычный символ имени файла.

Для точного определения внутри оболочки, вот соответствующий раздел man bash
Обратите внимание, как замена ~ от $HOME это лишь один частный случай из многих случаев: "Если это имя для входа в систему является пустой строкой, тильда заменяется значением параметра оболочки HOME".:

Tilde Expansion
    If a word begins with an unquoted tilde character (`~'), all of the charac‐
    ters  preceding the first unquoted slash (or all characters, if there is no
    unquoted slash) are considered a tilde-prefix.  If none of  the  characters
    in  the tilde-prefix are quoted, the characters in the tilde-prefix follow‐
    ing the tilde are treated as a possible login name.  If this login name  is
    the  null string, the tilde is replaced with the value of the shell parame‐
    ter HOME.  If HOME is unset, the home directory of the user  executing  the
    shell is substituted instead.  Otherwise, the tilde-prefix is replaced with
    the home directory associated with the specified login name.

    If the tilde-prefix is a `~+', the value of the shell variable PWD replaces
    the  tilde-prefix.   If  the tilde-prefix is a `~-', the value of the shell
    variable OLDPWD, if it is set, is substituted.  If the characters following
    the tilde in the tilde-prefix consist of a number N, optionally prefixed by
    a `+' or a `-', the tilde-prefix is replaced with the corresponding element
    from  the  directory  stack,  as  it would be displayed by the dirs builtin
    invoked with the tilde-prefix as an argument.  If the characters  following
    the  tilde in the tilde-prefix consist of a number without a leading `+' or
    `-', `+' is assumed.

    If the login name is invalid, or the tilde expansion  fails,  the  word  is
    unchanged.

    Each variable assignment is checked for unquoted tilde-prefixes immediately
    following a : or the first =.  In these cases, tilde expansion is also per‐
    formed.   Consequently, one may use filenames with tildes in assignments to
    PATH, MAILPATH, and CDPATH, and the shell assigns the expanded value.

~ это не путь сам по себе. Это персонаж, который получает специальную обработку из оболочки, где ~ или же ~/ означает "заменить на путь к домашнему каталогу текущего пользователя". ~username означает "заменить на путь к домашней директории пользователя".

Поскольку это не путь, он распознается только в определенных местах команды (как первый символ нового токена с разделением пробелами).

При расширении он заменяется абсолютным путем.

С помощью $HOME работает, потому что HOME - это просто переменная, установленная оболочкой, и следует нормальным правилам оболочки для замены переменных (это происходит до того, как входные данные разделены на пробелы и выполнены).

Ты прав. ~/Downloads такой же, как / home / username / Downloads.

Некоторые инсталляторы и экстракторы очень разборчивы в том, куда нужно поместить вещи. Я думаю, что это может быть потому, что он регистрирует пути к файлам, и журналы не принимают ~ по принятому пути.

Я просто привык вместо этого вводить / home / username.:)

Другие вопросы по тегам