首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FastScripts MacOSX应用程序:调用子处理MacOSX脚本时奇怪的stdin行为

FastScripts MacOSX应用程序:调用子处理MacOSX脚本时奇怪的stdin行为
EN

Stack Overflow用户
提问于 2015-05-09 06:31:35
回答 1查看 189关注 0票数 2

总结。为什么FastScripts应用要做以下工作,它是有目的的吗?我或FastScripts开发人员可以以某种方式修复/更改行为以避免这样做吗?(否则,我发现FastScripts是一个极好的应用程序。我正在运行MacOS 10.9.5。)

详细信息。

如下面的命令行会话所示,FastScripts 2.6.8似乎将其运行的当前脚本的内容复制到运行在上述脚本中的任何子进程的stdin中。这不仅很奇怪,而且在开发由FastScripts指令触发的软件时会造成严重的混乱。

我没有用非Python脚本测试过类似的行为,但我编写的多个独立Python程序的行为都是相同的。我将通过电子邮件将这个问题链接到FastScripts开发人员/技术支持部门。

下面演示了正确运行的脚本:

代码语言:javascript
复制
$ cat test_subprocess_stdin.py 
#!/usr/bin/env python
import subprocess
cmd1 = '/tmp/reprint_stdin.py            >/tmp/cmd1out.txt'
cmd2 = '/tmp/reprint_stdin.py </dev/null >/tmp/cmd2out.txt'
subprocess.Popen(cmd1, shell=True)
subprocess.Popen(cmd2, shell=True)
$ cat /tmp/reprint_stdin.py 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
# from http://stackoverflow.com/a/17735803/605356
stdin_content_present = not sys.stdin.isatty()
if stdin_content_present:
    for line in sys.stdin:
        sys.stdout.write('stdin: ' + line)
$ ./test_subprocess_stdin.py 
$ cat /tmp/cmd1out.txt
$ cat /tmp/cmd2out.txt
$

但是,在从FastScripts运行上述脚本时会发生奇怪的事情:

代码语言:javascript
复制
$ # <now running test_subprocess_stdin.py from FastScripts keyboard shortcut>
$ 
$ cat /tmp/cmd1out.txt 
stdin: #!/usr/bin/env python
stdin: import subprocess
stdin: cmd1 = '/tmp/reprint_stdin.py            >/tmp/cmd1out.txt'
stdin: cmd2 = '/tmp/reprint_stdin.py </dev/null >/tmp/cmd2out.txt'
stdin: subprocess.Popen(cmd1, shell=True)
stdin: subprocess.Popen(cmd2, shell=True)
$ cat /tmp/cmd2out.txt 
$ 
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.9.5
BuildVersion:   13F1077
$ 

请注意,调用os.system()代替subprocess.Popen()会导致相同的异常行为。

出于某种原因,FastScripts和只有FastScripts似乎将它正在运行的脚本的内容(在上面的例子中是test_subprocess_stdin.py)指向在toplevel脚本/程序中调用的任何(子)脚本的stdin。( </dev/null指示被调用的下标忽略stdin。)这很奇怪,正因为如此,我花了大量的development+debugging时间才发现为什么我的FastScript调用的程序会中断。

EN

回答 1

Stack Overflow用户

发布于 2015-05-18 15:54:48

谢谢你提出这个有趣的问题。我已经下载并确认了您所看到的相同行为,目前正在试图理解它。

FastScripts运行shell脚本的方式是从#!(shebang)脚本中要运行的工具的名称,然后简单地运行该工具,提供脚本文件的内容作为要运行的工具的标准输入。例如,在您的示例中,它将运行:

/usr/bin/env python

将文件的内容作为标准输入。

据我所知,这是一种非常传统的方法,可以调用shell工具来运行基于脚本的任意命令。那么,为什么FastScripts的行为与从命令行运行工具不同呢?我不知道。

很明显,子进程确实继承了父进程的stdin (https://unix.stackexchange.com/questions/58252/what-sets-a-childs-stderr-stdout-and-stdin),所以当env运行python,然后python运行子进程调用时,标准输入应该保持活动,这一点并不神秘。

在我看来,问题是,在直接从命令行运行脚本的情况下,发生了什么不同的事情?我不知道shell脚本执行的标准实现是否做了一些特殊的事情来防止stdin传播到脚本本身。我得调查一下这个。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30136821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档