参数扩展好像少了一块

参数扩展好像少了一块

我目前正在学习如何编写简单的脚本,但无法解决一个非常简单的问题。

我的脚本中有以下命令...

touch ${DIRECTORY}/${FILE}

该命令在我的脚本中出现了多次,并且在除一个实例之外的所有实例中都运行良好。由于某种原因,仅在某一时刻,它决定在尝试创建的文件名中包含斜杠,并且我收到错误...

cannot touch `/myfile.dat': Permission denied

起初,我认为这可能是由于我缺乏经验(可能确实如此),但经过一些研究后,我发现这条线在无数示例中都可以正常工作。我无法理解 - 同一条线在我的脚本中的其他几个位置运行良好!

有人愿意解释一下吗?这种不一致真的让我很恼火。围绕该特定命令的命令会影响其结果吗?

答案1

看起来${DIRECTORY}是空的。在这种情况下,触摸${DIRECTORY}/${FILE}扩展到touch /${FILE}

答案2

可能会发生几件事。

  • 也许您DIRECTORY此时拼写错误,因此脚本正在运行类似touch ${DRIECTORY}/${FILE}.由于DIRECTORY未设置,如果$FILEis myfile.dat,则扩展为touch /${FILE}(未设置的变量被视为空)。
    如果您每次尝试扩展未设置的变量,则可以使 shell 停止并显示错误消息。放在set -u脚本的顶部(该#!行之后)。您可以使用set -u和在 unset-triggers-error 和 unset-is-empty 之间来回切换set +u
  • DIRECTORY此时变量可能未设置或为空。请参阅上一点。
  • 也许您不小心多加了一个空格:touch ${DIRECTORY} /${FILE}。然后该touch命令接收两个参数,对其进行操作${DIRECTORY}(因为这可能是现有目录的名称,因此将该目录的修改时间设置为当前时间),然后它在/${FILE}.
  • 也许 的值末尾有一个额外的空格DIRECTORY。例如,如果变量的值/some/path末尾有空格,则touch接收两个参数:/some/path/myfile.dat。请参阅上一点。

DIRECTORY如果或FILE包含任何空格或通配符,您的脚本将无法工作\[?*。这是因为当您编写 eg 时$FOO,这不仅仅扩展到变量的值:然后该值在每个空白序列处拆分为单词,并且每个单词都被解释为通配符模式并替换为匹配的文件名(如果没有文件名匹配,该模式将被保留)。始终在变量替换(以及同样的命令替换)周围使用双引号。在双引号内,"$FOO"扩展为 的值,FOO而无需进一步修改。

touch "$DIRECTORY/$FILE"

(也可以看看$VAR 与 ${VAR} 以及引用或不引用

为了更好地了解脚本正在做什么,请放在set -x#!行后面。这启用了调试模式,外壳程序在执行之前打印每个命令。您可以使用set -x和来打开和关闭调试跟踪set +x

相关内容