Start application from Matlab - linux

I'm looking for a way to start an application from within Matlab. The thing is, my Matlab script saves some results to a file, which should then be opened in the associated application (Blender in this case).
I'm familiar with commands like
system('program_name')
or
!program_name
and some other ways, but the thing is, the application is started with the Matlab PATH, so it looks inside the Matlab directory for all kinds of libraries it needs. For instance:
>> !blender
blender: /usr/local/MATLAB/R2011a/sys/os/glnx86/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by blender)
Is there some way to start an application, which uses the global (system) PATH?
A moment ago I thought I found a tweak, namely starting a terminal from within Matlab, with some arguments (Blender filename.blend).
system('terminal -x blender /home/pieter/Red.blend')
This did work a couple of times, but now I'm getting errors after executing this command 20 times or so...
>> system('terminal -x blender /home/pieter/Red.blend')
(terminal:10982): GLib-CRITICAL **: PCRE library is compiled without UTF8 support
(terminal:10982): Terminal-CRITICAL **: Failed to parse regular expression pattern 0: PCRE library is compiled without UTF8 support
I'm using Arch Linx, by the way.
Edit:
Well, I just thought of a rather dirty solution. Matlab uses the environment variable
LD_LIBRARY_PATH
For the paths to the necessary libraries:
getenv('LD_LIBRARY_PATH')
/usr/local/MATLAB/R2011a/sys/os/glnx86:/usr/local/MATLAB/R2011a/bin/glnx86:/usr/local/MATLAB/R2011a/extern/lib/glnx86:/usr/local/MATLAB/R2011a/runtime/glnx86:/usr/local/MATLAB/R2011a/sys/java/jre/glnx86/jre/lib/i386/native_threads:/usr/local/MATLAB/R2011a/sys/java/jre/glnx86/jre/lib/i386/client:/usr/local/MATLAB/R2011a/sys/java/jre/glnx86/jre/lib/i386
So I could save this information to a variable (e.g. MatlabPath):
MatlabPath = getenv('LD_LIBRARY_PATH')
and then before I call blender do this:
setenv('LD_LIBRARY_PATH',getenv('PATH'))
Which makes Matlab use my system libraries. Then after the program has started, re-assign the old value to LD_LIBRARY_PATH:
setenv('LD_LIBRARY_PATH',MatlabPath)
So... it is a solution, but if anybody knows a cleaner way of solving the problem, let me know.

