- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这是我们更新 bash 后发生的事情之一(由于 Shellshock 事件)
这是我正在测试的代码:
#!/usr/bin/python2.4
import subprocess, os
p = subprocess.Popen(
cmd,
shell = True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE
)
out, err = p.communicate()
print "out:", out
print "err:", er
首先运行命令:
cmd = "cd /home/me/; pwd; p4 client -o"
out: /home/me/
err:
perforce client that is NOT mine ( some kind of a default template is trying to be used here )
第二个测试,我添加了以下 Python args:
env = os.environ.copy()
# and add "env" variable to the Popen command after "cmd, like:
env = env,
输出:
cmd = "cd /home/me/; pwd; p4 client -o"
out: /home/me/
err:
my perforce client information - as it should.
我的问题是,我似乎无法理解为什么“env = env”在这里很重要。我尝试运行几个命令,例如“export”等,以了解有/没有它之间的区别——但结果是一样的,还检查了“shell”都使用“sh”。所以我不太确定环境的哪一部分导致它无法像示例 #1 那样工作。
我确定它与 Perforce 本身并没有真正的关系,Perforce 可能只是需要一些环境变量,这些环境变量由于这个 bash Shellshock 事件而受到了某种影响。
我尝试在没有“env=env”(这是一个 os.environ.copy() )的情况下查看 ENV,
# 1
# The outouput is wrong ( generic Perforce views )
cd /home/me/; pwd; p4 client -o
# 2 - manually adding P4CONFIG
# The outouput is *correct*
cd /home/me/; pwd; P4CONFIG='.perforce'; p4 client -o
# But the environment variable looks like is there with the correct information ( can't paste it here )
subprocess.call("env") | grepping the script's output P4
> P4CONFIG=...
> P4PORT=...
> P4USER ...
请注意,P4 变量配置了两次:
/etc/profile
/home/me/.bash_profile
环境忽略 %ENV 中的 P4CONFIG 条目。
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $dir = "/home/me/";
my $cmd1 = "cd $dir; p4 client -o";
my $cmd2 = "cd $dir; P4CONFIG='.perforce'; p4 client -o";
# Scenario 1 - does NOT work ! $ENV does have P4CONFIG with a correct value.
`$cmd1`;
# ** still wrong result - generic Perforce views
# Scenario 2 - adding P4CONFIG= to the command:
`$cmd2`;
# Correct result - my .perforce client's views.
# Scenario 3 - Adding to the ENV P4CLIENT ( which does not exists in %ENV )
$ENV{'P4CLIENT'} = "my_client_name";
`$cmd1`; # The one without the P4CONFIG enforcement. - WORK.
实际上,在考虑它时,当我的一个库在上面的子进程(Python)“cmd”示例中有一个“>/dev/null”重定向导致脚本挂起并退出时,引入了整个问题超时,我用“-o file-output”替换它,问题消失了,但后来我陷入了这个问题,所以我打开了这个帖子。
# I already found that adding this row - solving the ENV thing ( not really solving ... but )
$ENV{'P4CONFIG'} = ".perforce";
# Work, I see the excepted output
my $bla = `p4 client -o`;
# Doesn't work, script hangs and Perforce exit with a timeout ( like a P4PORT missing error )
# (I was just trying to remove all the comments-junk )
my $bla = `p4 client -o | grep -v '^#'`;
# Script doesn't hang for example if I just "echo"
my $bla = `echo 'p4 client bla bla' | grep -v '^#'`;
只是想再说一遍,它在 shellshock 之前一切正常(可能是真实的,也可能是巧合),但在 exec() 调用的环境中有些不同......有什么想法吗?
最佳答案
您的代码是否正在修改环境?事情是这样的
os.putenv('VAR', 'VAL')
(可能)直接修改环境但不更新 os.environ
而
os.environ['VAR'] = 'VAL'
确实如此。来自Python documentation :
Calling
putenv()
directly does not changeos.environ
, so it's better to modifyos.environ
.If
putenv()
is not provided, a modified copy of this mapping may be passed to the appropriate process-creation functions to cause child processes to use a modified environment.
在阅读了 os
Python 模块和随附的 posixmodule
C 模块的有些晦涩的源代码之后,从该文档中变得不太清楚的是,如果 C 库底层平台没有 putenv(3)
C 函数,然后在 os.environ
中设置键只会影响 Python 字典,而 os.putenv
是空操作。来自 Lib/os.py
:
try:
_putenv = putenv
except NameError:
_putenv = lambda key, value: None
else:
if "putenv" not in __all__:
__all__.append("putenv")
来自Modules/posixmodule.c
:
static PyMethodDef posix_methods[] = {
/* Lots and lots of code skipped... */
#ifdef HAVE_PUTENV
{"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
#endif
/* Even more code skipped... */
};
因此,您可以在两种情况下观察到不同的行为,因为 - 令我惊讶的是 - 如果将 env=None
传递给 subprocess.Popen
构造函数,它不将 os.environ
替换为默认值,而是使用 C 标准库中的值。
为子进程设置环境的代码(在Lib/subprocess.py
)是
if env is not None:
env_list = [os.fsencode(k) + b'=' + os.fsencode(v)
for k, v in env.items()]
else:
env_list = None # Use execv instead of execve.
并且最近没有变化。并来自 exec(3)
的手册页(强调我的):
The
execle()
andexecvpe()
functions allow the caller to specify the environment of the executed program via the argument envp. Theenvp
argument is an array of pointers to null-terminated strings and must be terminated by a null pointer. The other functions take the environment for the new process image from the external variableenviron
in the calling process.
我进入了Modules/_posixsubprocess.c
(用于execv
/execve
)和Modules/posixmodule 的源代码。 c
(对于 putenv
)来检查它们是否真的按照描述调用了系统函数,据我所知,它们似乎是这样做的。这两个 C 模块都没有收到似乎与此功能相关的最新更改。
阅读您的问题后,我的第一个想法是,Python 开发人员最终对传递给子进程的环境引入了健全性检查,但他们似乎并没有这样做。很抱歉,如果这不是一个答案,但我认为它可能仍然对其他人有用,可以帮助他们避免深入研究 CPython 源代码。
作为进一步调试的建议,尝试运行
$ python -c "import os; import subprocess; os.putenv('VAR', 'VAL'); subprocess.call('env');" | grep VAR=
和各种变化来追踪正在发生的事情。
脚注:我认为 subprocess.Popen
的行为与其说是一个功能,不如说是一个错误,因为它使 Python 代码在提供或不提供putenv
无缘无故的 C 函数。
关于python - bash shellshock 更新导致脚本行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26203311/
我正在尝试使用 Spark 从 Cassandra 读取数据。 DataFrame rdf = sqlContext.read().option("keyspace", "readypulse
这是代码: void i_log_ (int error, const char * file, int line, const char * fmt, ...) { /* Get erro
我必须调试一个严重依赖 Gtk 的程序。问题是由于某些原因,在使用 GtkWindow 对象时开始出现许多运行时警告。问题是,即使 Gtk 提示严重错误,它也不会因这些错误而中止。我没有代码库的更改历
我正在尝试从已有效编译和链接的程序中检索二进制文件。我已经通过 GL_PROGRAM_BINARY_LENGTH 收到了它的长度。该文档说有两个实例可能会发生 GL_INVALID_OPERATION
我有一个托管在 Azure 环境中的服务。我正在使用控制台应用程序使用该服务。这样做时,我得到了异常: "The requested service, 'http://xxxx-d.yyyy.be/S
我有以下代码,它被 SEGV 信号杀死。使用调试器表明它被 main() 中的第一个 sem_init() 杀死。如果我注释掉第一个 sem_init() ,第二个会导致同样的问题。我试图弄清楚是什么
目前我正在编写一个应用程序(目标 iOS 6,启用 ARC),它使用 JSON 进行数据传输,使用核心数据进行持久存储。 JSON 数据由 PHP 脚本通过 json_encode 从 MySQL 数
我对 Xamarin.Forms 还是很陌生。我在出现的主页上有一个非常简单的功能 async public Task BaseAppearing() { if (UserID
这是我的代码的简化版本。 public class MainActivity extends ActionBarActivity { private ArrayList entry = new Arr
我想弄明白为什么我的两个 Java 库很难很好地协同工作。这是场景: 库 1 有一个类 A,其构造函数如下: public A(Object obj) { /* boilerplate */ } 在以
如果网站不需要身份验证,我的代码可以正常工作,如果需要,则在打印“已创建凭据”后会立即出现 EXC_BAD_ACCESS 错误。我不会发布任何内容,并且此代码是直接从文档中复制的 - 知道出了什么问题
我在使用 NSArray 填充 UITableView 时遇到问题。我确信我正在做一些愚蠢的事情,但我无法弄清楚。当我尝试进行简单的计数时,我得到了 EXC_BAD_ACCESS,我知道这是因为我试图
我在 UITableViewCell 上有一个 UITextField,在另一个单元格上有一个按钮。 我单击 UITextField(出现键盘)。 UITextField 调用了以下方法: - (BO
我有一个应用程序出现间歇性崩溃。崩溃日志显示了一个堆栈跟踪,这对我来说很难破译,因此希望其他人看到了这一点并能为我指出正确的方向。 基本上,应用程序在启动时执行反向地理编码请求,以在标签中显示用户的位
我开发了一个 CGImage,当程序使用以下命令将其显示在屏幕上时它工作正常: [output_view.layer performSelectorOnMainThread:@selector(set
我正在使用新的 EncryptedSharedPreferences以谷歌推荐的方式上课: private fun securePrefs(context: Context): SharedPrefe
我有一个中继器,里面有一些控件,其中一个是文本框。我正在尝试使用 jquery 获取文本框,我的代码如下所示: $("#").click(function (event) {}); 但我总是得到 nu
在以下场景中观察到 TTS 初始化错误,太随机了。 已安装 TTS 引擎,存在语音集,并且可以从辅助功能选项中播放示例 tts。 TTS 初始化在之前初始化和播放的同一设备上随机失败。 在不同的设备(
maven pom.xml org.openjdk.jol jol-core 0.10 Java 类: public class MyObjectData { pr
在不担心冲突的情况下,可以使用 MD5 作为哈希值,字符串长度最多为多少? 这可能是通过为特定字符集中的每个可能的字符串生成 MD5 哈希来计算的,长度不断增加,直到哈希第二次出现(冲突)。没有冲突的
我是一名优秀的程序员,十分优秀!