阿毛
It's me !
想你所想
关于shell脚本中一次意外的command not found错误

问题发现

有大致这样一个脚本:

#!/usr/bin/env bash

hadoop fs -ls /

当我登录主机后,手动执行该脚本,可以正常执行。但当该脚本为crontab中一个任务时,就报 hadoop command not found 。

问题排查

首先,我们知道,“!/usr/bin/env bash” 这种声明解释器的方式,是可以让脚本直接从环境变量中加载到shell,包含系统shell以及自己配置到$PATH的shell。而“#!/bin/sh”和“#!/bin/bash”均只加载系统shell,所以使用两者的话,一般都会在shell脚本中使用绝对路径。两者的区别在于,前者标注的脚本执行过程为“当某行代码出错时,不继续往下解释”,而后者继续执行。类似于“/bin/bash --posix”。

明确以上前要内容后,再来进行排查过程。

1、排查登录主机,成功执行脚本的用户,是否和crontab中执行该脚本任务的用户为同一用户(crontab -u user -l)。
排查确认为同一用户。
2、排查“hadoop”命令是否有配置在环境变量中。
本人系统shell使用的“/bin/bash”(echo $SHELL)。所以排查“/etc/profile”、“~/.bash_profile”和“~/.bashrc”中是否有配置“hadoop”,经排查,“hadoop”配置在“~/.bash_profile”中。
这就是真正的问题所在,按我一开始的理解,显然环境变量中已经配置成功了,我登录系统,手动执行脚本,成功执行就能说明这个问题。那为什么crontab不行呢,用户也对着。

找了度娘后,发现原因,问题就是在于.bash_profile和.bashrc的差别。

  • /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。并从/etc/profile.d目录的设置文件中搜集shell的设置。
  • /etc/bashrc:为每一个运行bash shell的用户执行此文件。当bash shell被打开时,该文件被读取。
  • ~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件。
  • ~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时及每次打开新的shell时,该文件被读取。
  • ~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件。
  • /etc/profile是全局性的功能,其中设置的变量作用于所有用户,~/.bash_profile中设置的变量能继承/etc/profile中的变量并作用于用户。
  • ~/.bash_profile 是交互式、login 方式进入 bash 运行的。
  • ~/.bashrc 是交互式 non-login 方式进入 bash 运行的。
    (注:上面这段内容摘抄自:https://blog.csdn.net/zc02051126/article/details/20480289

可是在运行crontab的时候,是non_login方式调用程序的,此时“~/.bash_profile”并不会被提前调用。而我的“hadoop”正是配在“~/.bash_profile”中的!所以才导致一开始的问题。

问题解决

解决此类问题,有大致三种方法:

1、在non_login方式的path配置文件中配置crontab任务脚本中可能用到的shell。
如“/etc/profile”、“~/.bashrc”中,LD_LIBRARY_PATH或配置到PATH中都可以。
2、将对应crontab任务配置成 登录执行脚本方式
如“0 5 * * * /test.sh”改为“0 5 * * * su - -c /test.sh”, 切换为当前用户执行脚本,会以login方式切换用户。所以也就能加载到login变量
3、任务脚本中,使用绝对路径
这里,就是将脚本中的“hadoop”,改成hadoop命令的绝对路径。

首页      code      Linux      关于shell脚本中一次意外的command not found错误

发表评论

textsms
account_circle
email

想你所想

关于shell脚本中一次意外的command not found错误
问题发现 有大致这样一个脚本: #!/usr/bin/env bash hadoop fs -ls / 当我登录主机后,手动执行该脚本,可以正常执行。但当该脚本为crontab中一个任务时,就报 hadoop command…
扫描二维码继续阅读
2020-08-14