[elbe-devel] [PATCH 2/3] elbepack: shellhelper: handle non-shell commands
Thomas Weißschuh
thomas.weissschuh at linutronix.de
Thu Apr 25 17:47:21 CEST 2024
Executing commands via a shell has a multitude of problems.
(See the docs of the python subprocess module)
Extend shellhelper to also handle non-shell commands.
In due time all usages of shellhelper should be migrated to non-shell
mode.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh at linutronix.de>
---
elbepack/shellhelper.py | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/elbepack/shellhelper.py b/elbepack/shellhelper.py
index 1b32fd784467..cda394c34470 100644
--- a/elbepack/shellhelper.py
+++ b/elbepack/shellhelper.py
@@ -5,6 +5,7 @@
import logging
import os
+import shlex
import subprocess
from subprocess import PIPE, Popen, STDOUT
@@ -14,6 +15,17 @@ log = logging.getLogger('log')
soap = logging.getLogger('soap')
+def _is_shell_cmd(cmd):
+ return isinstance(cmd, str)
+
+
+def _log_cmd(cmd):
+ if _is_shell_cmd(cmd):
+ return cmd
+ else:
+ return shlex.join(cmd)
+
+
def do(cmd, allow_fail=False, stdin=None, env_add=None, log_cmd=None):
"""do() - Execute cmd in a shell and redirect outputs to logging.
@@ -53,14 +65,16 @@ def do(cmd, allow_fail=False, stdin=None, env_add=None, log_cmd=None):
if isinstance(stdin, str):
stdin = stdin.encode()
- logging.info(log_cmd or cmd, extra={'context': '[CMD] '})
+ shell = _is_shell_cmd(cmd)
+
+ logging.info(log_cmd or _log_cmd(cmd), extra={'context': '[CMD] '})
r, w = os.pipe()
if stdin is None:
- p = Popen(cmd, shell=True, stdout=w, stderr=STDOUT, env=new_env)
+ p = Popen(cmd, shell=shell, stdout=w, stderr=STDOUT, env=new_env)
else:
- p = Popen(cmd, shell=True, stdin=PIPE, stdout=w, stderr=STDOUT, env=new_env)
+ p = Popen(cmd, shell=shell, stdin=PIPE, stdout=w, stderr=STDOUT, env=new_env)
with async_logging_ctx(r, w, soap, log):
p.communicate(input=stdin)
@@ -131,14 +145,16 @@ def get_command_out(cmd, stdin=None, allow_fail=False, env_add=None):
if isinstance(stdin, str):
stdin = stdin.encode()
- logging.info(cmd, extra={'context': '[CMD] '})
+ shell = _is_shell_cmd(cmd)
+
+ logging.info(_log_cmd(cmd), extra={'context': '[CMD] '})
r, w = os.pipe()
if stdin is None:
- p = Popen(cmd, shell=True, stdout=PIPE, stderr=w, env=new_env)
+ p = Popen(cmd, shell=shell, stdout=PIPE, stderr=w, env=new_env)
else:
- p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=w, env=new_env)
+ p = Popen(cmd, shell=shell, stdin=PIPE, stdout=PIPE, stderr=w, env=new_env)
with async_logging_ctx(r, w, soap, log):
stdout, _ = p.communicate(input=stdin)
--
2.44.0
More information about the elbe-devel
mailing list