bash 如何在bash脚本中从matlab获取返回值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10085184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the return value from matlab in bash script?
提问by Jessada Thutkawkorapin
If I have this matlab function
如果我有这个 matlab 函数
function [result] = matlab_test(param1, param2)
disp(sprintf('param1 : %s', param1));
disp(sprintf('param2 : %s', param2));
result = 'hello matlab';
And I want to call this matlab function in bash script like
我想在 bash 脚本中调用这个 matlab 函数,比如
matlab -nodesktop -nosplash -nodisplay -r "try, A=matlab_test('test','matlab'); end; quit"
echo $A
And I want this output
我想要这个输出
test
matlab
hello matlab
My requirement here is to find if it is possible to use the return value from Matlab in my bash script and also to pass it through the pipeline. I only want to make my application separated into small components (files) and communicate through pipeline/params. In short, I want to see how far I can wrap Matlab script in my bash script so that I can set my code architecture.
If I cannot do this, I'll simply bundle the part that I need the return value from matlab together into matlab script.
我的要求是找出是否可以在我的 bash 脚本中使用来自 Matlab 的返回值,并将其传递到管道中。我只想将我的应用程序分成小组件(文件)并通过管道/参数进行通信。简而言之,我想看看我可以在我的 bash 脚本中包装 Matlab 脚本多远,以便我可以设置我的代码架构。
如果我不能这样做,我将简单地将需要从 matlab 返回值的部分捆绑到 matlab 脚本中。
采纳答案by Sevenless
You're asking two questions. I'll answer both, including why the second one might be impossible depending on your operating system (and definitely impossible on mine), then offer a suggestion on a problem dependent workaround.
你问两个问题。我会回答这两个问题,包括为什么根据您的操作系统(而在我的绝对不可能),为什么第二个可能是不可能的,然后提供有关问题相关解决方法的建议。
First, I use a script like this when getting Matlab to interact with a shell.
首先,当让 Matlab 与 shell 交互时,我使用了这样的脚本。
#!/bin/sh
cat <<EOF | matlab -nodesktop -nosplash -nodisplay
A=matlab_test('','');
system(['export temp1=' A]); %doesn't work
setenv('temp2',A); %also doesn't work, I'll explain why below
exit
EOF
echo $temp1
echo $temp2
gives output:
给出输出:
[XXXXXX@compute-0-138 ~]$ ./stack_ex test matlab
Warning: No window system found. Java option 'MWT' ignored
< M A T L A B (R) >
Copyright 1984-2010 The MathWorks, Inc.
Version 7.12.0.635 (R2011a) 64-bit (glnxa64)
March 18, 2011
To get started, type one of these: helpwin, helpdesk, or demo.
For product information, visit www.mathworks.com.
>> param1 : test
param2 : matlab
>> >> >>
So clearly the two versions of setting environment variables doesn't work. This leads us to your second question.
所以很明显,设置环境变量的两个版本都不起作用。这就引出了你的第二个问题。
The reason behind the failure to 'echo' is that both systemand setenvcreate shells that are closed when Matlab is closed. That is to say, Matlab cannot set environment variables outside the shell that called it.
'echo' 失败背后的原因是,当 Matlab 关闭时,system和 都setenv创建了关闭的壳。也就是说,Matlab 不能在调用它的 shell 之外设置环境变量。
There's a workaround for this for Windows systems discussed in this posting, that uses a tool from Microsoft. Also mentioned here.
对于这篇文章中讨论的 Windows 系统,有一个解决方法,它使用 Microsoft 的工具。这里也提到了。
I don't believe there's a workaround for *nix systems to set environment variables from within Matlab.
我认为 *nix 系统没有解决方法可以从 Matlab 中设置环境变量。
Here's a method to do something similar to what you described.
这是一种执行类似于您所描述的操作的方法。
I'm assuming the use of echo is not what you actually want to do. Rather, I'm guessing that you'd like to use the string output stored in the environment variable to be used in further work with commands or scripts in the shell. One possible workaround would be the following:
我假设使用 echo 不是您真正想要做的。相反,我猜测您希望使用存储在环境变量中的字符串输出来进一步处理 shell 中的命令或脚本。一种可能的解决方法如下:
#!/bin/sh
cat <<EOF | matlab -nodesktop -nosplash -nodisplay
A=matlab_test('','');
setenv('temp1',A); %doesn't work
[a b] = system(['echo ' '$' 'temp1'])
exit
EOF
Giving output: [XXXXXX@compute-0-138 ~]$ ./stack_ex_3 test matlab Warning: No window system found. Java option 'MWT' ignored
给出输出: [XXXXXX@compute-0-138 ~]$ ./stack_ex_3 test matlab 警告:未找到窗口系统。忽略 Java 选项“MWT”
< M A T L A B (R) >
Copyright 1984-2010 The MathWorks, Inc.
Version 7.12.0.635 (R2011a) 64-bit (glnxa64)
March 18, 2011
To get started, type one of these: helpwin, helpdesk, or demo.
For product information, visit www.mathworks.com.
>> param1 : test
param2 : matlab
>> >>
a =
0
b =
hello matlab
This shows that the command echo $temp1was evaluated in the subshell created by setenvand temp1 holds the value assigned to it. The result of this call to the shell is now stored in b (a holds 0 indicating success). It is conceivable that you could pass the whole of what you would like to do in the shell through the system command, so that it runs in the subshell. We would have to know more specifics of your problem to give a complete assessment of this approach though.
这表明该命令echo $temp1是在由创建的子 shell 中评估的,setenv并且 temp1 保存分配给它的值。对 shell 调用的结果现在存储在 b 中(a 保持 0 表示成功)。可以想象,您可以通过系统命令将您想在shell 中执行的全部操作传递给它,以便它在子shell 中运行。不过,我们必须了解您的问题的更多细节才能对这种方法进行全面评估。
Edits and followup **********************
编辑和跟进************************
The closest thing to wrapping Matlab and bash that I can think of is the following trick. You can pipe the output from the Matlab script to myresult.outwith the following:
我能想到的最接近包装 Matlab 和 bash 的是以下技巧。您可以将 Matlab 脚本的输出通过管道传输myresult.out到以下内容:
#!/bin/sh
cat <<EOF | matlab -nodesktop -nosplash -nodisplay /> myresult.out
A=matlab_test('','');
disp(['grepMe ' A])
exit
EOF
You can grep the grepMeline from myresult.out, pipe to sed, and select only the part of the output line you need, then pipe that on the the rest of your script. That's as close as I think you can get to what you're trying to do.
您可以 grepgrepMe从myresult.out, pipe 到 sed 的行,并仅选择您需要的输出行部分,然后在脚本的其余部分进行管道传输。这与我认为您可以实现的目标非常接近。
回答by Sevenless
Been thinking about this over the last few days and just thought of something. You can use one of the MATLAB clones as a #! script interpreter. My choice in this is Octave, like so:
这几天一直在思考这个问题,只是想到了一些东西。您可以使用 MATLAB 克隆之一作为 #! 脚本解释器。我的选择是 Octave,如下所示:
#! /usr/bin/octave -qf
A=matlab_test('test','matlab');
printf(A)
printf puts the value of A into STDOUT and you can pipe from there.
printf 将 A 的值放入 STDOUT ,您可以从那里进行管道传输。
matteson@mauler[~]$ ./oshelltest
param1 : test
param2 : matlab
hello matlab
matteson@mauler[~]$ ./oshelltest | grep hello
hello matlab
Now Octave isn't exactlythe same as MATLAB, but it's close, maybe enough for your needs. It also has the advantage of being free.
现在 Octave与 MATLAB并不完全相同,但它很接近,也许足以满足您的需求。它还具有免费的优点。
回答by Richante
There are two things you're trying to do here. Firstly: display the output of a Matlab program in a shell. Secondly, assign a variable in the shell.
您在这里尝试做两件事。首先:在shell中显示Matlab程序的输出。其次,在shell中分配一个变量。
When I tried this, I found that Matlab would write all over stdout with its opening message, so I ended up doing:
当我尝试这个时,我发现 Matlab 会在整个 stdout 上写上它的开始消息,所以我最终做了:
mkfifo ~/matlab_output
matlab ... > /dev/null & cat ~/matlab_output
and then inside matlab, replacing sprintfwith:
然后在 matlab 中,替换sprintf为:
f = fopen('~/matlab_output', 'w');
fprintf(f, 'param1 : %s', param1);
fclose(f);
That is one solution to your first requirement (you could just write to a normal file and then cat the file afterwards, but you'd have to used &&for that, so you wouldn't see the output until Matlab was completely finished.). The second issue you have - doing "A = result" in matlab and being able to "echo $A" in the shell - is harder. You could do something like:
这是您的第一个要求的一个解决方案(您可以只写入一个普通文件,然后在之后 cat 文件,但您必须使用&&它,因此在 Matlab 完全完成之前您不会看到输出。)。您遇到的第二个问题 - 在 matlab 中执行“A = result”并能够在 shell 中“echo $A” - 更难。你可以这样做:
mkfifo ~/matlab_commands
mkfifo ~/matlab_output
matlab ... > /dev/null & cat ~/matlab_output & eval $(cat ~/matlab_commands)
and in matlab:
在 matlab 中:
f2 = fopen('~/matlab_commands', 'w');
fprintf(f2, 'A=%s', double2str(results));
fclose(f2);
but I don't really know how well this would work.
但我真的不知道这会有多好。

