为什么在BIN_DIR =“〜/ bin /”的脚本中,mkdir失败(没有这样的文件或目录)?


Answers:


11

~Zanna的答案中所述,由于引用了波浪号而产生了错误消息。如果要使用~,脚本的相关部分应为:

BIN_DIR=~/bin/

如果出于某种原因想要引用字符串,则可以使用环境变量$HOME

BIN_DIR="$HOME/bin/"

我认为第二种方法是更好的做法。


6
~在脚本中使用没有任何问题。它的工作方式与在命令行中完全相同。问题是引号会阻止波浪号扩展,如Zanna的答案所述
terdon

@terdon,我同意。但是我没有告诉您有什么问题,但这是一个更好的主意,因为您应该少注意。
pa4080

5
但是这里的命令行和脚本之间绝对没有区别。这在脚本中是完全不相关的,在命令行中您将有完全相同的错误。问题是引号,而不是脚本中的引号。
terdon

虽然完全正确,但$HOME在脚本中使用是个好主意。
甜点,

3
@ pa4080您能否添加一个解释,说明为什么您认为扩展$HOME比使用代字扩展更好?您给出的唯一解释是说:“这是一个更好的主意,因为您应该少注意。” 我不知道那是什么意思。您可以在编辑中对此进行阐述吗?没有它,没有任何东西可以支持您的答案,因此可以肯定它属于其中。POSIX要求Tilde扩展已经有一段时间了 脚本的hashbang行是,#!/bin/bash所以我认为可移植性不是原因。
伊莱亚·卡根

23

因为~引用了,所以它不起作用。双引号 "可抑制波浪号扩展。没有名称为的目录~/bin。如man bash(重点我的)中所述:

波浪号扩展

如果单词以未加引号的波浪号字符('〜')开头,则将第一个未加引号的斜杠(或所有字符,如果没有未加引号的斜杠)之前的所有字符视为波浪号前缀。如果没有在波浪号前缀中引用任何字符,则将波浪号后的波浪号前缀中的字符视为可能的登录名。如果此登录名是空字符串,则将波浪号替换为shell参数HOME的值。如果未设置HOME,则将替换执行Shell的用户的主目录。否则,将tilde-prefix替换为与指定登录名关联的主目录。

您可以删除引号,因为这~是路径~/bin中会导致Shell执行扩展的唯一字符,在这种情况下,我们需要扩展。至少在Bash 4中,Shell 不会对波浪号扩展的结果进行任何进一步的扩展,而Bash 4当前或远程的所有Ubuntu版本都具有。因此,即使您的主目录包含不寻常的字符(例如空格),也可以。

或者你可以使用$HOME代替~,因为参数扩展不是由双引号抑制,只有单引号。双引号确实确保扩展的值本身不会受到任何进一步的扩展,因此不会发生单词拆分文件名扩展。因此,$HOME即使有奇怪的命名主目录,也有效,只要你保持双引号。


根据此陈述,“参数扩展不会被双引号抑制,只能被单引号​​抑制”cd '~'is 的输出-bash: cd: ~: No such file or directory
pa4080 '17

2
@ pa4080的扩展~不是参数扩展的一部分。
Barmar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.