Skip to content

Commit 25fd748

Browse files
authored
Merge pull request #5187 from Flamefire/fix-non-interactive-cmd.sh
enhance `cmd.sh` so it works in non-interactive mode, like when passing `-c` to run a command
2 parents 6a8ce5c + 32f0f69 commit 25fd748

2 files changed

Lines changed: 19 additions & 10 deletions

File tree

easybuild/tools/run.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,22 +273,28 @@ def create_cmd_scripts(cmd_str, work_dir, env, tmpdir, out_file, err_file):
273273
# Make script that sets up bash shell with specified environment and working directory
274274
cmd_fp = os.path.join(tmpdir, 'cmd.sh')
275275

276-
# using -i to force interactive shell, so env.sh is also sourced when -c is used to run commands
277-
launch_cmd = 'bash --rcfile $EB_SCRIPT_DIR/env.sh -i "$@"'
278-
276+
launch_cmd = 'bash'
279277
# prefix launch command with bwrap (if used)
280278
bwrap_cmd = os.getenv('EB_BWRAP_CMD')
281279
if bwrap_cmd:
282280
launch_cmd = bwrap_cmd + ' ' + launch_cmd
283281

282+
# using -i for interactive shell, so env.sh is sourced
283+
launch_cmd_interactive = f'{launch_cmd} --rcfile $EB_SCRIPT_DIR/env.sh -i'
284+
launch_cmd_with_args = f'BASH_ENV=$EB_SCRIPT_DIR/env.sh {launch_cmd} "$@"'
285+
284286
with open(cmd_fp, 'w') as fid:
285287
fid.write('#!/usr/bin/env bash\n')
286288
fid.write('# Run this script to set up a shell environment that EasyBuild used to run the shell command\n')
287289
fid.write('\n'.join([
288290
'EB_SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )',
289291
f'echo "# Shell for the command: \'"{shlex.quote(cmd_str)}"\'"',
290292
'echo "# Use command history, exit to stop"',
291-
launch_cmd,
293+
'if [ "$#" -eq 0 ]; then',
294+
' ' + launch_cmd_interactive,
295+
'else',
296+
' ' + launch_cmd_with_args,
297+
'fi',
292298
]))
293299
os.chmod(cmd_fp, 0o775)
294300

test/framework/run.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,20 +266,23 @@ def test_run_shell_cmd_basic(self):
266266
cmd_script = os.path.join(cmd_tmpdir, 'cmd.sh')
267267
self.assertExists(cmd_script)
268268

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

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

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

0 commit comments

Comments
 (0)