shell 脚本应该在绝对路径还是相对路径下工作?

shell 脚本应该在绝对路径还是相对路径下工作?

我正在将一些批处理脚本转换为 shell 脚本。批处理脚本具有 cd 命令,但仍然使用绝对路径。

foo.bat:

pushd
cd C:\some\directory
copy C:\some\directory\foo.txt C:\some\other\directory
popd

我认为此脚本中的 cd 是多余的,因为正在复制的文件是使用绝对路径调用的。我需要将其转换为 shell 脚本。我有以下两个选择:

测试1.sh:

cp /some/directory/foo.txt /some/other/directory

测试2.sh:

cd /some/directory
cp foo.txt /some/other/directory

第一个仅使用 cp 和绝对路径,第二个使用 cd 和相对路径。

我的问题是:就在 shell 脚本中使用路径而言,这两个示例中哪一个是更好的做法?

作为一个附带问题,这些示例中是否需要 pushd/popd ?

答案1

调用脚本不一定是坏事cd,但应该谨慎行事。多次调用会cd产生“代码味道”。绝对路径通常更可取。

cd可能会失败。请务必正确处理错误。

调用 后cd,相对路径将变得无效。特别是,如果您正在编写一个包装器脚本来准备一些内容,然后运行另一个命令,则永远不要调用cd:用户可能依赖于在原始目录中运行的命令。如果您的脚本使用在命令行上传递的文件名,它们通常是相对于原始目录的;你可以"$PWD/"在它们前面加上绝对值,但是如果出现问题,这会导致错误消息。

该变量PWD始终包含当前目录,因此您可以将其保存到另一个变量中,并通过cd稍后调用更改回来。但是,请注意,这在某些边缘情况下可能会失败,例如以低权限运行的脚本不允许更改回其原始目录,或者在脚本运行时移动的目录。

请注意相对路径:它们可以以 开头,如果您不采取预防措施,-以 开头的命令参数将被解释为选项。-绝对路径则不存在这个问题。

答案2

据我的经验,这主要取决于您的需求和偏好,
您会发现很多文档将其留给用户。这是我注意到的:

  • 绝对路径更清晰:谁将不得不维护/修改您的脚本(您或其他人)将能够知道每次涉及哪些目录;
  • 使用绝对路径,您可以确定所涉及的目录是具有您在脚本中编写的确切路径的目录;
  • 相对路径较短,但您需要确定您正在使用的子树;
  • 您可以在脚本开头用变量替换重复路径来实现简短(例如 /var/log/app/component/module/logfile.log -> $module_log_dir/logfile.log)

正如 thrig 所注意到的,您可以在要执行的命令之前添加对所涉及目录的检查。

相关内容