lib.ExecContext.run(): Pass LC_ALL=C by default

Pass LC_ALL="C" to _run() by default. This is necessary to be able to
parse error messages and raise FileNotFound if need be.

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-04-17 13:18:37 +02:00
commit 8a0770aec5

View file

@ -21,9 +21,10 @@ class ExecContext(Base):
def __init__( def __init__(
self, self,
parent: ExecContext, parent: ExecContext,
title: str, title: str|None,
cmd: list[str], cmd: list[str],
cmd_input: Input, cmd_input: Input,
env: dict[str, str]|None,
wd: str|None, wd: str|None,
log_prefix: str, log_prefix: str,
throw: bool, throw: bool,
@ -38,6 +39,7 @@ class ExecContext(Base):
self.__delim = title if title is not None else f'---- {parent.uri}: Running {self.pretty_cmd} -' self.__delim = title if title is not None else f'---- {parent.uri}: Running {self.pretty_cmd} -'
delim_len = 120 delim_len = 120
self.__delim += '-' * max(0, delim_len - len(self.__delim)) self.__delim += '-' * max(0, delim_len - len(self.__delim))
self.__env = {'LC_ALL': 'C'} if env is None else env
# -- At the end of this dance, interactive needs to be either True # -- At the end of this dance, interactive needs to be either True
# or False # or False
@ -98,6 +100,10 @@ class ExecContext(Base):
def cmd_input(self) -> bytes|None: def cmd_input(self) -> bytes|None:
return self.__cmd_input return self.__cmd_input
@property
def env(self) -> dict[str, str]:
return self.__env
@property @property
def throw(self) -> bool: def throw(self) -> bool:
return self.__throw return self.__throw
@ -190,7 +196,7 @@ class ExecContext(Base):
assert cmd_input is not None assert cmd_input is not None
ret = Result(None, None, 1) ret = Result(None, None, 1)
with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, wd=wd, with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, env=env, wd=wd,
log_prefix='|', throw=throw, verbose=verbose) as cc: log_prefix='|', throw=throw, verbose=verbose) as cc:
try: try:
ret = await self._run( ret = await self._run(
@ -198,7 +204,7 @@ class ExecContext(Base):
wd=wd, wd=wd,
verbose=cc.verbose, verbose=cc.verbose,
cmd_input=cc.cmd_input, cmd_input=cc.cmd_input,
env=env, env=cc.env,
interactive=cc.interactive, interactive=cc.interactive,
log_prefix=cc.log_prefix log_prefix=cc.log_prefix
) )
@ -231,9 +237,7 @@ class ExecContext(Base):
ret = Result(None, None, 1) ret = Result(None, None, 1)
if opts is None: if opts is None:
opts = {} opts = {}
if mod_env is None: with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, env=env, wd=wd,
mod_env = {}
with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, wd=wd,
log_prefix='|', throw=throw, verbose=verbose) as cc: log_prefix='|', throw=throw, verbose=verbose) as cc:
try: try:
ret = await self._sudo( ret = await self._sudo(
@ -243,7 +247,7 @@ class ExecContext(Base):
wd=wd, wd=wd,
verbose=cc.verbose, verbose=cc.verbose,
cmd_input=cc.cmd_input, cmd_input=cc.cmd_input,
env=env, env=cc.env,
interactive=cc.interactive, interactive=cc.interactive,
log_prefix=cc.log_prefix, log_prefix=cc.log_prefix,
) )
@ -264,7 +268,7 @@ class ExecContext(Base):
if wd is not None: if wd is not None:
path = wd + '/' + path path = wd + '/' + path
with self.CallContext(self, title=title, cmd=['cat', path], with self.CallContext(self, title=title, cmd=['cat', path],
cmd_input=InputMode.NonInteractive, wd=None, cmd_input=InputMode.NonInteractive, wd=None, env=None,
log_prefix='|', throw=throw, verbose=verbose) as cc: log_prefix='|', throw=throw, verbose=verbose) as cc:
try: try:
ret = await self._run( ret = await self._run(
@ -272,7 +276,7 @@ class ExecContext(Base):
wd=wd, wd=wd,
verbose=cc.verbose, verbose=cc.verbose,
cmd_input=cc.cmd_input, cmd_input=cc.cmd_input,
env=None, env=cc.env,
interactive=cc.interactive, interactive=cc.interactive,
log_prefix=cc.log_prefix log_prefix=cc.log_prefix
) )