我目前正在学习如何编写简单的脚本,但无法解决一个非常简单的问题。
我的脚本中有以下命令...
touch ${DIRECTORY}/${FILE}
该命令在我的脚本中出现了多次,并且在除一个实例之外的所有实例中都运行良好。由于某种原因,仅在某一时刻,它决定在尝试创建的文件名中包含斜杠,并且我收到错误...
cannot touch `/myfile.dat': Permission denied
起初,我认为这可能是由于我缺乏经验(可能确实如此),但经过一些研究后,我发现这条线在无数示例中都可以正常工作。我无法理解 - 同一条线在我的脚本中的其他几个位置运行良好!
有人愿意解释一下吗?这种不一致真的让我很恼火。围绕该特定命令的命令会影响其结果吗?
答案1
看起来${DIRECTORY}
是空的。在这种情况下,触摸${DIRECTORY}/${FILE}
扩展到touch /${FILE}
答案2
可能会发生几件事。
- 也许您
DIRECTORY
此时拼写错误,因此脚本正在运行类似touch ${DRIECTORY}/${FILE}
.由于DIRECTORY
未设置,如果$FILE
ismyfile.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
。