【问题标题】:Subprocess causing error: TypeError: expected str, bytes or os.PathLike object, not tuple子进程导致错误:TypeError: expected str, bytes or os.PathLike object, not tuple
【发布时间】:2021-11-07 16:49:45
【问题描述】:

我正在为 Hack the box、Try Hack Me 等主题的服务器构建一个枚举工具。在尝试自动执行端口扫描时,我遇到了子进程和将输出写入文件的问题。

import os
import sys
import traceback
import subprocess as sub
import re

ip_addr = ''
nickName = ''
Dir = ''


def getIP():
    global ip_addr
    ip_addr = str(input('[+] Please enter the IP address you would like to enumerate: \n'))
    if not re.match("^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$", ip_addr):
        print('[-] That is not the correct format for an IP address. \n    [-] Please try again.')
        getIP()
    
def mk_nickname():
    global nickName
    nickName = str(input('[+] Please give this IP a nickname. \n    [+] This will be used to create a directory to keep you notes organized. \n    [+] This will be found in your documents folder within your home directory.\n'))
    if nickName == '':
        mk_nickname()
    return

#add if file already exsists clause (exsit_ok may have done the trick)
def mkdir():
    global Dir
    Dir = f"{os.getenv('HOME')}/Documents/" + nickName
    os.makedirs(Dir, mode=0o700, exist_ok=True)
    

def PortScan():
    YN = str(input('[+] Would you like to run a port scan? '))
    portDir = Dir +'/portscan.txt'
    print(portDir)
    if YN == 'y' or YN == 'yes':
        print('[+] Starting portscan.\n    [+] The results can be found here: ' + portDir )
        cmd = "rustscan", "-a", ip_addr, "--", "-sV", "-sC", "-A"
        print(cmd)
        sub.Popen([cmd], stdout=sub.PIPE, stderr=sub.PIPE, text=True)
        with open(portDir, w) as f:
            file.write(result.stdout)

        
    elif YN == 'n' or YN == 'no':
        return
    else:
        print('[-] Invalid input!\n[-] Please try again.')
    

        
print('[+] Lets start enumerating!!!')
getIP()
mk_nickname()
mkdir()
PortScan()

我尝试了很多不同的方法,但似乎无法正常工作。

这是收到的错误:

[+] Lets start enumerating!!!
[+] Please enter the IP address you would like to enumerate: 
10.10.10.75
[+] Please give this IP a nickname. 
    [+] This will be used to create a directory to keep you notes organized. 
    [+] This will be found in your documents folder within your home directory.
nibbles
[+] Would you like to run a port scan? yes
/home/kali/Documents/nibbles/portscan.txt
[+] Starting portscan.
    [+] The results can be found here: /home/kali/Documents/nibbles/portscan.txt
('rustscan', '-a', '10.10.10.75', '--', '-sV', '-sC', '-A')
Traceback (most recent call last):
  File "/home/kali/Desktop/OSCPENUM.py", line 57, in <module>
    PortScan()
  File "/home/kali/Desktop/OSCPENUM.py", line 41, in PortScan
    sub.Popen([cmd], stdout=sub.PIPE, stderr=sub.PIPE, text=True)
  File "/usr/lib/python3.9/subprocess.py", line 951, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.9/subprocess.py", line 1698, in _execute_child
    and os.path.dirname(executable)
  File "/usr/lib/python3.9/posixpath.py", line 152, in dirname
    p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not tuple

我可以将此归结为不完全理解子流程,但在查看了文档和许多不同的fourms/stack overflow 帖子之后,我仍然无法找到解决方案。 这就是为什么我自己求助于 Stack Overflow 的领主! :)

【问题讨论】:

  • Popen 行替换为 sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE, text=True) 。 (请注意,我删除了方括号)
  • 哦,有道理!如果您提供变量,则删除括号。如果您提供直接命令,则使用方括号。当您知道诀窍时,这很容易解决!太感谢了!现在是时候修复其余的错误了:)。谢谢!

标签: python python-3.x subprocess popen


【解决方案1】:

将 Popen 行替换为 sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE, text=True) 。 (请注意,我删除了方括号) - 电影 1

这已经解决了这个问题。现在开始调试程序的其余部分。自从解决了这个问题后,这很容易。

根据我对问题的理解: 子流程文档使用括号 [] 指定“arg”的值。当您通过 subprocess.Popen() 而不是直接命令传递变量时,这并不适用。

def PortScan():
    YN = str(input('[+] Would you like to run a port scan?\n'))
    portDir = Dir +'/portscan.txt'
    print(portDir)
    if YN == 'y' or YN == 'yes':
        print('[+] Starting portscan.\n    [+] The results can be found here: ' + portDir )
        cmd = "rustscan", "-a", ip_addr, "--", "-sV", "-sC", "-A"
        print(cmd)
        f = open(portDir, "w")
        sub.Popen(cmd, stdout=f, text=True)

非常感谢 Flimm 的快速响应!

【讨论】:

  • 变量cmd 是一个元组,在这种情况下它的工作方式类似于一个列表。 cmd = "rustscan", "-a", ip_addr 相当于cmd = ("rustscan", "-a", ip_addr),在这种情况下括号是可选的,因为您用逗号分隔了多个项目。为了清楚起见,我建议添加括号。当你运行print(cmd)时,你可以看到它打印了一个元组。
猜你喜欢
  • 2021-09-12
  • 2020-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多