使用cron运行脚本的正确方法?

时间:2021-04-01 01:05:32

When running a script with cron, any executable called inside must have the full path. I discovered this trying to run wondershaper, when many errors showed when it tried to call tc. So my question is, what's the proper way to overcome this problem?

使用cron运行脚本时,内部调用的任何可执行文件都必须具有完整路径。我发现这个尝试运行奇迹,当许多错误显示它试图调用tc时。所以我的问题是,克服这个问题的正确方法是什么?

Possible solutions:

  • cd to the executable folder and prepare symbolic links to any other called executable there (not sure if it works - low portability)
  • cd到可执行文件夹并准备符号链接到任何其他被称为可执行文件(不确定它是否工作 - 低可移植性)

  • use full paths in the script (it works - low portability across different distros)
  • 在脚本中使用完整路径(它可以工作 - 跨不同发行版的低可移植性)

  • exporting a path variable with the needed paths inside the script (not sure if it works)
  • 导出路径变量,在脚本中包含所需的路径(不确定它是否有效)

Well, thanks in advance for anyone helping.

好吧,先谢谢任何人的帮助。

4 个解决方案

#1


Declaring variables inside your cron job is more explicit and easier to maintain : all you have to modify is contained in your cron job, and you don't need to transfer multiple files should you move it to another system.

在cron作业中声明变量更明确,更易于维护:您需要修改的所有内容都包含在您的cron作业中,如果您将其移动到另一个系统,则无需传输多个文件。

PATH=/usr/bin:/your/fancy/dir
MYAPPROOT=/var/lib/myapp

*/2 * * * * myappinpath
*/3 * * * * $MYAPPROOT/mylocalapp

#2


If you're on linux/bsd/mac you can set some environment variables like PATH right in the crontab, and with that you're generally good to go.

如果你在linux / bsd / mac上,你可以在crontab中设置一些像PATH这样的环境变量,你可以通常使用它。

If you're on Solaris, well, I pray for you. But, I do have an answer too: I generally source .profile before running anything:

如果你在Solaris上,那么,我为你祈祷。但是,我也有一个答案:我通常在运行任何东西之前使用.profile:

0 0 * * 0 . /home/myuser/.profile && cd /path && ./script

Mind you, my .profile loads .bash_profile and .bashrc. Just be sure whatever file you source has what you need.

请注意,我的.profile加载.bash_profile和.bashrc。只要确保您提供的文件中包含您需要的内容。

#3


Since cron does not run login, .profile and /etc/profile are not sourced. Therefore PATH may not be set to a value you expect. I would either

由于cron没有运行登录,因此不会提供.profile和/ etc / profile。因此,PATH可能未设置为您期望的值。我会的

  • set and export PATH to an appropriate value
  • 设置PATH并将其导出为适当的值

  • use full paths in the script
  • 在脚本中使用完整路径

Your trick with symlinks assumes . is in the PATH and just does not seem nice

使用符号链接的技巧假定。是在PATH中,似乎并不好看

#4


My recomendation:

Set all variables in a external file. I use 'process_name.env' file located in /etc/process_name or similar. Imagine you have a backup script. Then you:

将所有变量设置在外部文件中。我使用位于/ etc / process_name中的'process_name.env'文件或类似文件。想象一下,你有一个备份脚本。那么你:

  • Create /etc/backup.env and put all environment variables needed for do the "backup" task.
  • 创建/etc/backup.env并放置执行“备份”任务所需的所有环境变量。

  • Modify your backup script and add this line after Shebang:

    修改你的备份脚本并在Shebang之后添加这一行:

    . /etc/backup.env #There is a dot and a space before full path to backup environment.

    。 /etc/backup.env#在备份环境的完整路径之前有一个点和一个空格。

IMO this approach is better than declaring variables at CRON definitions because:

