为什么在 BIN_DIR="~/bin/" 的脚本中 mkdir 会失败(没有这样的文件或目录)?

为什么在 BIN_DIR="~/bin/" 的脚本中 mkdir 会失败(没有这样的文件或目录)?

为什么 mkdir 命令失败并显示:“没有这样的文件或目录”?

#!/bin/bash

set -e

BIN_DIR="~/bin/"

if [ ! -d "$BIN_DIR" ]; then
  mkdir "$BIN_DIR"
fi

答案1

~由于被引用,因此它不起作用。双引号 "压制波浪号扩展. 没有具有文字名称的目录~/bin。如man bash(重点是我的):

波浪号扩展

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

您可以删除引号,因为~是路径中唯一~/bin会导致 shell 执行扩展的字符,而我们在本例中需要执行扩展。shell不会表演对波浪号扩展结果的任何进一步扩展,至少在 Bash 4 中,所有当前或较新的 Ubuntu 版本。因此,即使您的主目录包含空格等不常见字符,也没关系。

或者你可以$HOME使用因为~参数扩展不会被双引号抑制,只能被单引号. 双引号确保扩展的值本身不会受到任何进一步扩展的影响,因此单词拆分或者文件名扩展不会发生这种情况。因此$HOME,即使使用名称奇怪的主目录,只要保留双引号,也可以正常工作。

答案2

产生错误消息是因为波浪号~被引用,如 Zanna 的回答。如果要使用~,脚本的相关部分应该是:

BIN_DIR=~/bin/

如果无论什么原因您想要引用字符串,可以使用环境变量$HOME

BIN_DIR="$HOME/bin/"

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

相关内容