How to call command program in MATLAB - c++

In MATLAB it is possible to call command programs written in C or C++. For example, I can use the following command to call a command program in Windows:
system('program.exe -i input_file1.txt -o output_file1.txt -m 1 ');
By doing so, I can invoke command line program directly from MATLAB. The problem I have now is that all the arguments must be fixed when I use the system function. If one argument, for example, is changeable, then using system function will fail. For instance,
for i=1:3
input_file_name = [num2str(i),'.txt'];
system('program.exe -i input_file_name -o output_file1.txt -m 1 ');
end
Then, how can I deal with this situation? Thanks.

You need to change your syntax slightly:
for i=1:3
input_file_name = [num2str(i),'.txt'];
system(['program.exe -i ' input_file_name ' -o output_file1.txt -m 1 ']);
end
input_file_name is the name of your variable in MATLAB so you can write verbatim in the string you pass to the system command.

More generally you can use sprintf to construct strings to pass to system, for example something like:
for n=1:3
system(sprintf('program.exe -i %d.txt -o output%d.txt -m 1',n,n));
end
(avoid using i and j as variables in MATLAB)

Related

/bin/sh: 1: Syntax error: "(" unexpected after running Makefile [duplicate]

I often find Bash syntax very helpful, e.g. process substitution like in diff <(sort file1) <(sort file2).
Is it possible to use such Bash commands in a Makefile? I'm thinking of something like this:
file-differences:
diff <(sort file1) <(sort file2) > $#
In my GNU Make 3.80 this will give an error since it uses the shell instead of bash to execute the commands.
From the GNU Make documentation,
5.3.2 Choosing the Shell
------------------------
The program used as the shell is taken from the variable `SHELL'. If
this variable is not set in your makefile, the program `/bin/sh' is
used as the shell.
So put SHELL := /bin/bash at the top of your makefile, and you should be good to go.
BTW: You can also do this for one target, at least for GNU Make. Each target can have its own variable assignments, like this:
all: a b
a:
#echo "a is $$0"
b: SHELL:=/bin/bash # HERE: this is setting the shell for b only
b:
#echo "b is $$0"
That'll print:
a is /bin/sh
b is /bin/bash
See "Target-specific Variable Values" in the documentation for more details. That line can go anywhere in the Makefile, it doesn't have to be immediately before the target.
You can call bash directly, use the -c flag:
bash -c "diff <(sort file1) <(sort file2) > $#"
Of course, you may not be able to redirect to the variable $#, but when I tried to do this, I got -bash: $#: ambiguous redirect as an error message, so you may want to look into that before you get too into this (though I'm using bash 3.2.something, so maybe yours works differently).
One way that also works is putting it this way in the first line of the your target:
your-target: $(eval SHELL:=/bin/bash)
#echo "here shell is $$0"
If portability is important you may not want to depend on a specific shell in your Makefile. Not all environments have bash available.
You can call bash directly within your Makefile instead of using the default shell:
bash -c "ls -al"
instead of:
ls -al
There is a way to do this without explicitly setting your SHELL variable to point to bash. This can be useful if you have many makefiles since SHELL isn't inherited by subsequent makefiles or taken from the environment. You also need to be sure that anyone who compiles your code configures their system this way.
If you run sudo dpkg-reconfigure dash and answer 'no' to the prompt, your system will not use dash as the default shell. It will then point to bash (at least in Ubuntu). Note that using dash as your system shell is a bit more efficient though.
It's not a direct answer to the question, makeit is limited Makefile replacement with bash syntax and it can be useful in some cases (I'm the author)
rules can be defined as bash-functions
auto-completion feature
Basic idea is to have while loop in the end of the script:
while [ $# != 0 ]; do
if [ "$(type -t $1)" == 'function' ]; then
$1
else
exit 1
fi
shift
done
https://asciinema.org/a/435159

What shell does std::system use?

TL;DR; I guess the shell that std::system use, is sh. But, I'm not sure.
I tried to print the shell, using this code: std::system("echo $SHELL"), and the output was /bin/bash. It was weird for me. So, I wanted to see, what happens if I do that in sh? And, the same output: /bin/bash. Also, if I use a command like SHELL="/usr/bin/something", to set the SHELL variable to another string, it will print the new string that I set to it (/usr/bin/something), and it looks it's not a good way to see what shell it's using. Then, I tried to check it, using the ps command, and the output was: bash, a.out, ps. It was weird to see bash in this list. So, I created a custom shell, and change the shell in gnome-terminal to it:
#include <iostream>
int main()
{
std::string input;
while (true)
{
std::string command;
std::getline(std::cin, command);
std::system(command.c_str());
}
}
Now, it's easier to test, and I think, the results is better.
Then, I tried to test the ps command again, but in the custom shell, and the results was: test_shell, ps.
It was weird again. How the shell isn't sh, nor bash? And, the final test I did was: echo $0. And, the results was sh, in both custom shell, and normal program.
Edit
It seems like /bin/sh is linked to /bin/bash (ll /bin/sh command's output is /bin/sh -> bash), and actually, it seems like the only difference between sh and bash is filename, and the files's contents are the same. I checked the difference between these files with diff command too:
$ xxd /bin/sh > sh
$ xxd /bin/bash > bash
$ diff sh bash
(+ Yes, $SHELL doesn't means the running shell (I didn't know that when I was testing, and I just wanted to see what happens))
The GNU sources (https://github.com/lattera/glibc/blob/master/sysdeps/posix/system.c) say
/bin/sh
So, whatever /bin/sh is hardlinked to is the shell invoked by std::system() on Linux.
(This is correct, as /bin/sh is expected to be linked to a sane shell capable of doing things with the system.)
According to cppreference.com, std::system
calls the host environment's command processor (e.g. /bin/sh, cmd.exe, command.com)
This means the shell used will depend on the operating system.
On any POSIX OS (including Linux), the shell used by std::system is /bin/sh. (Though as the OP points out, /bin/sh could be a symlink to another shell.)
As for the SHELL environment variable, as has been pointed out in the comments, this environment variable cannot be used to reliably identify the running shell program. SHELL is defined by POSIX to
represent a pathname of the user's preferred command language interpreter
(source)

How to trim last four character from the input in bash shell?

I intend to automate compile and run process in C++, I wrote the following code as compile-run.sh
#! /bin/bash
clang++ $1.cpp -o $1.out && ./$1.out
I put this compile-run.sh in /usr/local/bin for global usage,
and when I type the command compile-run.sh XXX.cpp, it intend to compile and run the specified cpp file. But the problem now is I have to manually removed ".cpp" in the command.
Is there any way to trim the last X number of character and assign to a variable in general?
Is there any way to trim the .cpp and apply trimmed $1 in the code?
Is there better way to automate compile and run process?
well, an ugly way could be by using something like:
#! /bin/bash
filename=$1
temp="${filename%%.cpp}"
clang++ $temp.cpp -o $temp.out && ./$temp.out
another way, if you want to trim the last 4 characters whatever the last part is:
#! /bin/bash
filename=$1
temp="${filename::-4}"
clang++ $temp.cpp -o $temp.out && ./$temp.out
but for substrings you could also use cut: ie. https://stackabuse.com/substrings-in-bash/

Running C++ program from ruby

How can you run a C++ program from a Ruby script?
Suppose that the Ruby script generates a file, called "hello.txt" and I want to run a C++ program to take the hello.txt file, work with it and write another file, called "result.txt" and the Ruby script continues to read the result.txt file.
For example, in the Linux shell I wrote g++ hello.c -c hello -o hello to receive the "result.txt" file.
Is there is a way that I can run the shell code from a Ruby program?
You can use system like other people said, however you should also check the exit value to verify the success or failure.
r = system("g++ hello.c -c hello -o hello") #=> r = true if success, nil if failed
You can use system :
system("./hello file.txt")
I find that backticks are more succinct than system.
You can trigger the C++ program by shelling out as follows:
`./hello file.txt`
Can you clarify whether you need to read results.txt from the current directory?
If so, you could use something like contents = IO::readlines './results.txt'

C++ program parsing arguments

I want to make a program to be called from the command line like this:
myprogram.exe -F/-T FILE/TEXT -W FILE.WAV -P FILE.PHO -A
They are 3 parts:
myprogram.exe
-F OR -T and the File or text
-W FILE -P FILE and -A (At least one, up to 3, in any order (or not, if it's complicated))
So it can be:
myprogram.exe -T "Text Text, test text" -A
or:
myprogram.exe -F FILENAME -A
or:
myprogram.exe -F FILENAME -P FILENAME -W FILENAME
etc.
-A is one function (needs the text or the file)
-W writes a WAV file with the info from the text/file
-P does something similar to -W
What is the best way to handle it? Analyzing argv[x] one by one, and deciding with ifs? Something easier?
I am new to programming and using VS2008.
You can parse them manually or use Boost.Program_options.
Analyizing argv[x] one by one
That's what I would do. Maybe maintain a counter of the current element ...
unsigned int cur = 0;
if (argc <= 1) {
.. error
}
if (!strncmp(argv[cur],"-T",2)) {
.. process
++cur;
}
...
for (;cur < argc;++cur) {
if (!strncmp(argv[cur],"-F",2)) {
.. process
}
else if ...
}
There are some command line parers out there. Unix has getopt, for example.
I'd use getopt if you can: it's simple enough. It'll handle combined options too (like in ls -lt instead of ls -l -t) and it handles options with arguments as well, and the order in which they appear also doesn't matter. All this makes it "standard" to people used to command line arguments (normally order of options is irrelevant, except when giving contradictory options...).
this is already done by others, so I wouldn't spend all your time on it if I were you.
Look at Boost's ProgramOptions for example.