python - 如何使用Python检查字符串是否是有效的shell命令?

标签 python cmd subprocess

我正在制作一个向 Windows 中的标准命令外壳添加附加功能的程序。例如,输入 google后跟关键字将打开一个新选项卡,其中包含 Google 搜索这些关键字等。每当输入未引用我创建的自定义函数时,它就会使用 subprocess.call(rawCommand, shell=True) 作为 shell 命令进行处理。 .
因为我想预测我的输入何时不是有效命令并返回类似 f"Invalid command: {rawCommand}" 的内容。 ,我该怎么做呢?
到目前为止,我已经尝试过 subprocess.call(rawCommand)它还返回标准输出以及退出代码。所以看起来像这样:

>>> from subprocess import call
>>> a, b = call("echo hello!", shell=1), call("xyz arg1 arg2", shell=1)
hello!
'xyz' is not recognized as an internal or external command,
operable program or batch file.
>>> a
0
>>> b
1
我只想收到那个退出代码。关于我如何做到这一点的任何想法?

最佳答案

如果有一天你想要处理编码错误,取回你正在运行的命令的结果,有一个超时或决定哪些退出代码不是 0 可能不会触发错误(我在看着你,java 运行时!),这是完成这项工作的完整功能:

import os
from logging import getLogger
import subprocess

logger = getLogger()


def command_runner(command, valid_exit_codes=None, timeout=300, shell=False, encoding='utf-8',
                   windows_no_window=False, **kwargs):
    """
    Whenever we can, we need to avoid shell=True in order to preseve better security
    Runs system command, returns exit code and stdout/stderr output, and logs output on error
    valid_exit_codes is a list of codes that don't trigger an error
    windows_no_window will hide the command window (works with Microsoft Windows only)
    
    Accepts subprocess.check_output arguments
        
    """

    # Set default values for kwargs
    errors = kwargs.pop('errors', 'backslashreplace')  # Don't let encoding issues make you mad
    universal_newlines = kwargs.pop('universal_newlines', False)
    creationflags = kwargs.pop('creationflags', 0)
    if windows_no_window:
        creationflags = creationflags | subprocess.CREATE_NO_WINDOW

    try:
        # universal_newlines=True makes netstat command fail under windows
        # timeout does not work under Python 2.7 with subprocess32 < 3.5
        # decoder may be unicode_escape for dos commands or utf-8 for powershell
        output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=shell,
                                         timeout=timeout, universal_newlines=universal_newlines, encoding=encoding,
                                         errors=errors, creationflags=creationflags, **kwargs)

    except subprocess.CalledProcessError as exc:
        exit_code = exc.returncode
        try:
            output = exc.output
        except Exception:
            output = "command_runner: Could not obtain output from command."
        if exit_code in valid_exit_codes if valid_exit_codes is not None else [0]:
            logger.debug('Command [%s] returned with exit code [%s]. Command output was:' % (command, exit_code))
            if isinstance(output, str):
                logger.debug(output)
            return exc.returncode, output
        else:
            logger.error('Command [%s] failed with exit code [%s]. Command output was:' %
                         (command, exc.returncode))
            logger.error(output)
            return exc.returncode, output
    # OSError if not a valid executable
    except (OSError, IOError) as exc:
        logger.error('Command [%s] failed because of OS [%s].' % (command, exc))
        return None, exc
    except subprocess.TimeoutExpired:
        logger.error('Timeout [%s seconds] expired for command [%s] execution.' % (timeout, command))
        return None, 'Timeout of %s seconds expired.' % timeout
    except Exception as exc:
        logger.error('Command [%s] failed for unknown reasons [%s].' % (command, exc))
        logger.debug('Error:', exc_info=True)
        return None, exc
    else:
        logger.debug('Command [%s] returned with exit code [0]. Command output was:' % command)
        if output:
            logger.debug(output)
        return 0, output
用法:
exit_code, output = command_runner('whoami', shell=True)

关于python - 如何使用Python检查字符串是否是有效的shell命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62729836/

相关文章:

python - python shell中的python命令行可以,但是不能通过Windows cmd

windows - for/f "the system cannot find the file"在 windows 命令脚本中

linux - 从网络服务器调用时,python 子进程命令未成功执行

使用 pythonw.exe 时 Python subprocess.call() 失败

python - 多个租户的帐户管理

python - 使用 python lxml 抓取airbnb

windows - Windows 批处理文件中的计时器

python如何在linux shell中使用子进程管道

python - 如何在 Linux 中显示进程状态(阻塞、非阻塞)

python - 如何在 Django 中遍历一个 GenericForeignKey?