【问题标题】:Updating environment variables in bash在 bash 中更新环境变量
【发布时间】:2016-06-26 09:20:48
【问题描述】:

我有一个长时间运行的脚本,它可以与 AWS 一起工作。

我有另一个脚本,它为 AWS 身份验证放置环境变量,但仅在 15 分钟内有效。

现在我无法更改长时间运行的脚本,所以有什么方法可以让我有 cron 作业或其他任何可以更新运行长脚本的 shell 中的环境变量的方法

【问题讨论】:

  • 您可以准备一个单独的脚本,该脚本会不时更新。长脚本将在更新后立即读取这个单独的脚本并更新相关的环境变量。
  • @GMichael 我无法控制长脚本的外部模块,我无法编辑
  • 如果不重新启动或修改代码,您将无法更改正在运行的脚本中的任何内容
  • 可能有一个解决方案:您是否能够修改长时间运行的脚本正在调用的任何二进制文件/脚本?就像创建将要执行的某个文件的符号链接一样?如果是这样,您可以在那里截取长时间运行的脚本的代码。
  • @threadp 是的,我可以做到。你能详细说明我如何拦截代码

标签: linux bash environment-variables


【解决方案1】:

详细说明:

假设

  • 无法修改长时间运行的脚本。
  • 长时间运行的脚本会调用一个可以修改的可执行文件(为了举例,假设可执行文件是/usr/local/bin/callable)。
  • 您有权重命名 /usr/local/bin/callable 并在该文件路径和名称下创建一个新文件。
  • 长时间运行的脚本以 root 身份运行,或者/usr/local/bin/callable 必须能够通过设置setuid 位执行权限提升。
  • 您需要安装gdb
  • 如果长时间运行的脚本没有以 root 身份运行,您需要安装 gcc

风险

  • 如果这是一个关键系统并且安全性是中等到主要问题,请不要使用以下任何程序。
  • 虽然不太可能发生,但附加到正在运行的进程并对其注入调用可能会导致意外或未定义的行为。如果这是执行某些关键程序的关键系统,请不要使用以下任何程序。
  • 通常,所有这些程序都是坏主意,但它们代表了一种可能的解决方案。但是...
  • 使用风险自负。

过程(用于以 root 身份运行的长时间运行脚本)

bash# mv /usr/local/bin/callable /usr/local/bin/callable.orig
bash# cat > /usr/local/bin/callable << EOF
> #!/bin/bash
>
> echo -e "attach ${PPID}\ncall setenv(\"VAR_NAME\", \"some_value\", 1)\ndetach" | /usr/bin/gdb >& /dev/null
>
> /usr/local/bin/callable.orig
>
> EOF
bash# chmod 755 /usr/local/bin/callable

过程(用于长时间运行的脚本以root身份运行)

bash# mv /usr/local/bin/callable /usr/local/bin/callable.orig
bash# cat > /usr/local/bin/callable.c << EOF
> #include <stdio.h>
> #include <sys/types.h>
> #include <unistd.h>
> #include <stdlib.h>
> int main(void) {
>   char inject[128]; /* You may want to increase this size, based on your environment variables that will affect the size of the string */
>   uid_t save_uid = getuid();
>   gid_t save_gid = getgid();
>   sprintf(inject, "echo -e \"attach %u\ncall setenv(\\\"VAR_NAME\\\", \\\"some_value\\\", 1)\ndetach\" | /usr/bin/gdb >& /dev/null", getppid());
>   setreuid(0, 0);
>   setregid(0, 0);
>   system(inject);
>   setregid(save_gid, save_gid);
>   setreuid(save_uid, save_uid);
>   system("/usr/local/bin/callable.orig");
>   return 0;
> }
> EOF
bash# gcc -o /usr/local/bin/callable /usr/local/bin/callable.c
bash# rm -f /usr/local/bin/callable.c
bash# chown root:long_running_script_exclusive_group /usr/local/bin/callable
bash# chmod 4750 /usr/local/bin/callable

奖金

  • 如您所说,您可以使用 cronjob 以 gdb 附加到进程而不是拦截(这至少可以避免您使用另一个脚本拦截长时间运行的脚本,并且在最坏的情况下,需要创建一个setuid 二进制文件来做)。但是,您将需要知道或获取长时间运行的脚本 shell 进程的 PID(因为它在每次调用时都会发生变化)。由于同步问题(crontab 触发时脚本可能未运行),它也容易失败。

参考文献

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 2019-04-28
    • 1970-01-01
    • 2016-03-14
    • 2018-09-20
    相关资源
    最近更新 更多