cron 忽略“.bashrc”和“.bash_profile”中定义的变量

Mar*_*tin 77 bash cron

我在 /etc/crontab 文件中定义了“SHELL”变量:

[martin@martin ~]$ grep SHELL /etc/crontab 
SHELL=/usr/local/bin/bash
[martin@martin ~]$ file /usr/local/bin/bash
/usr/local/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.0 (800107), stripped
[martin@martin ~]$ 
Run Code Online (Sandbox Code Playgroud)

此外,我在 /etc/crontab 文件中的所有脚本都是在用户“martin”下启动的。但是/home/martin/.bash_profile(用于登录 shell)和/home/martin/.bashrc(用于非日志 shell)包含一些变量,这些变量在 cron 作业的情况下被忽略,但在我登录机器时使用SSH 或打开新的 bash 会话。为什么 cron 忽略这些变量?cron 不是简单地以用户“martin”的权限执行“/usr/local/bin/bash my-script.sh”吗?

小智 98

您可以在脚本顶部或作业开始处为执行作业的用户提供所需的文件。“source”命令是内置的。如果您对这些文件进行编辑以加载更改,您会做同样的事情。

* * * * * source /home/user/.bash_profile; <command>
Run Code Online (Sandbox Code Playgroud)

或者

#!/bin/bash
source /home/user/.bash_profile

<commands>
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果 cron 不使用 `bash` shell,“source”可能不起作用。我添加了一个可以处理 shell 为 `sh` 时的情况的答案。 (3认同)

Dav*_*e C 27

因为它不是交互式 shell。打开某些终端时也会发生同样的情况。

看看这个问题:什么是 .bashrc 文件?| 超级用户

还有这个:

.bashrc、.bash_profile 和 .environment 之间有什么区别?| 堆栈溢出

不同的脚本触发取决于连接是登录 shell(或不是)、交互式 shell(或不是),还是两者兼而有之。

如果要制作 bashrc,则需要进行以下更改:

Bash非交互启动时,为了运行一个shell脚本,例如在环境中寻找变量BASH_ENV,如果出现就将其值展开,并将展开后的值作为文件名进行读取和执行. Bash 的行为就像执行了以下命令:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi 
Run Code Online (Sandbox Code Playgroud)

但 PATH 变量的值不用于搜索文件名。

如上所述,如果使用该--login选项调用非交互式 shell ,Bash 会尝试从登录 shell 启动文件中读取和执行命令。

来源:Bash 启动文件 | Bash 参考手册 | GNU网


Jon*_*han 18

source如果sh正在使用 shell,您可能无法运行。这可以通过在您的 crontab 中添加以下行来更改:

SHELL=/bin/bash
* * * * * source "/root/.bashrc"; <command>
Run Code Online (Sandbox Code Playgroud)

您还可以指定环境:

BASH_ENV="/root/.bashrc"
* * * * * <command>
Run Code Online (Sandbox Code Playgroud)

或者,/home/user/.bashrc如果它是用户 cron 作业(例如crontab -e),则您可以使用本地。

请注意,.bash_profile可以替换.bashrc,如果存在。

信用:如何更改 cron shell(sh 到 bash)?


Rob*_*ade 10

您可以使用该-l选项调用 bash ,如下所示:

* * * * * /bin/bash -l /path/to/script arg1 arg2
Run Code Online (Sandbox Code Playgroud)

-l选项使 bash 成为登录shell。因此,它将读取用户的.bash_profile. 它不会读取用户的,.bashrc除非它明确来自.bash_profile. 这是因为非交互式 shell 不会自动读取.bashrc. 但是您不需要.bashrccron 作业,因为.bashrc它用于设置对交互式shell有用的东西。

变化:

如果 bash 在 PATH 上,则无需指定绝对路径:

* * * * * bash -l /path/to/script arg1 arg2
Run Code Online (Sandbox Code Playgroud)

一种优化是使用以下命令替换当前的 shell exec

* * * * * exec bash -l /path/to/script arg1 arg2
Run Code Online (Sandbox Code Playgroud)


小智 7

可能会干扰.bashrc从 cronjob获取您的资源的其他事情是该文件为检测交互式 shell 所做的任何检查。

例如,在 Ubuntu 18.04 上,.bashrc用户的默认设置如下:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac
Run Code Online (Sandbox Code Playgroud)

所以采购它不会做任何有用的事情,因为它会立即退出。