波浪号,`~` 被认为是相对路径吗?

Reg*_*gan 37 command-line paths

我正在尝试提取 Nvidia cuda 库安装程序的不同部分。我正在使用以下命令:

mkdir ~/Downloads/nvidia_installers
./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers
Run Code Online (Sandbox Code Playgroud)

我收到以下消息:

ERROR: extract: path must be absolute.
Run Code Online (Sandbox Code Playgroud)

当我用我家的字面地址输入命令时,它工作得很好。

./cuda_6.5.14_linux_64.run -extract=/home/likewise-open/XXX/username/Downloads/nvidia_installers
Run Code Online (Sandbox Code Playgroud)

我很困惑不应该 ~ 与 /home/likewise-open/XXX/username 相同吗?

测试:

./cuda_6.5.14_linux_64.run -extract=$HOME/Downloads/nvidia_installers
Run Code Online (Sandbox Code Playgroud)

它有效,但我不知道为什么它不允许 ~

Oli*_*Oli 50

Bash 仅扩展 ~ 如果它是单词的开头。您可以在以下命令之间看到这一点:

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

oli@bert:~$ echo -extract ~/test
-extract /home/oli/test
Run Code Online (Sandbox Code Playgroud)

Bash 寻找独立的~字符和~/这种替换。没有其他组合或引用版本将起作用。

$HOME之所以有效,是因为变量替换更健壮(这$是一个特殊字符,而~很少如此):

$ echo Thisisastring${HOME}awrawr
Thisisastring/home/oliawrawr
Run Code Online (Sandbox Code Playgroud)

当我们谈论 时~,它实际上还有另外几个替代用途:

  • ~+当前工作目录(从 读取$PWD
  • ~-上一个工作目录(从 中读取$OLDPWD

与 plain 一样~,这些可以在末尾添加额外的路径,同样,这些必须是单词的前缀,否则 Bash 将忽略它们。

您可以在 man bash | less -p ' Tilde'

  • 值得注意的是,`zsh` _does_(或者更确切地说可以配置为)在`=` 之后扩展`~`。在其他方便的改进中,它对 bash 进行了改进。 (2认同)

Vol*_*gel 19

刚修好

此命令显示错误消息“错误:提取:路径必须是绝对的”:

./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers
Run Code Online (Sandbox Code Playgroud)

该错误没有帮助 - 程序已经太混乱了。
您已经知道错误来自~,因为它可以使用$HOME

问题:~仅在单词的开头被替换。

例如,这适用于波浪号:

echo -extract ~/Downloads
Run Code Online (Sandbox Code Playgroud)

如果您需要带选项的语法=,使用 $HOME 而不是~最干净的解决方案;

echo -extract=$HOME/Downloads
Run Code Online (Sandbox Code Playgroud)

实践

你应该知道的:

在某些特殊情况下,~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
Run Code Online (Sandbox Code Playgroud)

波浪号的含义

在 shell 中,~波浪号 并不是真正的路径。有时它只会被路径替换$HOME

它类似于 shell 提供的速记或缩写。
它不能像一般的路径一样使用,shell 仅在非常特殊的地方将它“扩展”为路径。
即使它被扩展,它也可以是主目录以外的其他东西。

  • 它仅在扩展一个单词的开头,或在一个变量赋值后:=
  • 仅当它不在引号内时才会扩展
  • $HOME当a 之前的单词中没有其他字符时才扩展为/

命令行中的问题

据此,您的命令中的问题是波浪号

-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.

如果您使用pushdandpopd而不是cd,您将已经知道可以像~-2.

细节

~扩展到路径的所有情况都由 shell 处理。对于其他程序,~它只是一个普通的文件名字符。

对于确切的定义在外壳内部,这里的相关章节 说明如何更换的只是一个的情况很多特殊情况:“如果这个登录名是空字符串,波浪线将被替换为shell参数HOME的值。 ” man bash
~$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.
Run Code Online (Sandbox Code Playgroud)