3

I have a MatLab project on Win-7.

Its version controled with Git-Extension.

I have a matlab function that runs a kind of self-test.

It's named pre_push_test_suit, and it exits with either code 0 (OK) or 1 (there is a problem).

I want to implement the pre-commit git hook, that will prevent pushing to the central repo if the self-test function fails.

my script starts like this:

#!/bin/sh
res_file=pre_push_test_log.txt
resultcode=$(matlab -automation -minimize -r pre_push_test_suit -logfile $res_file)
if [ "$resultcode" -eq "0" ]
...

Expected result: I wanted the script to lunch MatLab and wait for exit value.

Actual result: the script lunches MatLab process, and continues with empty value in $resultcode.

If I got it correctly, the script is run on a bash-like shell that is installed with git on windows, but I'm not sure it is a real bash.

Typing ps did not show the matlab process.

Also tried, but with no change of result:

  • to replace the $(...) with ...
  • to add "wait" after the third line
  • google it.

I did not try scripts in any other language but bash (I do not know many scripting languages).

I thought about the ugly solution of infinite loop with "wait", waiting for a file to contain some output, but i prefer something more decent.

Any better solution to wait for the result, in any language, is welcome.

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
Oded
  • 151
  • 1
  • 1
  • 4
  • use wait to wait for the process to be finished: http://stackoverflow.com/questions/356100/how-to-wait-in-bash-for-several-subprocesses-to-finish-and-return-exit-code-0/26240420#26240420 – patapouf_ai Jul 20 '15 at 15:36
  • `matlab` is probably forcibly disassociating itself from the controlling terminal (to run as a windowed/etc. application. You need to see if it has a no-daemon, no-background or foreground command line argument you can give it to make it not do that. Many programs that do this sort of thing have such an option. – Etan Reisner Jul 20 '15 at 16:08

2 Answers2

1

It seems the problem occurs because matlab automatically detaches itself from the shell in windows (this behaviour doesn't happen on Linux with the -nodesktop option).

Option 1:

Use the -wait option:

From Docs

Wait for MATLAB to Terminate

By default, when you call the matlab command from a script, the command starts MATLAB and then immediately executes the next statements in the script. The -wait option pauses the script until MATLAB terminates. Option Result

-wait

Use in a startup script to process the results from MATLAB. Calling MATLAB with this option blocks the script from continuing until the results are generated.

#!/bin/sh

res_file=pre_push_test_log.txt

resultcode=$(matlab -wait -nodesktop -minimize -r pre_push_test_suit -logfile $res_file) 


if [ "$resultcode" -eq "0" ]

Option 2:

use octave instead of matlab

Option 3:

use wait to wait for the process to be finished: How to wait in bash for several subprocesses to finish and return exit code !=0 when any subprocess ends with code !=0?

the -nodesktop option should keep the matlab session inside terminal's control.

#!/bin/sh

res_file=pre_push_test_log.txt

resultcode=$(matlab -nodesktop  -minimize -r pre_push_test_suit -logfile $res_file) 
wait $!

if [ "$resultcode" -eq "0" ]

[there are problems with option 3, see comments]

Community
  • 1
  • 1
patapouf_ai
  • 17,605
  • 13
  • 92
  • 132
  • From what I understand, the OP waited for the file to contain info, not waiting for the process to be finished. And the OP did some ugly loop, which I am not doing here. – patapouf_ai Jul 20 '15 at 16:09
  • I don't know how OP added wait after the third line, but it must have been wrong because waiting for the process works. – patapouf_ai Jul 20 '15 at 16:11
  • There's no "ugly loop" in the OPs code. That was a potential solution they rejected. And no, `wait` does not work on processes that forcibly detach themselves. Try running `{ sleep 5s & } &; wait` and tell me if your `wait` waits for anything. – Etan Reisner Jul 20 '15 at 16:24
  • that's why I give the pid to wait. – patapouf_ai Jul 20 '15 at 16:25
  • Wrong place for that `&`. You need it inside the `$()`. And this may or may not help if `matlab` itself disassociates. Try my earlier example with an explicit `wait "$!"` and it doesn't work any better either. – Etan Reisner Jul 20 '15 at 16:27
  • With `-nodesktop` (assuming that keeps `matlab` in the foreground) there shouldn't be a need to `wait` at all. – Etan Reisner Jul 20 '15 at 16:44
  • 1
    Being new in SO, I may fail to form it correctly. But: As for the wait – I added the wait line just like in the suggestion above. It did not solve it. As for the -nodesktop option, it is covered by the -automation option (see [link](http://www.mathworks.com/matlabcentral/newsreader/view_thread/83159) ) yet, I tried both as in the line suggested, and then wrote ps, but there was no new process ID (except for the ps itself), so there was now process recognized by the shell to wait for. Just to be sure I'm having it correctly, I did the same for sleep and did have a new entry in ps output. – Oded Jul 21 '15 at 13:24
  • Thanks for this info. Let me check into it. – patapouf_ai Jul 21 '15 at 13:40
  • According to info here: http://stackoverflow.com/questions/12111957/parsing-variables-from-matlab-to-linux-and-vice-versa-in-a-shell the situation doesn't look promissing. – patapouf_ai Jul 21 '15 at 14:10
  • Because it seems that the shell detaches automatically, I was hoping that the initial suggestion of wait $! would work without & at the end of the automatically detaching line ... – patapouf_ai Jul 21 '15 at 14:12
  • trying `ps -ef ` should show you all processes. `ps` only potentially misses some processes. – patapouf_ai Jul 21 '15 at 14:24
0

is did not try Octave, as it will take installing Octave on each machine of the team, and is sensitive to the small differences between MatLab and Octave (I run a lot of code in the pre-push test).

at the bottom line i made the MatLab function write result (0 for success) to a file named $(matlab_file).txt, implemented the ugli loop i mentioned before.

here is the code i use now:

#!/bin/sh
matlab_file="pre_push_test_suit"
log_file="pre_push_test_log.txt"
res_file="${matlab_file}.txt"
rm -f $log_file
rm -f $res_file
sleep 1
matlab -automation -minimize -r $matlab_file -logfile $log_file
# wait for the result file to exist
until [ -f $res_file ]
do
     sleep 1
done
sleep 1
res_zero="$(grep 0 $res_file | wc -l)"
if [ $res_zero -eq "1" ]
    then
        echo "matlab pre_push_test_suit OK"
        exit 0
fi
echo "matlab pre_push_test_suit exited with an error"
echo "push is prevented"
exit 1
Oded
  • 151
  • 1
  • 1
  • 4