python - 程序可以检测它是否是通过 shell 启动的吗?
问题描述
如果设置为,该ls
命令会给我一个不同的标准输出。这是为什么 ?shell
true
是否有一个基本概念允许程序(ls
在这种情况下)检测它是否通过 shell 启动?
我注意到两者在 Windowsp1
上p2
共享相同的标准输出,但在 Linux 上却没有。
import subprocess
cmd = ['ls', '-la']
# Using shell
p1 = subprocess.run(executable=cmd[0], args=cmd[1:], shell=True, text=True, capture_output=True)
# Without using shell
p2 = subprocess.run(executable=cmd[0], args=cmd[1:], shell=False, text=True, capture_output=True)
print(p1.stdout)
print(p2.stdout)
Linux 上的输出
total 12
drwxr-xr-x 2 root root 4096 Feb 20 18:25 .
drwx------ 10 root root 4096 Feb 20 18:51 ..
-rw-r--r-- 1 root root 269 Feb 20 18:57 test.py
test.py
解决方案
Python 文档很模糊,但行为无法从strace
.
你的 Python 代码:
cmd = ['ls', '-la']
p1 = subprocess.run(executable=cmd[0], args=cmd[1:], shell=True, text=True, capture_output=True)
p2 = subprocess.run(executable=cmd[0], args=cmd[1:], shell=False, text=True, capture_output=True)
变成(strace -f -e execve python3 foo.py
):
[pid 143557] execve("/bin/ls", ["ls", "-c", "-la"], 0x7fffc1235340 /* 34 vars */) = 0
[pid 143558] execve("/bin/ls", ["-la"], 0x7fffc1235340 /* 34 vars */) = 0
这相当于运行这些 shell 命令,即使两者都是从 shell 执行的,您也可以确认它们会给出相同的结果。
ls -c -la # Generally equivalent to: ls -lca
( exec -a -la ls ) # Generally equivalent to: ls
由此我们可以推断出行为。
如果shell=True
,executable
则调用 。参数列表是executable
,后跟 shell 标准-c
标志,然后是args
. 这在 的情况下更有意义executable='bash', args=['ls -la']
。
如果shell=False
,则调用可执行文件。参数列表是args
。这模仿execve
.
所以基本上没有,这里没有检测。这只是对 的两种不同调用ls
,也不是您想要的。
推荐阅读
- docker - 如何获取在容器中运行的进程的主机 pid?
- kotlin - 可以从 Kotlin 的列表中弹出一个元素吗?
- java - 当它们在库中时,如何使带有 Springboot 注释的类正确加载?
- eigen - 在 Eigen 中,是否可以从其 Column 主要表示构造一个 Eigen::sparseMatrix ?
- android - 浮动操作按钮未执行 OnClick
- mysql - 在 MySQL 查询中使用 UTF8 编码的字符串
- c# - 传递两个动作
参数并根据异步 API 调用的 JSON 结果执行其中一个 - excel - 过滤并删除我从不同列中过滤的条件
- python - 在opencv中绘制轮廓
- augmented-reality - AR.js - Barcode Marker 仅检测 id=0 的标记