linux - Safer alternative to MATLAB's `system` command -


i have been using matlab's system command result of linux commands, in following simple example:

[junk, result] = system('find ~/ -type f') 

this works expected, unless user types matlab's command window @ same time. during long find command not uncommon. if happens user's input seems mixed result of find command (and things break).

as example, instead of:

/path/to/file/one /path/to/file/two /path/to/file/three /path/to/file/four 

i might get:

j/path/to/file/one u/path/to/file/two n/path/to/file/three k/path/to/file/four 

in order demonstrate easily, can run like:

[junk, result] = system('cat') 

type command window , press ctrl+d close stream. result variable whatever typed in command window.

is there safer way me call system commands matlab without risking corrupted input?

wow. behavior surprising. sounds worth reporting bug mathworks. tested on os x, , see same behavior.

as workaround, re-implement system() using calls java.lang.process , related objects in jvm embedded in matlab.

you'll need to:

  • use polling keep matlab's own input, ctrl-c, live
  • use shell processing instead of passing commands directly processbuilder support expansion of ~ , other variables , wildcards, , support specifying commands , arguments in single string matlab's system does. ** alternately, expose arguments-array form if want lower-level control , don't want deal escaping , quoting strings shell. both useful.
  • redirect output files, or periodically drain child process's output buffers in polling code.

here's example.

function [status,out,errout] = systemwithjava(cmd) %systemcmd version of system implemented java.lang features % % [status,out,errout] = systemwithcmd(cmd) % % written work around issue matlab ui entry getting mixed  % output captured system().  if isunix     % use 'sh -s' enable processing of single line command , expansion of ~     % , other special characters, matlab system()     pb = java.lang.processbuilder({'bash', '-s'});     % redirect stdout avoid filling buffers     mytempname = tempname;     stdoutfile = [mytempname '.systemwithjava.out'];     stderrfile = [mytempname '.systemwithjava.err'];     pb.redirectoutput(java.io.file(stdoutfile));     pb.redirecterror(java.io.file(stderrfile));     p = pb.start();     raii.cleanupprocess = oncleanup(@() p.destroy());     raii.stdoutfile = oncleanup(@() delete(stdoutfile));     raii.stderrfile = oncleanup(@() delete(stderrfile));     childstdin = java.io.printstream(p.getoutputstream());     childstdin.println(cmd);     childstdin.close(); else     % todo: fill in windows implementation here     end  % poll instead of waitfor() ctrl-c stays live % try/catch mechanism lousy, there no isfinished() method. % done more cleanly java worker did waitfor() on % separate thread, , have gui event thread interrupt on ctrl-c. status = []; while true     try         status = p.exitvalue();         % if returned, means process finished         break;     catch err         if isequal(err.identifier, 'matlab:java:genericexception') ...                 && isa(err.exceptionobject, 'java.lang.illegalthreadstateexception')             % means child process still running             % (seriously, java.lang.process, no "bool isfinished()"?             % continue         else             rethrow(err);         end     end     % pause allow ui event processing, including ctrl-c     pause(.01); end  % collect output out = slurpfile(stdoutfile); errout = slurpfile(stderrfile); end  function out = slurpfile(file) fid = fopen(file, 'r'); raii.fid = oncleanup(@() fclose(fid)); out = fread(fid, 'char=>char')'; %' end 

i tried out best could, , looks keeps child process's output separate keyboard input matlab ide. keyboard input buffered , executed additional commands after systemwithjava() returns. ctrl-c stays live , interrupt function, letting child process killed.


Comments

Popular posts from this blog

c++ - OpenCV Error: Assertion failed <scn == 3 ::scn == 4> in unknown function, -

php - render data via PDO::FETCH_FUNC vs loop -

The canvas has been tainted by cross-origin data in chrome only -