源无法识别cwd?

源无法识别cwd?

我有一个 bash 脚本,它获取一个文件,该文件获取另一个文件:

script.sh:
cd /script/dir
source funcs.sh


funcs.sh:
...
source mode.sh

现在,当我从 /script/dir 中的命令行运行该脚本时,该脚本运行正常。但是当我从 crontab 运行它时,funcs.sh 文件找不到 mode.sh。可能是因为某种原因cd /script/dir没有传递给它?我可以在脚本中做任何事情,或者我需要在 cron 中执行 cd 或类似的操作吗?

答案1

可能出现的问题:

  1. 没有舍邦里面script.sh。如果告诉 cron 运行,script.sh那么它会像这样运行/bin/sh -c script.sh(除非SHELL你的 crontab 内部指向 以外的东西/bin/sh,我们不知道这一点)。由于没有 shebang,因此适用:哪个 shell 解释器运行不带 shebang 的脚本?答案取决于您的 cron 使用什么 shell,我们不确定这一点。最终sh可能会选择其他东西作为脚本的解释器。即使选择了,它也可能由或其他东西sh提供(默认情况下在 Ubuntu 中,但我们不知道是否真的如此)dashbashdash在你的情况下)。

    关键是script.sh当脚本从 cron 启动时,我们并不真正知道解释器是什么。我想在某些情况下脚本可能根本无法从 cron 启动。

    OTOH 当您从交互式 shell 运行脚本时,可能会选择不同的解释器然后它就可以工作。

  2. cd /script/dir可能会因某种原因失败(例子)。

  3. source是 的别名.,但并非在所有 shell 中。由于我们不认识解释器,所以我们不知道它是否理解source

  4. 即使解释器将其理解source为 as .,参数仍是funcs.sh且不包含/。在这种情况下, POSIX 的行为.funcs.sh$PATH.现在:

    • 即使您$PATH包含.(即当前工作目录),cron 中的相同变量也可能不包含它。

    • 仅当搜索$PATH失败时,一些shell 尝试当前工作目录。

要修复,请执行以下操作:

  1. 在里面使用 shebang script.sh,这样你就可以控制script.sh执行时使用哪个 shell 来解释。

    (根据您选择的 shell,修复程序 (3) 和 (4) 可能是必要的,也可能不是必要的;它们不会造成损害,因此如果有任何疑问,请无论如何应用它们。)

  2. 如果失败则中止cd。如果脚本在cd失败后继续,则脚本可能会尝试funcs.sh从错误的目录获取源。

  3. 使用.而不是source.前者是便携式的,后者则不是。

  4. /使用包含(在本例中./funcs.sh而不是)的显式路径funcs.sh,因此无需搜索,$PATH并且清楚您的意思是什么文件。

固定的script.sh将是这样的:

#!/bin/sh
cd /script/dir || exit 1
. ./funcs.sh

funcs.sh不需要在 shebang内部,因为该文件是由 shell 解释获取的script.sh,但修复 (3) 和 (4) 可能仍然是必要的(取决于所选的 shell)。

答案2

每个进程都有一个$PWD(工作目录)cron 不在您的$HOME.您可以使用这个来代替cd脚本中的 ing

#!/bin/bash

dir="$(dirname "$(readlink -f "$0")")"
echo $dir

$dir是脚本的位置目录。例如

$ cd /
$ bash /home/junaga/script.sh

输出/home/junaga,因为那是脚本位置

相关内容