调用shell、cmd
python 调用系统 shell
常用来调用系统内其他命令,如 tags,nodes,php,等等等等等,
依赖
import sys
import subprocess
from subprocess import Popen, PIPE
import platform
from typing import *
class TRun_command(TypedDict):
success:bool
res:Any
err:Any
COMMANDS = {
'node':['node','-v'],
'npm':['npm','-v'],
'yarn':['yarn','-v'],
'ts-node':['ts-node','-v'],
"tsc":['tsc', '--version']
}
def check_command(target:str) -> bool:
res = False
global COMMANDS
if target in COMMANDS.keys():
res = run_command(COMMANDS[target]).strip()
print(res)
return True if res else False
简易版
import subprocess
from subprocess import DEVNULL
def shell(commands: list[str], debug: bool = False) -> bool:
# 使用列表组合指令
command_str = " ".join(commands)
try:
if debug:
res = subprocess.call(command_str)
else:
res = subprocess.call(command_str, stdout=DEVNULL)
if res == 0:
return True
return False
except Exception as err:
print("err: ", err)
return False
执行shell命令(有点问题)
- 有时候通过stderr返回的也属于执行成功
def run_command(
command:list,
strBuffer:str=None,
shell:bool=False,
decode:str='utf-8',
cwd=None,
pause:bool=False) -> TRun_command:
"""
@Description {description}
- param command :{list} 通过列表将需要输入的shell命令传入
- param strBuffer :{str} 需要传输的数据
- param shell :{bool} 是否开启一个独立的shell执行指令
- param decode :{str} 对返回的结果指定编码方式
- param pause :{bool} 是否暂停
- panam cwd :{str} 指定工作目录
@example
```python
command = ['node', '-v']
# 简单单向指令
run_command(command)
# 复杂交互指令
res = run_command(command, decode='gb2312', shell=True, pause=True)
if res['success']:
print(res['res'])
else:
print(res['err'])
```
@returns `{str}` {description}
"""
os_type = platform.system().lower()
if os_type == 'windows':
new_shell = 'cmd'
else:
new_shell = 'bash'
# 指定工作目录
if cwd: os.chdir(cwd)
try:
# run with inside
if shell:
is_pause = ' & pause' if pause else ''
_command = f'start {new_shell} /c \"{" ".join(command)}{is_pause}\"'
Popen(_command, shell=True)
# return True
return { "success":True }
# run with outside
child_process = Popen(command, stdout=PIPE, stdin=PIPE, stderr=PIPE, shell=True)
# 过来一遍 strBuffer
if strBuffer != None:
if isinstance(strBuffer, str):
strBuffer = strBuffer.encode(decode)
# 执行 command
stdout, stderr = child_process.communicate(input=strBuffer, timeout=10000)
if stdout:
if decode:
return { "res":stdout.decode(decode), "success":True }
return { "res":stdout, "success":True }
# return stdout.decode('utf-8')
if stderr:
# raise Exception('run_command() 结果出错:', stderr)
print('run_command() 结果出错:', stderr)
return { "err":stderr, "success":False }
return { "success":False, "err":"nothing change" }
except Exception as err:
print('run_command() 运行出错:', command)
# raise Exception('run_command() 运行出错:', command)
return { "err":err, "success":False }
使用
# 使用列表组合指令
command = ['npm', '-v']
# 简单单向指令
res = run_command(command, decode='gb2312')
# 复杂交互指令
run_command(command, decode='gb2312', shell=True)