Linux crontab 路径和用户
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10129381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
crontab PATH and USER
提问by Adam S
I am new to scheduling tasks with cron and crontab. I am trying to schedule execution of a task as if I had logged on, opened a terminal, and executed it myself.
我是使用 cron 和 crontab 调度任务的新手。我正在尝试安排任务的执行,就像我已登录、打开终端并自己执行一样。
However, I scheduled a task to help me observe what $USER and $PATH a scheduled task is executing with, and this is what I found:
但是,我安排了一个任务来帮助我观察计划任务正在执行的 $USER 和 $PATH,这就是我发现的:
$ crontab -l
41 11 * * * echo "USER: $USER" > ~/Desktop/cron_env.log; echo "PATH: $PATH" >> ~/Desktop/cron_env.log
$ cat ~/Desktop/cron_env.log
USER:
PATH: /usr/bin:/bin
It appears as though $USER is not set, and $PATH is something very basic and/or default. On the contrary, this is what I see when I open a terminal (logged in) and echo this same information:
看起来好像没有设置 $USER,而 $PATH 是非常基本的和/或默认的。相反,这是我打开终端(登录)并回显相同信息时看到的:
USER: aschirma
PATH: /usr/lib/jvm/java-6-sun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/pkg/icetools/bin:/pkg/hwtools/bin:/pkg/netscape/bin:/pkg/gnu/bin
What do I need to do to make my crontab tasks run the way I want?
我需要做什么才能使我的 crontab 任务按我想要的方式运行?
回答by KurzedMetal
crontab is not a bash script, you can't use environment variables that are normally available in a shell.
crontab 不是 bash 脚本,您不能使用通常在 shell 中可用的环境变量。
Try moving all that code into a shebang'ed script file (one starting with the line "#!/bin/bash") and run that script in the crontab.
尝试将所有这些代码移动到一个 shebang 的脚本文件中(一个以“#!/bin/bash”行开头的文件)并在 crontab 中运行该脚本。
I'm not sure, but i think PATH (and maybe EMAIL if you set it) may be the only one you can access inside the crontab file .
我不确定,但我认为 PATH(如果您设置它,也可能是 EMAIL)可能是您可以在 crontab 文件中访问的唯一一个。
EDIT:Check the crontab 5 man page, there quite a few environment variables aviable, all set by the cron daemon.
编辑:检查crontab 5 手册页,有很多环境变量可用,全部由 cron 守护程序设置。
回答by Freddy
Remember crontab is a daemon or service, so is not like a user logged in or something. If you want to have your environment variables you will need to set them yourself. However, most of these variables are set by the shell from the /etc/profile path and then going into your custom variables into your $HOME directory.
记住 crontab 是一个守护进程或服务,所以不像用户登录之类的。如果你想拥有你的环境变量,你需要自己设置它们。但是,这些变量中的大多数是由 shell 从 /etc/profile 路径设置的,然后进入您的 $HOME 目录中的自定义变量。
You may be able to set some of them by "sourcing" your /etc/profile like:
您可以通过“采购”您的 /etc/profile 来设置其中的一些,例如:
41 11 * * * /home/<me>/cron_env.sh
哪里cron_env.sh
cron_env.sh
将包含以下内容:
#!/bin/sh
source /etc/profile
/usr/bin/env > /home/<me>/cron_env.log
#!/bin/sh
source /etc/profile
/usr/bin/env > /home/<me>/cron_env.log
回答by user1277476
In *ix, processes commonly inherit an environment from their parent process across fork+exec. They have the option of clearing the environment, but usually they don't. You can see the process tree with ps axf, and you can see the environment variables by using ps axfe.
在 *ix 中,进程通常通过 fork+exec 从其父进程继承环境。他们可以选择清理环境,但通常不会。用ps axf可以看到进程树,用ps axfe可以看到环境变量。
cron is commonly not a child of someone's shell, so it'll often have a different environment from your interactive shell. There's a good chance cron's going to be intentionally clearing its own environment somehow for consistency though.
cron 通常不是某人的 shell 的子级,因此它通常具有与您的交互式 shell 不同的环境。不过,cron 很有可能会以某种方式有意清除自己的环境以保持一致性。
I like to test my cron jobs ("foo" for the sake of discussion) with the following in an interactive shell: env - ./foo This will actually clear out more env vars that cron does, but it makes it easier to get things going IMO, since what you're testing is more similar. You'll need to set any variables you're depending on (like $PATH), or replace them with something else - EG $USER becomes $(whoami).
我喜欢在交互式 shell 中使用以下内容测试我的 cron 作业(为了讨论而使用“foo”): env - ./foo 这实际上会清除 cron 所做的更多 env vars,但它使获取事物变得更容易去 IMO,因为你正在测试的内容更相似。您需要设置您所依赖的任何变量(如 $PATH),或者用其他东西替换它们 - EG $USER 变为 $(whoami)。
I also like to write my bash scripts to use "set -eu" and "set -o pipefail". The -eu says "exit on a nonzero exit code, and exit on an undefined variable reference", and the pipefail says "don't return the last exit code in a pipeline, instead return the first exit code that's nonzero in a pipeline". In your case, the set -u might be particularly helpful.
我还喜欢编写我的 bash 脚本以使用“set -eu”和“set -o pipefail”。-eu 表示“在非零退出代码上退出,并在未定义的变量引用上退出”,而 pipefail 表示“不要返回管道中的最后一个退出代码,而是返回管道中第一个非零的退出代码” . 在您的情况下, set -u 可能特别有用。
回答by Julien Palard
According to "man 5 crontab" you can set environment variables in your crontab, by writing them before your cron lines.
根据“man 5 crontab”,您可以在您的 crontab 中设置环境变量,方法是在您的 cron 行之前编写它们。
There is also an example of a crontab so you just have to copy/paste it :
还有一个 crontab 的例子,所以你只需要复制/粘贴它:
$ man 5 crontab | grep -C5 PATH | tail
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow usercommand
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
So you can adjust your PATH or any environment variable to whatever you want. But this example seems enough for typical cases.
因此,您可以根据需要调整 PATH 或任何环境变量。但是这个例子对于典型案例来说似乎已经足够了。
回答by Alan Kwiatkowski
In our environment, we typically don't have this issue as root is the only cron allowed and each command is typically ran as an application specific user VIA a su -c command as:
在我们的环境中,我们通常没有这个问题,因为 root 是唯一允许的 cron 并且每个命令通常作为特定于应用程序的用户通过 su -c 命令运行:
su - myuser -c "/usr/local/scripts/app.sh" 2>&1
since the "-" option is specified we get myuser's profile and environment. We recently had an issue with a command that needed root's authority to complete successfully, so we just issued the command without the su -c. After some amount of research, it dawned on us that the easiest way to get root's environment is to use the same technique for root as we do for all other applications so we issued:
由于指定了“-”选项,我们获得了 myuser 的配置文件和环境。我们最近遇到了一个需要 root 权限才能成功完成的命令的问题,所以我们只是发出没有 su -c 的命令。经过一些研究,我们意识到获取 root 环境的最简单方法是对 root 使用与我们对所有其他应用程序相同的技术,因此我们发布了:
su - root -c "/usr/local/scripts/app.sh" 2>&1