Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions easybuild/tools/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,22 +273,28 @@ def create_cmd_scripts(cmd_str, work_dir, env, tmpdir, out_file, err_file):
# Make script that sets up bash shell with specified environment and working directory
cmd_fp = os.path.join(tmpdir, 'cmd.sh')

# using -i to force interactive shell, so env.sh is also sourced when -c is used to run commands
launch_cmd = 'bash --rcfile $EB_SCRIPT_DIR/env.sh -i "$@"'

launch_cmd = 'bash'
# prefix launch command with bwrap (if used)
bwrap_cmd = os.getenv('EB_BWRAP_CMD')
if bwrap_cmd:
launch_cmd = bwrap_cmd + ' ' + launch_cmd

# using -i for interactive shell, so env.sh is sourced
launch_cmd_interactive = f'{launch_cmd} --rcfile $EB_SCRIPT_DIR/env.sh -i'
launch_cmd_with_args = f'BASH_ENV=$EB_SCRIPT_DIR/env.sh {launch_cmd} "$@"'

with open(cmd_fp, 'w') as fid:
fid.write('#!/usr/bin/env bash\n')
fid.write('# Run this script to set up a shell environment that EasyBuild used to run the shell command\n')
fid.write('\n'.join([
'EB_SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )',
f'echo "# Shell for the command: \'"{shlex.quote(cmd_str)}"\'"',
'echo "# Use command history, exit to stop"',
launch_cmd,
'if [ "$#" -eq 0 ]; then',
' ' + launch_cmd_interactive,
'else',
' ' + launch_cmd_with_args,
'fi',
]))
os.chmod(cmd_fp, 0o775)

Expand Down
15 changes: 9 additions & 6 deletions test/framework/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,20 +266,23 @@ def test_run_shell_cmd_basic(self):
cmd_script = os.path.join(cmd_tmpdir, 'cmd.sh')
self.assertExists(cmd_script)

cmd = f"{cmd_script} -c 'echo pwd: $PWD; echo $FOOBAR; echo $EB_CMD_OUT_FILE; cat $EB_CMD_OUT_FILE'"
cmd = f"{cmd_script} -c '"
cmd += 'echo pwd: $PWD; echo "bash_env: $BASH_ENV"; echo $FOOBAR; echo $EB_CMD_OUT_FILE; cat $EB_CMD_OUT_FILE'
cmd += "'"
with self.mocked_stdout_stderr():
res = run_shell_cmd(cmd, fail_on_error=False)
self.assertEqual(res.exit_code, 0)
regex = re.compile("pwd: .*\nfoobar\n.*/echo-.*/out.txt\nhello$")
regex = re.compile("pwd: .*\nbash_env: .*\nfoobar\n.*/echo-.*/out.txt\nhello$")
self.assertTrue(regex.search(res.output), f"Pattern '{regex.pattern}' should be found in {res.output}")

# check whether working directory is what's expected
regex = re.compile('^pwd: .*', re.M)
res = regex.findall(res.output)
self.assertEqual(len(res), 1)
pwd = res[0].strip()[5:]
matches = re.findall('^pwd: (.*)', res.output, re.M)
self.assertEqual(len(matches), 1)
pwd = matches[0]
self.assertTrue(os.path.samefile(pwd, self.test_prefix))

# BASH_ENV is that of the current shell, not the one set in the cmd.sh
self.assertEqual(re.search('^bash_env: (.*)', res.output, re.M)[1], os.environ.get('BASH_ENV', ''))
cmd = f"{cmd_script} -c 'module --version'"
with self.mocked_stdout_stderr():
res = run_shell_cmd(cmd, fail_on_error=False)
Expand Down
Loading