IMO这种方法比在CRON定义中声明变量更好,因为:

  • Easy to maintain. Just edit a file.
  • 易于维护。只需编辑一个文件。

  • Easy to switch configuration/centralized configuration:
    • You can have multiple .env for using your script in different situations (for example, consider you have backup locations on your .env, you can pass .env location as an argument and run your cron job daily providing an .env with few locations and weekly with different locations by providing another .env, just a example).
    • 在不同的情况下,您可以使用多个.env来使用脚本(例如,考虑在.env上有备份位置,您可以将.env位置作为参数传递,并且每天运行您的cron作业,提供几个位置的.env和每周一次,提供另一个.env,只是一个例子)。

  • 易于切换配置/集中配置:您可以在不同情况下使用多个.env来使用您的脚本(例如,考虑您在.env上有备份位置,您可以将.env位置作为参数传递并每天运行您的cron作业通过提供另一个.env来提供具有少量位置和每周不同位置的.env,仅作为示例。

  • You can keep your .env files in a VCS like SVN or Git.
  • 您可以将.env文件保存在SVN或Git之类的VCS中。

  • Much easy to test your scripts (there is no need to execute it from CRON).
  • 很容易测试你的脚本(不需要从CRON执行它)。

Regards

#1


Declaring variables inside your cron job is more explicit and easier to maintain : all you have to modify is contained in your cron job, and you don't need to transfer multiple files should you move it to another system.

在cron作业中声明变量更明确,更易于维护:您需要修改的所有内容都包含在您的cron作业中,如果您将其移动到另一个系统,则无需传输多个文件。

PATH=/usr/bin:/your/fancy/dir
MYAPPROOT=/var/lib/myapp

*/2 * * * * myappinpath
*/3 * * * * $MYAPPROOT/mylocalapp

#2


If you're on linux/bsd/mac you can set some environment variables like PATH right in the crontab, and with that you're generally good to go.

如果你在linux / bsd / mac上,你可以在crontab中设置一些像PATH这样的环境变量,你可以通常使用它。

If you're on Solaris, well, I pray for you. But, I do have an answer too: I generally source .profile before running anything:

如果你在Solaris上,那么,我为你祈祷。但是,我也有一个答案:我通常在运行任何东西之前使用.profile:

0 0 * * 0 . /home/myuser/.profile && cd /path && ./script

Mind you, my .profile loads .bash_profile and .bashrc. Just be sure whatever file you source has what you need.

请注意,我的.profile加载.bash_profile和.bashrc。只要确保您提供的文件中包含您需要的内容。

#3


Since cron does not run login, .profile and /etc/profile are not sourced. Therefore PATH may not be set to a value you expect. I would either

由于cron没有运行登录,因此不会提供.profile和/ etc / profile。因此,PATH可能未设置为您期望的值。我会的

  • set and export PATH to an appropriate value
  • 设置PATH并将其导出为适当的值

  • use full paths in the script
  • 在脚本中使用完整路径

Your trick with symlinks assumes . is in the PATH and just does not seem nice

使用符号链接的技巧假定。是在PATH中,似乎并不好看

#4


My recomendation:

Set all variables in a external file. I use 'process_name.env' file located in /etc/process_name or similar. Imagine you have a backup script. Then you:

将所有变量设置在外部文件中。我使用位于/ etc / process_name中的'process_name.env'文件或类似文件。想象一下,你有一个备份脚本。那么你:

  • Create /etc/backup.env and put all environment variables needed for do the "backup" task.
  • 创建/etc/backup.env并放置执行“备份”任务所需的所有环境变量。

  • Modify your backup script and add this line after Shebang:

    修改你的备份脚本并在Shebang之后添加这一行:

    . /etc/backup.env #There is a dot and a space before full path to backup environment.

    。 /etc/backup.env#在备份环境的完整路径之前有一个点和一个空格。

IMO this approach is better than declaring variables at CRON definitions because:

IMO这种方法比在CRON定义中声明变量更好,因为:

  • Easy to maintain. Just edit a file.
  • 易于维护。只需编辑一个文件。

  • Easy to switch configuration/centralized configuration:
    • You can have multiple .env for using your script in different situations (for example, consider you have backup locations on your .env, you can pass .env location as an argument and run your cron job daily providing an .env with few locations and weekly with different locations by providing another .env, just a example).
    • 在不同的情况下,您可以使用多个.env来使用脚本(例如,考虑在.env上有备份位置,您可以将.env位置作为参数传递,并且每天运行您的cron作业,提供几个位置的.env和每周一次,提供另一个.env,只是一个例子)。

  • 易于切换配置/集中配置:您可以在不同情况下使用多个.env来使用您的脚本(例如,考虑您在.env上有备份位置,您可以将.env位置作为参数传递并每天运行您的cron作业通过提供另一个.env来提供具有少量位置和每周不同位置的.env,仅作为示例。

  • You can keep your .env files in a VCS like SVN or Git.
  • 您可以将.env文件保存在SVN或Git之类的VCS中。

  • Much easy to test your scripts (there is no need to execute it from CRON).
  • 很容易测试你的脚本(不需要从CRON执行它)。

Regards