[rtems-tools PATCH] rtemstoolkit: Fix shell execution

Frank Kühndel frank.kuehndel at embedded-brains.de
Tue Aug 29 08:23:50 UTC 2023


Hello Chris,

our continuous integration server found an issues with this patch
("module 'shlex' has no attribute 'join'"):

+ cd rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8
+ ./waf distclean configure --prefix=/opt/rtems/6
'distclean' finished successfully (0.001s)
Setting top to                           : 
/home/minna/src/rtems-source-builder/rtems/build/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8 

Setting out to                           : 
/home/minna/src/rtems-source-builder/rtems/build/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8/build 

invalid version file: module 'shlex' has no attribute 'join'
(complete log in 
/home/minna/src/rtems-source-builder/rtems/build/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8/build/config.log)
shell cmd failed: /bin/sh -ex 
/home/minna/src/rtems-source-builder/rtems/build/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1/do-build
error: building rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1

Our CI build RTEMS Source Builder git commit 
0860f9948dec7c001391948337723b313c052d1b correctly over the weekend. 
Tonight it failed with git commit 
9ca95760eefadccd90e651b248efbe42810d2ed6. The failing build was a build 
with the following parameters:

Container: opensuse-leap 15.5
Python: 3.6.15
Nativ gcc: 7.5.0
Command Line: ../source-builder/sb-set-builder --rtems-version 6 
--prefix /opt/rtems/6 --with_cxx --with_fortran --with_objc --jobs=12 
--trace --log 
/home/minna/src/rtems6-devtools-arm-6+git.4303.9ca95760ee.x86_64_sb-set-builder.log 
6/rtems-arm
Git head: 9ca95760eefadccd90e651b248efbe42810d2ed6
RTEMS Version: 6
RTEMS Tools for: ARM
Build host arch: x86_64

Your RSB commit triggered only this single build (opensuse 15.5/ARM). I 
have not tested to build on different Linux distributions or 
architectures, yet. If you need more infos, drop me an email. If you 
have a fix, I am happy to test it.

Greetings,
Frank

