从包装二进制文件调用脚本时未设置 Bash 变量

Posted

技术标签:

【中文标题】从包装二进制文件调用脚本时未设置 Bash 变量【英文标题】:Bash variable not set when calling the script from wrapper binary 【发布时间】:2021-01-17 00:10:38 【问题描述】:

我有以下代码, bash 脚本“tryme.sh”:

#!/usr/bin/env bash

PATH=$(/usr/bin/getconf PATH || /bin/kill $$)

PASS="hellthatrocks"

if [ ! -v "$1" ]; then
    echo "no.."
    echo "hell..."
    exit 1
fi

if test "$1" = "$PASS" ; then
    echo "yeah it is : $PASS"
else
    echo "humm..."
fi

exit 0

以及包装二进制文件“wrapper.c”:

#include <unistd.h>

int main(int arc, char** arv) 
    char *argv[] =  "/bin/bash", "-p", "./tryme.sh", arv[1] , NULL ;
    execve(argv[0], argv, NULL);
    return 0;


compiled gcc -o wrapper wrapper.c
export hellthatrocks="hellthatrocks"

问题是当我给出一个模式作为参数时,它在命令行中寻找已定义的环境变量,例如:

./tryme.sh $!h*

它给了我,“是的,它是hellthatrocks”。

但如果我从包装器中调用脚本,它不会找到变量并给出“no... hell....”

./wrapper $!h*

出了什么问题? 谢谢,

【问题讨论】:

and gives "no... hell...." 你在什么系统上? execve 应该是错误的......你为什么要使用 $!h* ?为什么不简单的"hellthatrocks"?我希望您知道您的脚本确实读取环境变量的值 - 那么设置它的意义何在?哦,我明白为什么它没有出错,来自man execve,但引用Do not take advantage of this nonstandard and nonportable misfeature! 没有错误...它适用于 Linux 5.4.0-62-generic #70~18.04.1-Ubuntu... 包装器没有错误。但是它调用了脚本并且脚本找不到 hellthatrocks...我检查了每个变量...它识别了 hellthatrocks 但无法确定它是否设置为... @hellXY 既然你用了execve,原来的环境就换成空的了。 有没有办法从调用 tryme.sh 脚本的包装二进制文件中读取密码?因为脚本和二进制文件都具有相同的用户.... 【参考方案1】:

怎么了?

envp 在 Linux 上可能被错误地指定为 NULL,来自手册页:

在 Linux 上,可以将 argv 和 envp 指定为 NULL。在这两种情况下, 这与将参数指定为指向的指针具有相同的效果 包含单个空指针的列表。 不要利用 这种非标准且不可移植的错误功能!

您将其指定为NULL,因此在子进程中环境为空,因此导出的hellthatrocks 变量不存在-因此检查[ -v "$1" ]$1=hellthatrocks 失败。

【讨论】:

感谢您的解释。我投票给这篇文章作为答案...不幸的是,我不能投票,因为我没有 15 名声望。抱歉...我必须更频繁地在这里发帖才能进入这个行业。再次感谢...

以上是关于从包装二进制文件调用脚本时未设置 Bash 变量的主要内容,如果未能解决你的问题,请参考以下文章

拦截 bash 脚本函数/系统调用并将它们包装到自定义函数中

Shell 脚本之规范和变量

在 bash 脚本中执行时未生成 gprof 输出

Bash 安全地从文件中获取变量

CentOS 中 crontab 定时任务找不到命令问题

12bash脚本变量总结