1 Star 0 Fork 7

wency/src-aops-ceres

forked from src-openEuler/aops-ceres 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0004-fix-cve-2021-33633.patch 23.16 KB
一键复制 编辑 原始数据 按行查看 历史
wency 提交于 2024-02-04 00:58 . fix cve-2021-33633
From d5c2db0af6d62a85c35c6cfe3e7af55edddf3b91 Mon Sep 17 00:00:00 2001
From: rabbitali <wenxin32@foxmail.com>
Date: Sun, 4 Feb 2024 00:39:26 +0800
Subject: [PATCH 1/1] fix cve-2021-33633
---
ceres/function/check.py | 4 +--
ceres/function/util.py | 11 ++++----
ceres/manages/collect_manage.py | 18 ++++++-------
ceres/manages/list_file_manage.py | 2 +-
ceres/manages/plugin_manage.py | 8 +++---
ceres/manages/resource_manage.py | 4 +--
ceres/manages/rollback_manage.py | 16 +++++------
ceres/manages/vulnerability_manage.py | 38 +++++++++++++--------------
8 files changed, 50 insertions(+), 51 deletions(-)
diff --git a/ceres/function/check.py b/ceres/function/check.py
index 20978f5..18b9561 100644
--- a/ceres/function/check.py
+++ b/ceres/function/check.py
@@ -61,14 +61,14 @@ class PreCheck(object):
"""
# Example of command execution result::
# /boot/vmlinuz-5.10.0-60.18.0.50.oe2203.x86_64
- code, boot_kernel_version, stderr = execute_shell_command("grubby --default-kernel")
+ code, boot_kernel_version, stderr = execute_shell_command(["grubby --default-kernel"])
if code != CommandExitCode.SUCCEED:
LOGGER.error(stderr)
return False, "Query boot kernel info failed!"
# Example of command execution result::
# 5.10.0-60.18.0.50.oe2203.x86_64
- code, current_kernel_version, stderr = execute_shell_command("uname -r")
+ code, current_kernel_version, stderr = execute_shell_command(["uname -r"])
if code != CommandExitCode.SUCCEED:
LOGGER.error(stderr)
return False, "Query current kernel info failed!"
diff --git a/ceres/function/util.py b/ceres/function/util.py
index 433db09..1d3d9e3 100644
--- a/ceres/function/util.py
+++ b/ceres/function/util.py
@@ -15,7 +15,7 @@ import json
import os
import shlex
import subprocess
-from typing import Any, Tuple, NoReturn
+from typing import Any, Tuple, NoReturn, Sequence
from libconf import load, ConfigParseError, AttrDict
from jsonschema import validate, ValidationError
@@ -63,12 +63,12 @@ def validate_data(data: Any, schema: dict) -> bool:
return False
-def execute_shell_command(command: str, **kwargs) -> Tuple[int, str, str]:
+def execute_shell_command(commands: Sequence[str], **kwargs) -> Tuple[int, str, str]:
"""
execute shell commands
Args:
- command(str): shell command which needs to execute
+ command(Sequence[str]): Multiple shell commands that need to be executed continuously
**kwargs: keyword arguments, it is used to create Popen object.supported options: env, cwd, bufsize, group and
so on. you can see more options information in annotation of Popen obejct.
@@ -77,11 +77,10 @@ def execute_shell_command(command: str, **kwargs) -> Tuple[int, str, str]:
a tuple containing three elements (return code, standard output, standard error).
Example usage:
- >>> return_code, stdout, stderr = execute_shell_command("ls -al|wc -l", **{"env": {"LANG": "en_US.utf-8"}})
+ >>> return_code, stdout, stderr = execute_shell_command(["ls -al", "wc -l"], **{"env": {"LANG": "en_US.utf-8"}})
>>> print(return_code, stdout, stderr)
0, 42, ""
"""
- commands = command.split('|')
process = None
stdout_data = ""
stderr_data = ""
@@ -153,7 +152,7 @@ def plugin_status_judge(plugin_name: str) -> str:
if service_name is None:
LOGGER.warning(f"Fail to get service name about {plugin_name}")
return ""
- return_code, stdout, _ = execute_shell_command(f"systemctl status {service_name}|grep Active")
+ return_code, stdout, _ = execute_shell_command([f"systemctl status {service_name}", "grep Active"])
if return_code == CommandExitCode.SUCCEED:
return stdout
diff --git a/ceres/manages/collect_manage.py b/ceres/manages/collect_manage.py
index e702120..b2ba350 100644
--- a/ceres/manages/collect_manage.py
+++ b/ceres/manages/collect_manage.py
@@ -104,7 +104,7 @@ class Collect:
Returns:
str: e.g openEuler 21.09
"""
- _, stdout, _ = execute_shell_command("cat /etc/os-release")
+ _, stdout, _ = execute_shell_command(["cat /etc/os-release"])
res = re.search('(?=PRETTY_NAME=).+', stdout)
if res:
@@ -140,7 +140,7 @@ class Collect:
Returns:
str
"""
- _, stdout, _ = execute_shell_command("dmidecode -t bios")
+ _, stdout, _ = execute_shell_command(["dmidecode -t bios"])
res = re.search('(?=Version:).+', stdout)
if res:
@@ -156,7 +156,7 @@ class Collect:
Returns:
str
"""
- code, stdout, stderr = execute_shell_command("uname -r")
+ code, stdout, stderr = execute_shell_command(["uname -r"])
if code != CommandExitCode.SUCCEED:
LOGGER.warning('Failed to get current kernel version, please check uname command and try again')
@@ -181,7 +181,7 @@ class Collect:
"l3_cache": string
}
"""
- _, stdout, _ = execute_shell_command("lscpu", **{"env": {"LANG": "en_US.utf-8"}})
+ _, stdout, _ = execute_shell_command(["lscpu"], **{"env": {"LANG": "en_US.utf-8"}})
info_list = re.findall('.+:.+', stdout)
@@ -214,7 +214,7 @@ class Collect:
Returns:
str: memory size
"""
- _, stdout, _ = execute_shell_command("lsmem")
+ _, stdout, _ = execute_shell_command(["lsmem"])
res = re.search("(?=Total online memory:).+", stdout)
if res:
@@ -245,7 +245,7 @@ class Collect:
"""
res = {'size': self.__get_total_online_memory() or None, "total": None, "info": []}
- code, memory_data, _ = execute_shell_command("dmidecode -t memory")
+ code, memory_data, _ = execute_shell_command(["dmidecode -t memory"])
# dmidecode -t memory
# e.g
@@ -306,7 +306,7 @@ class Collect:
}
]
"""
- code, stdout, _ = execute_shell_command("lshw -xml -c disk")
+ code, stdout, _ = execute_shell_command(["lshw -xml -c disk"])
if code != CommandExitCode.SUCCEED:
LOGGER.error(stdout)
return []
@@ -384,7 +384,7 @@ class Collect:
Returns:
uuid(str)
"""
- code, stdout, _ = execute_shell_command("dmidecode|grep UUID")
+ code, stdout, _ = execute_shell_command(["dmidecode", "grep UUID"])
if code == CommandExitCode.SUCCEED:
return stdout.replace("-", "").split(':')[1].strip()
return ""
@@ -420,7 +420,7 @@ class Collect:
}]
"""
- code, source_name_info, _ = execute_shell_command("rpm -qi kernel|grep .src.rpm")
+ code, source_name_info, _ = execute_shell_command(["rpm -qi kernel", "grep .src.rpm"])
if code != CommandExitCode.SUCCEED:
LOGGER.error("Failed to query installed packages.")
return []
diff --git a/ceres/manages/list_file_manage.py b/ceres/manages/list_file_manage.py
index 3d7fd21..dab55e6 100644
--- a/ceres/manages/list_file_manage.py
+++ b/ceres/manages/list_file_manage.py
@@ -40,7 +40,7 @@ class ListFileManage:
"""
file_list_res = []
try:
- command = "ls -l " + directory_path + " | awk '{print $9}'"
+ command = [f"ls -l {directory_path}", "awk '{print $9}'"]
_, stdout, _ = execute_shell_command(command)
file_list = stdout.split("\n")
for file in file_list:
diff --git a/ceres/manages/plugin_manage.py b/ceres/manages/plugin_manage.py
index ed7b2ab..fb06220 100644
--- a/ceres/manages/plugin_manage.py
+++ b/ceres/manages/plugin_manage.py
@@ -52,7 +52,7 @@ class Plugin:
if "running" in plugin_status:
return SUCCESS
- code, _, _ = execute_shell_command(f"systemctl start {self.rpm_name}")
+ code, _, _ = execute_shell_command([f"systemctl start {self.rpm_name}"])
if code != CommandExitCode.SUCCEED:
return FAIL
return SUCCESS
@@ -68,7 +68,7 @@ class Plugin:
if "inactive" in plugin_status:
return SUCCESS
- code, _, _ = execute_shell_command(f"systemctl stop {self.rpm_name}")
+ code, _, _ = execute_shell_command([f"systemctl stop {self.rpm_name}"])
if code != CommandExitCode.SUCCEED:
return FAIL
return SUCCESS
@@ -100,7 +100,7 @@ class Plugin:
str: dead or running
"""
- code, stdout, _ = execute_shell_command(f"systemctl status {self.rpm_name}|grep Active")
+ code, stdout, _ = execute_shell_command([f"systemctl status {self.rpm_name}", "grep Active"])
if code == CommandExitCode.SUCCEED:
return re.search(r':.+\(', stdout).group()[1:-1].strip()
LOGGER.error(f'Failed to get service {self.rpm_name} status!')
@@ -114,7 +114,7 @@ class Plugin:
Returns:
The str type of main process id
"""
- code, main_pid_info, _ = execute_shell_command(f"systemctl status {rpm_name}|grep Main")
+ code, main_pid_info, _ = execute_shell_command([f"systemctl status {rpm_name}", "grep Main"])
if code == CommandExitCode.SUCCEED:
return re.search("[0-9]+[0-9]", main_pid_info).group()
LOGGER.error(f"Failed to get {rpm_name} pid")
diff --git a/ceres/manages/resource_manage.py b/ceres/manages/resource_manage.py
index 5766744..e9c6256 100644
--- a/ceres/manages/resource_manage.py
+++ b/ceres/manages/resource_manage.py
@@ -32,7 +32,7 @@ class Resource:
Returns:
str:The memory value which has used
"""
- code, stdout, _ = execute_shell_command(f"cat /proc/{pid}/status|grep VmRSS")
+ code, stdout, _ = execute_shell_command([f"cat /proc/{pid}/status", "grep VmRSS"])
if code == CommandExitCode.SUCCEED:
return stdout.split(":")[1].strip()
LOGGER.error(f'Failed to get memory info of process {pid}!')
@@ -80,7 +80,7 @@ class Resource:
Returns:
str: cpu usage
"""
- code, stdout, _ = execute_shell_command(f"ps -aux|grep -w {rpm_name}|grep {pid}|awk {{print$3}}")
+ code, stdout, _ = execute_shell_command(["ps -aux", f"grep -w {rpm_name}", f"grep {pid}", f"awk {{print$3}}"])
if code == CommandExitCode.SUCCEED:
return f'{stdout.strip()}%'
LOGGER.error(f'Failed to get plugin cpu info about {rpm_name}.')
diff --git a/ceres/manages/rollback_manage.py b/ceres/manages/rollback_manage.py
index 160a74c..51ef6d6 100644
--- a/ceres/manages/rollback_manage.py
+++ b/ceres/manages/rollback_manage.py
@@ -162,7 +162,7 @@ class RollbackManage:
Returns:
Tuple[str, str]: a tuple containing two elements (rollback result, log)
"""
- cmd = f"dnf history rollback {dnf_event_start} -y"
+ cmd = [f"dnf history rollback {dnf_event_start} -y"]
# 'dnf history rollback transaction-id' command can revert all dnf transactions performed after transaction-id
code, stdout, stderr = execute_shell_command(cmd)
if code != CommandExitCode.SUCCEED:
@@ -262,7 +262,7 @@ class RollbackManage:
Returns:
Tuple[str, str]: a tuple containing two elements (remove result, log)
"""
- code, stdout, stderr = execute_shell_command(f"rpm -qa | grep {installed_rpm}")
+ code, stdout, stderr = execute_shell_command(["rpm -qa", f"grep {installed_rpm}"])
# 'rpm -qa' shows installed rpm
# e.g.
# [root@openEuler ~]# rpm -qa | grep kernel-4.19.90-2112.8.0.0131.oe1.x86_64
@@ -272,7 +272,7 @@ class RollbackManage:
LOGGER.error(tmp_log)
return TaskExecuteRes.FAIL, tmp_log
- code, current_evra, stderr = execute_shell_command(f"uname -r")
+ code, current_evra, stderr = execute_shell_command([f"uname -r"])
# 'uname -r' show the kernel version-release.arch of the current system
# e.g.
# [root@openEuler ~]# uname -r
@@ -287,7 +287,7 @@ class RollbackManage:
if installed_evra == current_evra:
return TaskExecuteRes.SUCCEED, f"Preserve the {installed_rpm} due to it is in use."
- code, stdout, stderr = execute_shell_command(f"dnf remove {installed_rpm} -y")
+ code, stdout, stderr = execute_shell_command([f"dnf remove {installed_rpm} -y"])
if code != CommandExitCode.SUCCEED:
LOGGER.error(stderr)
return TaskExecuteRes.FAIL, stdout + stderr
@@ -305,7 +305,7 @@ class RollbackManage:
Returns:
Tuple[str, str]: a tuple containing two elements (check result, log)
"""
- code, stdout, stderr = execute_shell_command(f"grubby --default-kernel")
+ code, stdout, stderr = execute_shell_command([f"grubby --default-kernel"])
# 'grubby --default-kernel' shows boot default kernel version in the system
# e.g.
# [root@openEuler ~]# grubby --default-kernel
@@ -338,7 +338,7 @@ class RollbackManage:
Returns:
Tuple[str, str]: a tuple containing two elements (check result, log)
"""
- code, current_evra, stderr = execute_shell_command(f"uname -r")
+ code, current_evra, stderr = execute_shell_command(["uname -r"])
# 'uname -r' show the kernel version-release.arch of the current system
# e.g.
# [root@openEuler ~]# uname -r
@@ -371,7 +371,7 @@ class RollbackManage:
Returns:
Tuple[str, str]: a tuple containing two elements (check result, log)
"""
- code, stdout, stderr = execute_shell_command(f"rpm -qa | grep {target_rpm}")
+ code, stdout, stderr = execute_shell_command(["rpm -qa", f"grep {target_rpm}"])
# 'rpm -qa' shows installed rpm
# e.g.
# [root@openEuler ~]# rpm -qa | grep kernel-4.19.90-2112.8.0.0131.oe1.x86_64
@@ -402,7 +402,7 @@ class RollbackManage:
return TaskExecuteRes.FAIL, tmp_log
# 'grubby --set-default=/boot/vmlinuz-xxx' changes the default boot entry
- code, stdout, stderr = execute_shell_command(f"grubby --set-default={boot_file}")
+ code, stdout, stderr = execute_shell_command([f"grubby --set-default={boot_file}"])
if code != CommandExitCode.SUCCEED:
LOGGER.error(stderr)
return TaskExecuteRes.FAIL, stdout + stderr
diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py
index 314e054..9017b17 100644
--- a/ceres/manages/vulnerability_manage.py
+++ b/ceres/manages/vulnerability_manage.py
@@ -87,7 +87,7 @@ class VulnerabilityManage:
Returns:
bool
"""
- code, _, stderr = execute_shell_command(f"dnf repoinfo --repo {repo_id}")
+ code, _, stderr = execute_shell_command([f"dnf repoinfo --repo {repo_id}"])
if code == CommandExitCode.SUCCEED:
return True
LOGGER.warning(f"Failed to query repo information with repo id {repo_id}.")
@@ -181,9 +181,7 @@ class VulnerabilityManage:
# powertop:powertop-2.9-12.oe1.x86_64
# libusbx:libusbx-1.0.23-1.oe1.x86_64
code, stdout, _ = execute_shell_command(
- """
- rpm -qa --queryformat '%{NAME}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | grep kernel
- """
+ ["rpm -qa --queryformat '%{NAME}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n'", "grep kernel"]
)
if code != CommandExitCode.SUCCEED or not stdout:
LOGGER.error("query installed packages info failed!")
@@ -222,7 +220,7 @@ class VulnerabilityManage:
# CVE-2021-45469 Important/Sec. kernel-4.19.90-2201.1.0.0132.oe1.x86_64
# CVE-2021-44733 Important/Sec. kernel-4.19.90-2201.1.0.0132.oe1.x86_64
unfixed_cves = []
- code, stdout, stderr = execute_shell_command("dnf updateinfo list cves | grep kernel")
+ code, stdout, stderr = execute_shell_command(["dnf updateinfo list cves", "grep kernel"])
if code != CommandExitCode.SUCCEED:
LOGGER.error("query unfixed cve info failed by dnf!")
LOGGER.error(stderr)
@@ -287,7 +285,7 @@ class VulnerabilityManage:
# CVE-2021-42574 Important/Sec. binutils-2.34-19.oe1.x86_64 -
# CVE-2023-1513 Important/Sec. kernel-4.19.90-2304.1.0.0196.oe1.x86_64 patch-kernel-4.19.90-2112...
cve_info_list = []
- code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves | grep kernel")
+ code, stdout, stderr = execute_shell_command(["dnf hot-updateinfo list cves", "grep kernel"])
if code != CommandExitCode.SUCCEED:
LOGGER.error("query unfixed cve info failed by dnf!")
LOGGER.error(stderr)
@@ -354,7 +352,7 @@ class VulnerabilityManage:
return fixed_cves
current_kernel_rpm_name = f"kernel-{current_kernel_version}"
- code, stdout, stderr = execute_shell_command("dnf updateinfo list cves --installed |grep kernel")
+ code, stdout, stderr = execute_shell_command(["dnf updateinfo list cves --installed", "grep kernel"])
if code != CommandExitCode.SUCCEED:
LOGGER.error("query fixed cve info failed!")
LOGGER.error(stderr)
@@ -400,7 +398,7 @@ class VulnerabilityManage:
return []
current_kernel_rpm_name = f"kernel-{current_kernel_version}"
- code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves --installed | grep kernel")
+ code, stdout, stderr = execute_shell_command(["dnf hot-updateinfo list cves --installed", "grep kernel"])
if code != CommandExitCode.SUCCEED:
LOGGER.error("query unfixed cve info failed by dnf!")
LOGGER.error(stderr)
@@ -468,7 +466,7 @@ class VulnerabilityManage:
# CVE-2023-1111 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server NOT-APPLIED
# CVE-2023-1112 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server NOT-APPLIED
result = {}
- code, stdout, stderr = execute_shell_command("dnf hotpatch --list cves")
+ code, stdout, stderr = execute_shell_command(["dnf hotpatch --list cves"])
if code != CommandExitCode.SUCCEED:
LOGGER.error("query applied hotpatch info failed!")
LOGGER.error(stderr)
@@ -634,7 +632,7 @@ class VulnerabilityManage:
Tuple[str, str]
a tuple containing two elements (upgrade result, package upgrade log).
"""
- code, stdout, stderr = execute_shell_command(f"dnf upgrade-en {rpm} -y")
+ code, stdout, stderr = execute_shell_command([f"dnf upgrade-en {rpm} -y"])
if code != CommandExitCode.SUCCEED:
LOGGER.error(stderr)
return TaskExecuteRes.FAIL, stdout + stderr
@@ -673,7 +671,7 @@ class VulnerabilityManage:
final_fix_result, package_update_info = TaskExecuteRes.SUCCEED, []
for rpm in rpms:
- code, stdout, stderr = execute_shell_command(f"dnf hotupgrade {rpm} -y")
+ code, stdout, stderr = execute_shell_command([f"dnf hotupgrade {rpm} -y"])
tmp = {
"available_rpm": rpm,
"result": TaskExecuteRes.SUCCEED,
@@ -711,7 +709,7 @@ class VulnerabilityManage:
"kernel-5.10.0-60.91.0.116.oe2203.x86_64": ["CVE-2023-2006"]
}}
"""
- code, stdout, stderr = execute_shell_command("dnf updateinfo list cves")
+ code, stdout, stderr = execute_shell_command(["dnf updateinfo list cves"])
if code != CommandExitCode.SUCCEED:
LOGGER.error("Failed to query update info by dnf!")
LOGGER.error(stderr)
@@ -737,7 +735,7 @@ class VulnerabilityManage:
Example:
"Succeed", {"kernel": {"CVE-2023-XXXX","CVE-2022-XXXX"}}
"""
- code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves --installed")
+ code, stdout, stderr = execute_shell_command(["dnf hot-updateinfo list cves --installed"])
if code != CommandExitCode.SUCCEED:
LOGGER.error("Failed to query fixed cves by hotpatch!")
LOGGER.error(stderr)
@@ -808,7 +806,7 @@ class VulnerabilityManage:
return package_set
# The exit code of the command is 1 when input parameters contains assumeno
- _, stdout, _ = execute_shell_command(f"dnf upgrade-en {package} --assumeno")
+ _, stdout, _ = execute_shell_command([f"dnf upgrade-en {package} --assumeno"])
installed_rpm_info = re.findall(r"(Upgrading|Installing):(.*?)Transaction Summary", stdout, re.S)
if not installed_rpm_info:
@@ -841,7 +839,7 @@ class VulnerabilityManage:
return False
LOGGER.info("The Linux boot kernel is about to be changed")
- code, _, stderr = execute_shell_command(f"grubby --set-default={boot_kernel_path}")
+ code, _, stderr = execute_shell_command([f"grubby --set-default={boot_kernel_path}"])
if code != CommandExitCode.SUCCEED:
LOGGER.info("The Linux boot kernel change failed")
@@ -863,7 +861,9 @@ class VulnerabilityManage:
# ---------------------------------------------------------------------
# 3 | rm aops-ceres | 2023-11-30 09:57 | Removed | 1
# 2 | install gcc | 2023-11-30 09:57 | Install | 1
- code, stdout, stderr = execute_shell_command("dnf history | grep -E '^\s*[0-9]+'|head -1|awk '{print $1}'")
+ code, stdout, stderr = execute_shell_command(
+ ["dnf history", "grep -E '^\s*[0-9]+'", "head -1", "awk '{print $1}'"]
+ )
if code != CommandExitCode.SUCCEED:
LOGGER.error(stderr)
return None
@@ -898,7 +898,7 @@ class VulnerabilityManage:
# Last metadata expiration check: 3:25:24 ago on Wed 13 Sep 2023 08:16:17 AM CST.
# Gonna accept this hot patch: kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1
# accept hot patch 'kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1' failed, remain original status
- code, stdout, stderr = execute_shell_command(f"dnf hotpatch --{operation} {wait_to_remove_patch}")
+ code, stdout, stderr = execute_shell_command([f"dnf hotpatch --{operation} {wait_to_remove_patch}"])
if code != CommandExitCode.SUCCEED or 'failed' in stdout:
LOGGER.error(f"hotpatch {hotpatch} set status failed!")
return False, stdout + stderr
@@ -982,7 +982,7 @@ class VulnerabilityManage:
"CVE-XXXX-XXX": {"patch 1", "patch 2"}
}
"""
- code, stdout, _ = execute_shell_command(f"dnf hot-updateinfo list cves --installed|grep patch")
+ code, stdout, _ = execute_shell_command([f"dnf hot-updateinfo list cves --installed", "grep patch"])
if code != CommandExitCode.SUCCEED:
LOGGER.error(f"Failed to query the hotpatch list.")
return None
@@ -1016,6 +1016,6 @@ class VulnerabilityManage:
Args:
hotpatch: hotpatch package which needs to remove
"""
- cmd = f"dnf remove {hotpatch} -y"
+ cmd = [f"dnf remove {hotpatch} -y"]
_, stdout, stderr = execute_shell_command(cmd)
return True, f"Command:{cmd}\n\n{stdout}\n{stderr}\n"
--
2.33.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/rabbitali/src-aops-ceres.git
git@gitee.com:rabbitali/src-aops-ceres.git
rabbitali
src-aops-ceres
src-aops-ceres
master

搜索帮助