Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 为什么登录shell环境变量与cron环境变量不同?_Bash_Shell_Cron - Fatal编程技术网

Bash 为什么登录shell环境变量与cron环境变量不同?

Bash 为什么登录shell环境变量与cron环境变量不同?,bash,shell,cron,Bash,Shell,Cron,在bash登录shell中,存在数十个环境变量,例如: HOSTNAME=myhost TERM=screen SHELL=/bin/bash HISTSIZE=1000 SSH_TTY=/dev/pts/20 LC_ALL=en_US.UTF-8 USER=user LD_LIBRARY_PATH=$:/usr:/usr/lib:/usr/local/lib:/lib:/usr/local/lib64 DRC_ROOT=/home/ds PATH=/usr/local/mysql/bin:/u

在bash登录shell中,存在数十个环境变量,例如:

HOSTNAME=myhost
TERM=screen
SHELL=/bin/bash
HISTSIZE=1000
SSH_TTY=/dev/pts/20
LC_ALL=en_US.UTF-8
USER=user
LD_LIBRARY_PATH=$:/usr:/usr/lib:/usr/local/lib:/lib:/usr/local/lib64
DRC_ROOT=/home/ds
PATH=/usr/local/mysql/bin:/usr/local/mysql/bin:/usr/local/mysql/bin:/usr/local/mysql/bin:/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
MAIL=/var/spool/mail/user
PWD=/data/user
JAVA_HOME=/usr/java/jdk1.7.0_67-cloudera
LANG=en_US.UTF-8
TMUX_PANE=%135
PS1=(dbrt_env) \[\e[37m\][\[\e[32m\]\u\[\e[32m\](\[\e[36m\]\[\e[37m\])\[\e[35m\]@\[\e[0m\]\h \[\e[33m\]\W\[\e[0m\]]\$ 
HISTCONTROL=ignoredups
SHLVL=2
HOME=/data/user
LOGNAME=user
REALUSERNAME=
CVS_RSH=ssh
HISTTIMEFORMAT=%F %T
G_BROKEN_FILENAMES=1
_=/bin/env
.....
但在crontab作业中,环境变量实际上很少:

SHELL=/bin/sh
USER=user
PATH=/usr/bin:/bin
PWD=/data/user
LANG=en_US.UTF-8
SHLVL=1
HOME=/data/user
LOGNAME=user
_=/usr/bin/env
差异的设计意图是什么


为什么不让它们相同呢?

Cron对您的登录shell(/bin/bash)使用不同的shell(/bin/sh)。bashshell有各种不同的文件用于设置内容(
manbash
将提供完整的详细信息)

最好的办法不是让它们保持一致(为什么cron需要PS1等等),而是创建一个脚本,以可控的方式包含所有需要的内容,并让cron使用这些内容

如果所需的环境位于
/home/me/setupenv.sh
中,则将以下内容添加到cron脚本中,它将运行该脚本:

/home/me/setupend.sh


不要忘记前导的
,否则它将在不同的环境中运行脚本,脚本结束时更改将丢失。

Cron将不同的shell(/bin/sh)用于登录shell(/bin/bash)。bashshell有各种不同的文件用于设置内容(
manbash
将提供完整的详细信息)

最好的办法不是让它们保持一致(为什么cron需要PS1等等),而是创建一个脚本,以可控的方式包含所有需要的内容,并让cron使用这些内容

如果所需的环境位于
/home/me/setupenv.sh
中,则将以下内容添加到cron脚本中,它将运行该脚本:

/home/me/setupend.sh


不要忘记前导的
,否则它将在不同的环境中运行脚本,并且在脚本结束时更改将丢失。

交互式环境预计将根据单个用户的偏好进行大量定制。因此,存在多个额外环境变量来源:

  • PAM模块和其他登录时间源(在上述情况下,包括SSH设置的环境变量)
  • ~/.bash_profile
    /etc/profile
    ,以及其他用于登录shell的脚本
  • ~/.bashrc
    和其他用于交互式shell初始化的脚本
相比之下,暴露于守护进程(包括
cron
)的非交互环境应该是可预测和一致的——这意味着在一台机器上编写的脚本应该在另一台机器上工作。拉入单个用户的设置与此目标相反。此外,由于运行
cron
时不涉及登录shell,因此永远不会执行仅由登录shell来源的脚本


如果仔细查看您提供的环境列表,在非交互shell中,它们中的许多都毫无意义:

  • 术语
    只有在有终端时才有意义
  • TMUX_窗格
    仅当终端是TMUX时才有意义
  • HISTSIZE
    只有在交互式shell存储历史时才有意义
  • SSH\u TTY
    只有通过SSH连接时才有意义
  • LC\u ALL
    指定用于与操作终端的用户通信的语言和区域设置
  • PS1
    指定如何设置交互式提示的格式
等等等等等等



如果需要在运行crontab时导出变量,请在crontab顶部显式指定它。这可以防止为方便交互式用户而进行的设置破坏或修改后台作业的行为。

交互式环境需要根据用户的喜好进行大量定制。因此,存在多个额外环境变量来源:

  • PAM模块和其他登录时间源(在上述情况下,包括SSH设置的环境变量)
  • ~/.bash_profile
    /etc/profile
    ,以及其他用于登录shell的脚本
  • ~/.bashrc
    和其他用于交互式shell初始化的脚本
相比之下,暴露于守护进程(包括
cron
)的非交互环境应该是可预测和一致的——这意味着在一台机器上编写的脚本应该在另一台机器上工作。拉入单个用户的设置与此目标相反。此外,由于运行
cron
时不涉及登录shell,因此永远不会执行仅由登录shell来源的脚本


如果仔细查看您提供的环境列表,在非交互shell中,它们中的许多都毫无意义:

  • 术语
    只有在有终端时才有意义
  • TMUX_窗格
    仅当终端是TMUX时才有意义
  • HISTSIZE
    只有在交互式shell存储历史时才有意义
  • SSH\u TTY
    只有通过SSH连接时才有意义
  • LC\u ALL
    指定用于与操作终端的用户通信的语言和区域设置
  • PS1
    指定如何设置交互式提示的格式
等等等等等等



如果需要在运行crontab时导出变量,请在crontab顶部显式指定它。这可以防止为方便交互式用户而进行的设置破坏或修改后台作业的行为。

您是否注意到在这两种情况下,
SHELL
的值存在差异,这就是原因
cron
提供了一个由
sh
shell运行所需的最低限度的环境,没有任何浪费,因此可以将cron shell从sh更改为bash吗?是的,您可以