Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 键入的完整命令行_Python_Command Line - Fatal编程技术网

Python 键入的完整命令行

Python 键入的完整命令行,python,command-line,Python,Command Line,我想得到完整的命令行,因为它是键入的 这: .join(sys.argv[:]) 此处不起作用(删除双引号)。此外,我不希望重新加入已解析和拆分的内容 有什么想法吗?在Unix环境中,这通常是不可能的……您最好希望的是传递给进程的命令行 因为shell(本质上是任何shell)在将键入的命令行交给操作系统执行之前,可能会以多种方式咀嚼命令行。你太迟了。当类型化命令到达Python时,您的shell已经发挥了它的魔力。例如,引号被使用(正如您所注意到的),变量被插值,等等。*nix 请看:流程只看

我想得到完整的命令行,因为它是键入的

这:

.join(sys.argv[:])

此处不起作用(删除双引号)。此外,我不希望重新加入已解析和拆分的内容


有什么想法吗?

在Unix环境中,这通常是不可能的……您最好希望的是传递给进程的命令行


因为shell(本质上是任何shell)在将键入的命令行交给操作系统执行之前,可能会以多种方式咀嚼命令行。

你太迟了。当类型化命令到达Python时,您的shell已经发挥了它的魔力。例如,引号被使用(正如您所注意到的),变量被插值,等等。

*nix 请看:流程只看到单独的参数

您无法获取在常规情况下键入的命令行。在Unix上,shell将命令行解析为单独的参数,并最终被调用
sys.argv
来自传递给
execve()函数的
argv
参数。您可以使用
”.join(map(pipes.quote,argv))
获得一些等价的东西,但您不需要这样做,例如,如果您想使用稍微不同的命令行参数重新启动脚本,那么
sys.argv
就足够了(),请参阅

有一些创造性的(不实用的)解决方案:

  • 使用gdb连接shell并对其进行查询(大多数shell能够重复相同的命令两次)-您应该能够获得与键入的命令几乎相同的命令-或者如果在进程退出之前更新了它,则直接读取其历史文件
  • 使用屏幕、脚本实用程序获取终端会话
  • 使用键盘记录器,获取键入的内容
窗户 在Windows上,本机
CreateProcess()
接口是一个字符串,但python.exe仍然以列表形式接收参数
subprocess.list2cmdline(sys.argv)
可能有助于逆转该过程
list2cmdline
是为使用-
python的应用程序而设计的。exe
就是其中之一
list2cmdline
不会返回键入的命令行,但在本例中,它会返回等效的函数


在Python2上,您可能需要从命令行获取无法在Windows ANSI代码页(如cp1252)中表示的Unicode字符。

如前所述,这可能无法完成,至少不可靠。在一些情况下,您可能能够找到shell的历史文件(例如-“bash”,但不是“tcsh”),并从中获取用户的键入。我不知道您对用户环境有多大的控制权(如果有的话)。

如果您在Linux上,我建议您使用
~/.bash_history
文件或shell
history
命令,尽管我相信该命令必须在添加到shell历史记录之前完成执行

我开始玩:

import popen2
x,y = popen2.popen4("tail ~/.bash_history")
print x.readlines()

但是我有一种奇怪的行为,shell似乎没有完全刷新到
.bash_history
文件。

在Linux上有
/proc//cmdline
的格式是
argv[]
(也就是说,所有行之间都有0x00,您无法真正知道有多少字符串,因为您没有获得argc;尽管当文件的数据用完时您会知道它;)


您可以确定命令行也已经被屏蔽了,因为所有转义/变量填充都完成了,并且参数被很好地打包(参数之间没有额外的空格,等等)

commandstring = '';

for arg in sys.argv:
    if ' ' in arg:
        commandstring += '"{}"  '.format(arg);
    else:
        commandstring+="{}  ".format(arg);

print(commandstring);
例如:

像这样从终端调用

./saferm.py sdkf lsadkf -r sdf -f sdf -fs -s "flksjfksdkfj sdfsdaflkasdf"
将在commandstring中提供相同的字符串:

./saferm.py sdkf lsadkf -r sdf -f sdf -fs -s "flksjfksdkfj sdfsdaflkasdf"

我只是晚了10.5年才参加聚会,但是……下面是我在Linux下如何处理与OP完全相同的问题(正如其他人所说,在Windows中,可以从系统中检索信息)

首先,请注意,我使用
argparse
模块来解析传递的参数。此外,参数随后被假定为作为
--parname=2
--parname=“text”
-p2
-p“text”
传递

它可能不能完全覆盖所有角落的情况,但它对我很有用(它甚至可以检测到像
1e-06
这样的数字不需要引号)


在上面,为了检查传递给参数的值是否为“数值”,我从中偷取。

您可以使用提供跨平台解决方案的
psutil

import psutil
import os
my_process = psutil.Process( os.getpid() )
print( my_process.cmdline() )
如果这不是您想要的,您可以进一步获取父程序的命令行:


变量仍将被拆分为其组件,但与
sys.argv
不同,它们不会被解释器修改。

即使在.history中,也应用了一些处理(!至少替换…).1表示聪明。想法不错。我相信默认情况下,Bash不会写入.history文件,除非在会话结束时写入,因此这也不起作用。对于实际提议来说,这是可以的。但是,如果您想要获得所有的双空格或制表符,这将不起作用(这只是对命令行的良好“重建”,而不是原始命令行).Usage带有一个参数。这意味着
subprocess.list2cmdline(sys.argv)
应该使用。@A.Sommerh:1-它适用于双空格和制表符。它是
子流程
模块在Windows上创建新流程时使用的。Windows上的每个命令都解析自己的命令行。python.exe使用与
子流程相同的规则。list2cmdline()
.2-我已经批准了您的编辑。这使我在完整的代码示例中提到了函数的名称。我并不是想暗示
subprocess.list2cmdline()
是一个实际的名称sugg
import psutil
import os
my_process = psutil.Process( os.getpid() )
print( my_process.cmdline() )
my_parent_process = psutil.Process( my_process.ppid() )
print( my_parent_process.cmdline() )