As I indicated in my Edit above, this could be a solution:
% Save library paths
MatlabPath = getenv('LD_LIBRARY_PATH');
% Make Matlab use system libraries
setenv('LD_LIBRARY_PATH',getenv('PATH'))
disp('Starting Blender...')
system( ['blender ', Directory, FileName, '.blend'] )
% Reassign old library paths
setenv('LD_LIBRARY_PATH',MatlabPath)
However, with the other way to start an application, you can immediately return to Matlab after starting it:
% Start Blender and immediately return to Matlab
!blender Geometry.blend &
The ampersand (&) is the key to immediately return to Matlab after starting the application , but starting Blender this way I cannot provide a variable FileName like I can do with system(...).
So, anybody got a clue on how to
use !program_name with a variable filename
or
use system(program_name) with an option such that Matlab just starts the application (and doesn't wait with returning until the application has been closed)

Just run command in MATLAB:
setenv('LD_LIBRARY_PATH',[getenv('PATH') getenv('LD_LIBRARY_PATH')])
It appends matlab library in system library.

You can actually clear out the LD_LIBRARY_PATH variable in your system call, like this:
system('LD_LIBRARY_PATH=; blender');
(Note that this most likely depends on the command syntax of the shell that's launched internally by MATLAB. The above should work for Bash).

Related

Launching Programs (example: Vim) from Haskell

Using the Turtle shell scripting library I am trying to launch a program, i.e:
shell "vim" empty
The problem is that this yields the warning Warning: Input is not from a terminal and causes Vim to lag for a few seconds before finally launching.
Questions:
Is shell the best Turtle function to launch an external program from haskell?
If so, is there any way to get around errors like the above?
You want to use functions from the process library, specifically createProcess or runProcess.
Relevant turtle thread on the issue here.
Example usage.
You could try manually setting up I/O to the vty. E.g. in bash: vim < $TTY > $TTY. I guess turtle is doing that with its own file descriptors under the hood, based on the warning, so you should be able to manually set up those redirects (or just use the command I gave via shell). You just need to make sure you've got a TTY environment var around.

How to get gdb on Linux to find source file for binary cross compiled on windows

I am trying to debug an application that is cross-compiled on a Windows host for a Linux target.
The problem:
Because the initial compilation is in windows the stored source file paths in the binary is of the form C:\Users\foo\project\.... On the Linux target I have put the source files under \home\foo\project\.... By default gdb does not find the source file because of the different path.
What I have tried so far:
Use "directory" command in gdb to give an exact path for the .c source file in the target Linux system where the app is being debugged. This works but unfortunately there are literally hundreds of files so this solution is unrealistic.
Use the set substitute-path C:\\Users\\foo\\project /home/foo/project command to have gdb substitute all prefixes. Note that the \\ seems necessary such that show substitute-path registers the right string. This unfortunately does not work. My guess is that the substitute-path command does not handle ms-dos style paths.
Tried separating the debug info out into a separate .debug file (see How to generate gcc debug symbol outside the build target?) and then using debugedit to change the paths with the command debugedit --base-dir=C:\Users\foo --dest-dir=/home/foo project.debug. Unfortunately this does not work either. debugedit seems to work fine if the existing path is all UNIX/Linux like but doesn't seem to work with ms-dos style paths.
I have looked around stackoverflow and while there are similar topics I can't find anything that will help me. Would really appreciate any suggestions/help. I realize that cross compiling from Windows is a very roundabout way but can't avoid that for the moment.
Thanks
Although it's rather old question, I did encountered the same problem. I managed to resolve it but using sed on binary executable... (yeah, a 'bit' hack-ish, but did not found another way). With sed I've managed to replace symbols paths right inside the executable, the trick is that new path's length should be the same as the old one.
sed -i "s#C:/srcpath#/srcpath/.#g" ./executable
Be sure to make new path the same length, otherwise the executable will brake.
I also have this same problem. Your option 1 isn't as bad as you think because you can script creating all the 'directory' commands with something like this python code:
def get_directory_paths():
return_array = list()
unix_path = os.path.join('my','unix','path')
for root, dirs, files in os.walk(unix_path):
for dir in dirs:
full_unix_path = os.path.join(root,dir)
escaped_unix_path = re.sub("\s", "\\\\ ", full_unix_path)
return_array.insert(0, "directory " + escaped_unix_path)
return '\n'.join(return_array)
The downside is that if you have two source files with the same name in different directories, I don't think gcc can pick the right one. That worries me, but in my particular situation, I think I'm safe.
For option 2 (which I suspect would fix the aliasing condition from #1), I think the problem is that the substitutions are not ending with a "file separator" according to the linux so they aren't applied:
To avoid unexpected substitution results, a rule is applied only if the from part of the directory name ends at a directory separator. For instance, a rule substituting /usr/source into /mnt/cross will be applied to /usr/source/foo-1.0 but not to /usr/sourceware/foo-2.0. And because the substitution is applied only at the beginning of the directory name, this rule will not be applied to /root/usr/source/baz.c either." (from https://sourceware.org/gdb/current/onlinedocs/gdb/Source-Path.html#index-set-substitute_002dpath )
I haven't tried anything like your #3 and I also considered something like #dragn suggestion, but in my situation the paths are not even close to the same length, so that will be an issue.
I think I'm stuck with #1 and a script, but if anyone has other suggestions, I'm interested options :-)

Linux function name conflict MATLAB

I'm currently using a MATLAB software suite which includes a function called "Swap". Running this code on my personal machine runs just fine, but when attempting to run on a Linux server, it seems to be trying to use the built-in "Swap" function on the Linux terminal.
Is there some way that I can force the terminal to ignore this built-in Swap and simply call the "Swap" function which is part of the MATLAB suite?
Thanks!
Assumptions: When you said built-in "Swap" function on the Linux terminal, I am assuming you are talking about running MATLAB on the linux terminal itself. I am also assuming that the built-in swap command is something from the MATLAB platform and not the linux environment and this answer is based on these assumptions.
In a general case, when you would like to add a function file whose name is identical to an already exisiting function, you have to move the path of the function file to be added to somewhere above the path of the existing function file in the list of MATLAB search paths. The way it works is that when you mention the use of a function, MATLAB starts looking for a match from the top until the bottom of the list.
One can view the MATLAB search paths by running -
path
So, to answer your question, just add the path of the suite to the top of MATLAB search paths by using addpath -
addpath(PATH_TO_SUITE);
If PATH_TO_SUITE has subdirectories, one of which has the swap function file, use genpath along with addpath -
addpath(genpath(PATH_TO_SUITE));
This could be interesting too for you to follow - Access m-files in a subfolder without permanently adding it to the path.

File script searching for versioning

I need to search through all sub directories of a directory and find all files containing a "VERSION" string including a number.
I need to increment this number, so 1.1.2 will be incremented to 1.1.3 etc. and save it in the file again.
I need to run this on Windows machines only, if it makes any difference.
Can I do this with cmd commands or do I need to use a program for this ?
I would like to run this without installing anything if possible.
I ended up writing a Java program to go through the entire structure.
I found that using CMD commands was too complicated for me to structure, and using a Java program I could also easily reuse parts of the program in different but similar structures elsewhere in my file system.
The CMD usage could my the files for me, but extract a single line, manipulating it and putting it back inside the file was not easy using CMD commands, where as using Java was much easier.

Getting linux terminal value from my application

I am developing a Qt application in Linux. I wanted to pass Linux commands to a terminal. That worked but now i also want to get a response from the terminal for this specific command.
For example,
ls -a
As you know this command lists the directories and files of the current working directory. I now want to pass the returned values from the ls call to my application. What is a correct way to do this?
QProcess is the qt class that will let you spawn a process and read the result. There's an example of usage for reading the result of a command on that page.
popen() , api of linux systerm , return FILE * that you can read it like a file descriptor, may help youp erhaps。
Parsing ls(1) output is dangerous -- make a few files with funny names in a directory and test it out:
touch "one file"
touch "`printf "\x0a\x0a\x0ahello\x0a world"`"
That creates two files in the current working directory. I expect your attempts to parse ls(1) output won't work. This might be alright if you're showing the results to a human, (though a human will be immensely confused if a filename includes output that looks just like ls(1) output!) but if you're trying to present something like an explorer.exe or Finder.app representation of files in the filesystem, this is horribly broken.
Instead, use opendir(3), readdir(3), and closedir(3) to read directory entries yourself. This will be safer, more portable, and (as a side benefit) slightly better performing.

Resources