Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.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
调用windows';来自python的icacls_Python_Windows_Cmd_Icacls - Fatal编程技术网

调用windows';来自python的icacls

调用windows';来自python的icacls,python,windows,cmd,icacls,Python,Windows,Cmd,Icacls,我成功地使用了subprocess.check_output调用了大量windows程序。 然而,我在给icacls打电话时感到不安 通过cmd,这是有效的: cmd>icacls“C:\my folder”/GRANT*S-1-1-0:F 我试过: subprocess.check_输出(['C:\\Windows\\System32\\icacls.exe','C:\\my folder','/GRANT*S-1-1-0:F'],shell=True,stderr=subprocess.ST

我成功地使用了subprocess.check_output调用了大量windows程序。 然而,我在给icacls打电话时感到不安
通过cmd,这是有效的:
cmd>icacls“C:\my folder”/GRANT*S-1-1-0:F

我试过:
subprocess.check_输出(['C:\\Windows\\System32\\icacls.exe','C:\\my folder','/GRANT*S-1-1-0:F'],shell=True,stderr=subprocess.STDOUT)

但返回代码是123(根据micrsoft,无效文件名)。
我也尝试过(这也适用于cmd)
subprocess.check_输出(['C:\\Windows\\System32\\icacls.exe','C:/my folder','/GRANT*S-1-1-0:F'],shell=True,stderr=subprocess.STDOUT)

但返回代码也是123。


有什么想法吗?

不要过度引用你的论点,否则它们会被逐字传递。需要时,让
检查输出
处理报价。使用参数列表的最佳方法:

subprocess.check_output(['icacls.exe',r'C:\my folder','/GRANT','*S-1-1-0:F'],stderr=subprocess.STDOUT)

(请注意,我删除了
shell=True
和命令路径,并使用了原始前缀以避免文件夹参数的反斜杠加倍)

在Windows上,您最好为命令行提供字符串而不是序列,特别是如果您已经确切地知道您想要的命令行是什么样子的话。传递字符串告诉Python您知道自己在做什么,它不应该尝试添加引号或修改命令:

subprocess.check_output(
    r'C:\Windows\System32\icacls.exe "C:\my folder" /GRANT *S-1-1-0:F',
    stderr=subprocess.STDOUT)

@让·弗朗索瓦·法布给了我线索:
引用我的目标参数是有意义的,因为它有空格,所以从cmd调用时需要引用。然而,python似乎会过度引用。


谢谢大家的帮助

'/grant'
需要是一个单独的项目,例如
子进程。检查输出(['icacls.exe',r'C:\my folder','/grant','*S-1-1-0:F'],stderr=subprocess.STDOUT)
。如果glezo使用
shell=True
隐藏icacls.exe从非控制台进程运行时创建的控制台,最好通过传递参数
creationflags=DETACHED\u PROCESS
,告诉icacls.exe跳过创建控制台,其中
DETACHED\u PROCESS==8
@eryksun:忽略了“grant”部分。谢谢关于分离的过程,好吧,这不是与
startupinfo设置为startupinfo\u NOWINDOW
的效果相同吗?我想你的意思是设置标志
STARTF\u USESHOWWINDOW
,并将字段
wShowWindow
设置为
SW\u HIDE
(0)。控制台应用程序确实支持此设置(一些GUI应用程序如记事本也是如此),这是隐藏控制台窗口的好方法。您还可以使用创建标志
CREATE_NO_WINDOW
,该标志生成具有有效流但不创建窗口的控制台主机进程(conhost.exe)。如果子进程创建其他子控制台进程,则这两个选项都适用,因为它们将继承具有隐藏窗口或无窗口的控制台。当运行不生成子控制台进程的简单命令行程序(如icacls.exe)时,创建标志
DETACHED_PROCESS
尤其适用。此标志使应用程序完全跳过继承或生成控制台主机进程并附加到该进程。如果您没有将标准句柄设置为管道,则最好使用此标志强制将标准句柄设置为
\.\NUL
设备(即
subprocess.DEVNULL
),因为某些控制台应用程序希望其所有标准句柄都有效。如果您知道应用程序遵循VC++命令行解析规则,我认为使用参数列表并让
subprocess.list2cmdline
为您处理报价更简单。只有当应用程序具有不同的命令行解析规则时,才需要使用字符串,这显然是在使用
shell=True
时的情况,因为CMD在它自己的范围内。这种特殊情况不需要
shell=True
,也不应该使用它。另外,它不应该硬编码到icacls.exe的路径。@eryksun,我认为原始帖子是你断言的反例;OP在文件名周围加上引号,因为这是您在Windows中所做的,并且不希望Python尝试将它们加倍。如果您更习惯于UNIX,那么使用序列可能更自然;如果您是Windows本机用户,则使用字符串更自然。@eryksun,使用完整路径很重要,因为如果不这样做,将导致二进制植入漏洞。严格地说,您应该查找系统目录,而不是硬编码,但这超出了这个特定问题的范围。(我已经删除了
shell=True
)从Vista开始,可以通过定义环境变量
nodefaultcurrentDirectoryinePath
,将
CreateProcess
和CMD(它自己搜索)配置为跳过对工作目录的隐式搜索。仍然可以通过将“.”添加到
PATH
来显式搜索工作目录。也就是说,我只是说它不应该硬编码icacls.exe路径。使用
icacls\u path=os.path.join(os.environ['SystemRoot','System32','icacls.exe')
。Windows并不总是安装在“C:\Windows”中。