On 8/28/23 08:47, chrisj at rtems.org wrote:
> Subject:
> [rtems-tools PATCH] rtemstoolkit: Fix shell execution
> From:
> chrisj at rtems.org
> Date:
> 8/28/23, 08:47
> 
> To:
> devel at rtems.org
> 
> 
> From: Chris Johns<chrisj at rtems.org>
> 
> The fixes to parse the command along with the pipe options broke
> a simple shell command such as '/sbin/sysctl hw.ncpu' on FreeBSD.
> This patch fixes the shell command by passing a string for the
> various options.
> 
> The unit test has been updated to catch errors and report them.
> ---
>   rtemstoolkit/execute.py | 80 ++++++++++++++++++++++++++---------------
>   1 file changed, 51 insertions(+), 29 deletions(-)
> 
> diff --git a/rtemstoolkit/execute.py b/rtemstoolkit/execute.py
> index 3b7dcb0..d183b14 100755
> --- a/rtemstoolkit/execute.py
> +++ b/rtemstoolkit/execute.py
> @@ -356,10 +356,17 @@ class execute(object):
>           a string."""
>           if self.output is None:
>               raise error.general('capture needs an output handler')
> -        cs = command
> -        if type(command) is list:
> -            def add(x, y): return x + ' ' + str(y)
> -            cs = functools.reduce(add, command, '')[1:]
> +        # If a string split and not a shell command split
> +        if not shell and isinstance(command, str):
> +            command = shlex.split(command)
> +        if shell and isinstance(command, list):
> +            command = shlex.join(command)
> +            if self.shell_exe:
> +                command = self.shell_exe + ' ' + command
> +        if isinstance(command, list):
> +            cs = shlex.join(command)
> +        else:
> +            cs = command
>           what = 'spawn'
>           if shell:
>               what = 'shell'
> @@ -367,9 +374,6 @@ class execute(object):
>           if self.verbose:
>               log.output(what + ': ' + cs)
>           log.trace('exe: %s' % (cs))
> -        if shell and self.shell_exe:
> -            command = arg_list(command)
> -            command[:0] = self.shell_exe
>           if not stdin and self.input:
>               stdin = subprocess.PIPE
>           if not stdout:
> @@ -390,21 +394,21 @@ class execute(object):
>                       r, e = os.path.splitext(command[0])
>                       if e not in ['.exe', '.com', '.bat']:
>                           command[0] = command[0] + '.exe'
> -            # If a string split
> -            if isinstance(command, str):
> -                command = shlex.split(command)
> -            # See if there is a pipe operator in the command. If present
> -            # split the commands by the pipe and run them with the pipe.
> -            # if no pipe it is the normal stdin and stdout
>               pipe_commands = []
> -            current_command = []
> -            for cmd in command:
> -                if cmd == '|':
> -                    pipe_commands.append(current_command)
> -                    current_command = []
> -                else:
> -                    current_command.append(cmd)
> -            pipe_commands.append(current_command)
> +            if shell:
> +                pipe_commands.append(command)
> +            else:
> +                # See if there is a pipe operator in the command. If present
> +                # split the commands by the pipe and run them with the pipe.
> +                # if no pipe it is the normal stdin and stdout
> +                current_command = []
> +                for cmd in command:
> +                    if cmd == '|':
> +                        pipe_commands.append(current_command)
> +                        current_command = []
> +                    else:
> +                        current_command.append(cmd)
> +                pipe_commands.append(current_command)
>               proc = None
>               if len(pipe_commands) == 1:
>                   cmd = pipe_commands[0]
> @@ -600,16 +604,28 @@ class capture_execution(execute):
>   if __name__ == "__main__":
>       def run_tests(e, commands, use_shell):
>           for c in commands['shell']:
> -            e.shell(c)
> +            ec, out = e.shell(c)
> +            if ec != 0:
> +              raise RuntimeError('ec = {}'.format(ec))
> +        for c in commands['error']:
> +            ec, out = e.shell(c)
> +            if ec == 0:
> +              raise RuntimeError('ec = {}'.format(ec))
>           for c in commands['spawn']:
> -            e.spawn(c)
> +            ec, out = e.spawn(c)
> +            if ec != 0:
> +              raise RuntimeError('ec = {}'.format(ec))
>           for c in commands['cmd']:
>               if type(c) is str:
> -                e.command(c, shell = use_shell)
> +                ec, out = e.command(c, shell = use_shell)
>               else:
> -                e.command(c[0], c[1], shell = use_shell)
> +                ec, out = e.command(c[0], c[1], shell = use_shell)
> +            if ec != 0:
> +              raise RuntimeError('ec = {}'.format(ec))
>           for c in commands['csubsts']:
> -            e.command_subst(c[0], c[1], shell = use_shell)
> +            ec, out = e.command_subst(c[0], c[1], shell = use_shell)
> +            if ec != 0:
> +              raise RuntimeError('ec = {}'.format(ec))
>           ec, proc = e.command(commands['pipe'][0], commands['pipe'][1],
>                                capture = False, stdin = subprocess.PIPE)
>           if ec == 0:
> @@ -623,11 +639,15 @@ if __name__ == "__main__":
>               proc.stdin.close()
>               e.capture(proc)
>               del proc
> +        else:
> +            raise RuntimeError('ec = {}'.format(ec))
>           for c in commands['open']:
>               ec, proc = e.open(c)
>               if ec == 0:
>                   e.capture(proc)
>                   del proc
> +            else:
> +                raise RuntimeError('ec = {}'.format(ec))
>   
>       def capture_output(text):
>           print(text, end = '')
> @@ -640,7 +660,8 @@ if __name__ == "__main__":
>       commands = {}
>       commands['windows'] = {}
>       commands['unix'] = {}
> -    commands['windows']['shell'] = ['cd', 'dir /w', '.\\xyz', cmd_shell_test]
> +    commands['windows']['shell'] = ['cd', 'dir /w', cmd_shell_test]
> +    commands['windows']['error'] = ['.\\xyz']
>       commands['windows']['spawn'] = ['hostname', 'hostnameZZ', ['netstat', '/e']]
>       commands['windows']['cmd'] = [('ipconfig'), ('nslookup', 'www.python.org')]
>       commands['windows']['csubsts'] = [('netstat %0', ['-a']),
> @@ -650,8 +671,9 @@ if __name__ == "__main__":
>               ["echo",  "hello rtems", "|", "findstr", "rtems"],
>               " ".join(["echo",  "hello rtems", "|", "findstr", "rtems"])
>               ]
> -    commands['unix']['shell'] = ['pwd', 'ls -las', './xyz', sh_shell_test]
> -    commands['unix']['spawn'] = ['ls', 'execute.pyc', ['ls', '-i']]
> +    commands['unix']['shell'] = ['pwd', 'ls -las', sh_shell_test, 'ls -las']
> +    commands['unix']['error'] = ['./xyz']
> +    commands['unix']['spawn'] = ['ls', ['ls', '-i'], 'ls -l']
>       commands['unix']['cmd'] = [('date'), ('date', '-R'), ('date', ['-u', '+%d %D']),
>                                  ('date', '-u "+%d %D %S"')]
>       commands['unix']['csubsts'] = [('date %0 "+%d %D %S"', ['-u']),
> -- 2.37.1 _______________________________________________ devel mailing 
> list devel at rtems.org http://lists.rtems.org/mailman/listinfo/devel
> 

-- 
embedded brains GmbH & Co. KG
Herr Frank KÜHNDEL
Dornierstr. 4
82178 Puchheim
Germany
email: frank.kuehndel at embedded-brains.de
phone:  +49-89-18 94 741 - 23
mobile: +49-176-15 22 06 - 11

Registergericht: Amtsgericht München
Registernummer: HRA 117265
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


More information about the devel mailing list