我正在尝试提取 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
并且它可以工作,但我不知道为什么它不允许~
答案1
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
)
与 plain 一样~
,这些可以在末尾附加额外的路径,同样,这些必须是单词的前缀,否则 Bash 会忽略它们。
您可以在以下位置阅读更多相关信息man bash | less -p ' Tilde'
答案2
只是修复它
此命令显示错误消息“ERROR:extract:路径必须是绝对的”:
./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
波浪号的含义
在 shell 中,波浪符号 并不是真正的路径。它只是有时~
被路径 所取代。$HOME
它类似于 shell 提供的简写或缩写。
它不能像一般路径一样使用,shell 只会在非常特殊的地方将其“扩展”为路径。
即使它被扩展,它也可能被扩展为主目录以外的其他内容。
- 它只扩展到单词的开头或
:
或之后的变量赋值=
- 它只在以下情况下扩展:不在引号内
- 只有
$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
- 但现在没有 shell,因此波浪号没有特殊含义。它只是一个普通的目录名称。与所有其他形式的路径一样foo/bar/baz
,它是一个相对路径
其他用途
如果 后面有字符~
,如~alice
- 适用上述所有其他规则 - 并且有一个用户名alice
,则将扩展为 的主目录alice
,例如home/alice
。
此外,如果您是bob
,~
将扩展为/home/bob
,并且~bob
将扩展为 相同。
变体~+
扩展到当前目录,$PWD
要引用上一个目录(即上一个 之前所在的目录),cd
您可以使用~-
,其扩展为$OLDPWD
。
如果您使用pushd
和popd
,而不是cd
,那么您就已经知道目录堆栈可以像这样访问~-2
。
细节
~
所有扩展为路径的情况由 shell 处理. 对于其他程序来说,~
仅仅是一个普通的文件名字符。
为了确切定义在 shell 内部,以下是相关部分man bash
请注意,替换~
为$HOME
只是众多情况中的一个特例:“如果此登录名为空字符串,则波浪号将被替换为 shell 参数 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.
答案3
~
本身并不是路径。它是 shell 中得到特殊处理的字符,其中~
或~/
表示“用当前用户的主目录路径替换”。~username
表示“用用户名的主目录路径替换”。
因为它不是路径,所以它只能在命令中的某些位置被识别(作为新空间分割标记的第一个字符)。
扩展后,它会被绝对路径所取代。
使用$HOME
有效是因为 HOME 只是一个由 shell 设置的变量,并且遵循正常的 shell 变量替换规则(它发生在输入按空格拆分并执行之前)。
答案4
你是对的。~/Downloads 与 /home/username/Downloads 相同。
有些安装程序和提取程序对于放置内容的位置非常挑剔。我认为这可能是因为它记录文件路径,而日志不会接受可接受路径中的 ~。
我只是习惯输入 /home/username。:)