From 20aada54aa16227f412a2ca0bc05cdc3139dd5fa Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Sat, 20 Oct 2018 18:00:02 +0200 Subject: [PATCH] Fix 'system' to run cmd through shell system modulefile command is intended to the command passed to it trough shell, like done on compatibility version. So update system procedure to find correct shell on the current platform and run command through it. Doing so, shell commands with backticks for instance are correctly run. Fixes #205 --- doc/source/modulefile.rst | 8 ++++---- modulecmd.tcl.in | 16 +++++++++++++--- testsuite/modulefiles/system/2.0 | 2 ++ testsuite/modules.50-cmds/140-system.exp | 4 +++- testsuite/systest1 | 3 +++ 5 files changed, 25 insertions(+), 8 deletions(-) create mode 100755 testsuite/systest1 diff --git a/doc/source/modulefile.rst b/doc/source/modulefile.rst index 77876bf4..52ac8997 100644 --- a/doc/source/modulefile.rst +++ b/doc/source/modulefile.rst @@ -444,10 +444,10 @@ the *modulefile* is being loaded. **system** string - Pass *string* to the Tcl built-in command **exec**\ (n). For the **exec**\ - (n) call **modulecmd.tcl** redirects stdout to stderr since stdout would - be parsed by the evaluating shell. The exit status of the executed command - is returned. + Run *string* command through shell. On Unix, command is passed to the + ``/bin/sh`` shell whereas on Windows it is passed to ``cmd.exe``. + **modulecmd.tcl** redirects stdout to stderr since stdout would be parsed by + the evaluating shell. The exit status of the executed command is returned. **uname** field diff --git a/modulecmd.tcl.in b/modulecmd.tcl.in index dcd44485..f2b0f997 100644 --- a/modulecmd.tcl.in +++ b/modulecmd.tcl.in @@ -2733,14 +2733,24 @@ proc uname {what} { return $::unameCache($what) } -proc system {mycmd args} { - reportDebug "$mycmd $args" +# run shell command +proc system {args} { + reportDebug $args set mode [currentMode] set status {} if {$mode eq "load" || $mode eq "unload"} { - if {[catch {eval exec >&@stderr $mycmd $args}]} { + # run through the appropriate shell + if {[isWin]} { + set shell cmd.exe + set shellarg /c + } else { + set shell /bin/sh + set shellarg -c + } + + if {[catch {exec >&@stderr $shell $shellarg [join $args]}]} { # non-zero exit status, get it: set status [lindex $::errorCode 2] } else { diff --git a/testsuite/modulefiles/system/2.0 b/testsuite/modulefiles/system/2.0 index 5ca7954c..99159384 100644 --- a/testsuite/modulefiles/system/2.0 +++ b/testsuite/modulefiles/system/2.0 @@ -31,3 +31,5 @@ setenv testsuite [system $env(TESTSUITEDIR)/systest] setenv testsuite2 [system $env(TESTSUITEDIR)/systest 1 0 9] setenv testsuite3 [system "$env(TESTSUITEDIR)/systest 1 0 9"] +setenv testsuite4 [system "$env(TESTSUITEDIR)/systest1 /path/to/`$env(TESTSUITEDIR)/systest1 dir`/file"] +setenv testsuite5 [system $env(TESTSUITEDIR)/systest1 /path/to/`$env(TESTSUITEDIR)/systest1 dir`/file] diff --git a/testsuite/modules.50-cmds/140-system.exp b/testsuite/modules.50-cmds/140-system.exp index 5d24a7c9..ec480b1d 100644 --- a/testsuite/modules.50-cmds/140-system.exp +++ b/testsuite/modules.50-cmds/140-system.exp @@ -33,9 +33,11 @@ lappend ans [list set testsuite2 109] lappend ans [list set testsuite3 109] lappend ans [list set _LMFILES_ $modulefile] lappend ans [list set LOADEDMODULES $module] +lappend ans [list set testsuite4 0] lappend ans [list set testsuite 123] +lappend ans [list set testsuite5 0] -test_cmd "csh" "load $module" $ans +testouterr_cmd "csh" "load $module" $ans "str:/path/to/str:dir/file\nstr:/path/to/str:dir/file" # # Test a command returning 0 exit code diff --git a/testsuite/systest1 b/testsuite/systest1 new file mode 100755 index 00000000..2784b1ed --- /dev/null +++ b/testsuite/systest1 @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "str:$1"