gpt4 book ai didi

python:获取操作系统的argv[0],而不是sys.argv[0]

转载 作者:行者123 更新时间:2023-12-02 09:01:00 24 4
gpt4 key购买 nike

(这个问题被问到 here ,但答案是特定于 Linux 的;我在 FreeBSD 和 NetBSD 系统上运行,这些系统(编辑:通常)没有 /proc .)

Python 似乎简化了 argv[0],因此您无法像 C 程序那样获得传递给进程的内容。公平地说,sh、bash 和 Perl 也好不了多少。有什么方法可以解决这个问题,以便我的 Python 程序可以获得原始值?我对此 FreeBSD 系统具有管理权限,并且可以执行诸如更改每个人的默认 PATH 环境变量以指向包含 python2 和 python3 的目录之前的其他目录之类的操作,但我无法控制创建 /proc。我有一个脚本可以说明问题。首先,脚本的输出:

the C child program gets it right: arbitrary-arg0 arbitrary-arg1
the python2 program dumbs it down: ['./something2.py', 'arbitrary-arg1']
the python3 program dumbs it down: ['./something3.py', 'arbitrary-arg1']
the sh script dumbs it down: ./shscript.sh arbitrary-arg1
the bash script dumbs it down: ./bashscript.sh arbitrary-arg1
the perl script drops arg0: ./something.pl arbitrary-arg1

...现在是脚本:

#!/bin/sh

set -e
rm -rf work
mkdir work
cd work
cat > childc.c << EOD; cc childc.c -o childc
#include <stdio.h>
int main(int argc,
char **argv
)
{
printf("the C child program gets it right: ");
printf("%s %s\n",argv[0],argv[1]);
}
EOD
cat > something2.py <<EOD; chmod 700 something2.py
#!/usr/bin/env python2
import sys
print "the python2 program dumbs it down:", sys.argv
EOD
cat > something3.py <<EOD; chmod 700 something3.py
#!/usr/bin/env python3
import sys
print("the python3 program dumbs it down:", sys.argv)
EOD
cat > shscript.sh <<EOD; chmod 700 shscript.sh
#!/bin/sh
echo "the sh script dumbs it down:" \$0 \$1
EOD
cat > bashscript.sh <<EOD; chmod 700 bashscript.sh
#!/bin/sh
echo "the bash script dumbs it down:" \$0 \$1
EOD
cat > something.pl <<EOD; chmod 700 something.pl
#!/usr/bin/env perl
print("the perl script drops arg0: \$0 \$ARGV[0]\n")
EOD
cat > launch.c << EOD; cc launch.c -o launch; launch
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc,
char **argv,
char **arge)
{
int child_status;
size_t program_index;
pid_t child_pid;

char *program_list[]={"./childc",
"./something2.py",
"./something3.py",
"./shscript.sh",
"./bashscript.sh",
"./something.pl",
NULL
};

char *some_args[]={"arbitrary-arg0","arbitrary-arg1",NULL};

for(program_index=0;
program_list[program_index];
program_index++
)
{
child_pid=fork();

if(child_pid<0)
{
perror("fork()");
exit(1);
}
if(child_pid==0)
{
execve(program_list[program_index],some_args,arge);
perror("execve");
exit(1);
}
wait(&child_status);
}

return 0;
}
EOD

最佳答案

下面是对我想要问的问题的普遍有用的答案。

考虑到我表达问题的方式,kabanus 给出的答案非常好,所以他当然得到了向上箭头和复选标记。在我看来,透明度是一个很好的优点。

但事实证明我没有完全说明情况。每个 python 脚本都以 shebang 开头,shebang 功能使得使用人工 argv[0] 启动 python 脚本变得更加复杂。

此外,透明度不是我的目标;我的目标是透明。向后兼容性是。我希望正常情况是 sys.argv 可以像交付时一样工作,开箱即用,无需我进行修改。另外,我希望任何使用人工 argv[0] 启动 python 脚本的程序都不必担心任何额外的参数操作。

部分问题是要克服“shebang 改变 argv”问题。

答案是用 C 语言为每个脚本编写一个包装器,然后启动程序启动该程序而不是实际的脚本。实际的脚本查看父进程(包装器)的参数。

最酷的事情是,这可以适用于 python 以外的脚本类型。您可以下载概念证明here它演示了 python2、python3、sh、bash 和 perl 的解决方案。您必须使用 dos2unix 或 fromdos 将每个 CRLF 更改为 LF。这就是 python3 脚本处理它的方式:

def get_arg0():
return subprocess.run("ps -p %s -o 'args='" % os.getppid(),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
).stdout.decode(encoding='latin1').split(sep=" ")[0]

该解决方案不依赖于/proc,因此它可以在 FreeBSD 和 Linux 上运行。

关于python:获取操作系统的argv[0],而不是sys.argv[0],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59297692/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com