【发布时间】:2015-09-09 14:09:03
【问题描述】:
当我编写 cronjob、服务脚本或守护命令时,我经常让他们调用 bash 脚本或运行 bash 命令。问题是这些命令的执行与我在登录 shell 中运行它们时的行为不同。差异归结为环境变量以及登录和 shell 工作方式的许多其他细微之处,我不明白。
有没有办法运行 bash 命令并让它们的行为与我登录并运行它们时完全一样。我需要一个万无一失的流程,我可以在其中设置一个脚本来运行一个 bash 命令,该命令可以在这些情况下理想地工作:
- 在 cronjob 中调用
- 在服务 (init.d/systemd) 脚本中调用
- 作为后台进程运行(如使用 & 和 nohup) -stderr和stdout的可配置重定向
- 可配置用户
例如,经常运行:su -c 'nohup $MY_CMD > /var/log/out.txt 2>&1 &' $MY_USER 会导致应用程序出错,而不是 shell 命令本身,因为应用程序对在 shell 和非 shell 中执行的命令的处理方式不同。如何欺骗应用程序使其认为它是通过登录 shell 调用的?
虽然这种方法当然不是面向生产或安全的,但我通常会发现自己处于最后一刻的情况下,我必须让命令在后台自动运行(并且只需一个小时才能弄清楚)作为某个用户只有当我在 shell 中手动运行它时,命令本身才有效。
我还想避免使用通过 ssh 连接传递命令或调用 ssh 连接。 ssh $USER@127.0.0.1 '$CMD' 之类的东西会要求我将 ssh 密钥加载到我宁愿避免这样做的机器上。不确定这是否重要,但我的主要目标平台是 Centos 6(希望为所有 *nix 提供通用解决方案)。
如果我还可以捕获脚本生成的所有进程的 PID,那么我可以在以后以自动方式杀死它们。
【问题讨论】:
-
bash -l?但是,您希望登录 shell 的行为与其他 shell 不同,这有很多很好的理由。 -
完全理解“这是一种糟糕的做法”。当我必须让事情快速工作时,我只是想要一个快速的解决方案。作为参考,我正在尝试使用 runserver 选项运行 Django 应用程序。 Django 搜索某些 shell 设置(远远超出我的专业知识),当返回 None 时,应用程序就会死掉。在这个用例中使用
bash -l对我不起作用。 -
花了两年时间,但我遇到了一个案例,即 runuser -l 无法完全模拟从 shell 手动运行的命令。当让 Apache Nifi 运行运行可执行文件的 python 脚本时,可执行文件会引发错误,而在以登录用户身份手动运行 python 脚本时不会发生这种错误。我想它又回到了绘图板上,又浪费了几天时间。