crontab每分钟执行一次_不要踩到linux中crontab环境变量的坑了

问题背景

我们使用docker时,典型的用法就是在启动docker容器时,通过给docker run命令加上-e选项来给要在docker里面执行的命令传入参数. 然后在docker里面的进程中通过读取环境变量的方式得到这个输入值,如下.

docker run -d -it -e testkey=testvalue 93fd78260bd1 bashdocker exec -it 189 bashenv
0bb4095d1c495a1c9036dce71ce634e6.png

可以看到testkey=testvalue这个环境变量可以成功的看到.

但是有次我在docker里面启动了一个crontab service,然后用bash写了一个脚本. 我自己手动调用这个脚本可以正常运行,环境变量也可以正常解析. 但是crontab定时拉起来的进程里面就得不到这些环境变量,让人觉得很是诡异.

问题定位

我们知道在Linux里面,子进程是通过父进程fork+exec出来的,在exec的时候,可以通过一个额外的参数envp来指定子进程的环境变量,如果不指定,那么就是用父进程的环境变量.大部分的服务都会使用父进程环境变量.

a9347ca1321fa9eff638cfda67eb895d.png

所有我们可以想象,crond在启动子进程的时候,是显示指定了环境变量的,不然我们需要的环境变量不会没有了.

我们先写一个最简单的脚本来验证一下.脚本内容如下,其中exec &> /root/t1.log表示整个脚本的标准输出和标准错误直接写入到文件/root/t1.log中,env命令打印出当前进程的环境变量.脚本的效果就是将脚本的环境变量输出到/root/t1.log中.

890ce7321ecafedfc15c63d810c43f15.png

我们先在登录的shell中直接运行一下,

84a48f6171f8cdf41e44ac88fee45df1.png

注意到环境变量有很多,而且其中的PATH里面包含了挺多的路径的.

然后我们加上如下的crontab任务,就是每分钟都是运行一下这个脚本.

48f7eacb9d2943ae2032aba142bda91d.png

然后看了下执行输出的日志,发现里面的环境变量只有固定的几个值,而且明显的PATH环境变量只有很少的路径了.

4bf5d0093a186fe93e6da3f9ad16d878.png

为了验证其环境变量的值和crond的也不相同,我们找到crond的pid,然后通过proc得到其环境变量,可以看到PATH的值也是不同的.

ps auxf |grep crondstrings -n 1 /proc/1018/environ
8c206345081cf5a802f2d8d8a7a94042.png

原来crontab启动一个子进程的时候,其只会设置最基本的环境变量.也就是不管启动crond的进程给传入了什么样的环境变量,crond在fork出子进程,exec的时候只会给envp传入固定的值,导致拉起的脚本里面没有额外的环境变量.

在docker里面运行crontab

那么在docker里面使用crontab的时候,如果需要用到传入的环境变量,可以在entrypoint的脚本中加入下面的命令将环境变量的值写入的文件/dockerenv中

env > /dockerenv

然后再将crond打开

service cron start

在crontab拉起的脚本中一开始就加入

source /dockerenv

这样传入给docker的环境变量就可以在docker中的crond拉起的定时任务中使用了.

不知道大家有没有遇到这个坑,如果有更好的解决方法,欢迎讨论.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值