1

I want to run matlab using bash which requires the a command like matlab -nodesktop -nosplash -r "functionmat(var1,var2)" to be called. For example, I can run matlab -nodesktop -nosplash -r "functionmat(5,4)" and if this is a valid input it works and creates some files and does whatever the mfile has inside it.

But I want the variables to be inputs the user gets asked, thus it varies every run without the user needing to change the script. The user just enters different inputs when asked.

This does not work (nothing happens):

#!/bin/bash
echo "Please variables 1 and 2:"
read var1 var2

matlab -nodesktop -nosplash -r "functionmat($var1,$var2)"

Calling matlab like this does not work either (says this is an error since it probably is reading string type inputs when there supposed to be numbers):

matlab -nodesktop -nosplash -r "functionmat('$var1','$var2')"

This does not work either (nothings happens -- no files created):

sect1="\""
sect2="functionmat("
sect3=","
sect4=")"
sect5="\""

matlab -nodesktop -nosplash -r "$sect1$sect2$var1$sect3$var2$sect4$sect5"

Does any one no how to make it work?

3
  • what's the actual error message from matlab in the first version of your script? as roiama says, that should work - if the syntax is correct for functionmat() in matlab. Is functionmat a built-in in matlab, or is it defined in a script file somewhere (you don't seem to be running a script file)?
    – cas
    Oct 24 '15 at 22:17
  • The functionmat inputs are numbers, if I run the first one nothing happens, nothing runs in matlab. The matfile which functionmat is in, is supposed to create some txt files but nothing happens. There no error message just nothing.
    – HJY
    Oct 25 '15 at 0:33
  • 1
    The thing you are missing is that this is a matlab problem, not a shell scripting problem. The shell script is doing what you want, correctly passing var1 and var2 to your matlab script...so stop wasting your time trying to find a non-existant fault with your shell script and start thinking about why matlab is not doing what you want it to.
    – cas
    Oct 25 '15 at 1:41
3

Your first suggestion should work correctly. I suppose the only variant is to check that you're entering the variables correctly (space separated, not comma separated). You can demonstrate that the code is correct by modifying it slightly to print the values of the two variables and to print the matlab command rather than execute it:

#!/bin/bash
echo "Please variables 1 and 2:"
read var1 var2
echo "var1=$var1, var2=$var2."
echo matlab -nodesktop -nosplash -r "functionmat($var1,$var2)"
5
  • Ive checked and it does not work like that
    – HJY
    Oct 24 '15 at 23:31
  • @HUY what doesn't work like what? Please clarify. Also, seeing the result of you running this code would be very helpful.
    – roaima
    Oct 25 '15 at 8:49
  • So I ran modifying the code to echo the variables and it did, but the Matlab function just does not run. The Matlab screen comes up in the terminal but the code is not running. No error message is given I know it does not run because some files have to be created and none due. i suspect the problem is that since the $var1 are between the quotation marks "" in the phrase "functionmat($var1,$var2)" bash is not recognizing them as numbers. I also tried declaring the variables using the suggestion from below and it does not work either.
    – HJY
    Oct 27 '15 at 14:06
  • @HJY the shell doesn't care about variable types. If the code you gave us works with "functionmat(1,2)" you can replace that with var1="1" var2="2" followed by "functionmat($var1,$var2)". If that doesn't work then there is something else happening that you haven't identified
    – roaima
    Oct 27 '15 at 15:09
  • So in the end I answered this myself :/ Oct 27 '15 at 17:13
1

Your first approach is almost right, and all you need is to make sure the variables are really legal Matlab syntax. The second one is wrong because in Matlab the input looks like func('1','5') — strings as arguments. The third one does nothing because the line "func(1,5)" is just a string literal. Replace matlab with printf '%s\n' to see what you are passing into it.

Input Verification

Using declare -i var1 var2 causes the variables to be recognized as integers, and on assignment bash assigns the result of evaluating the string-to-assign as a C-style expression (and complains about expression syntax errors). So doing so:

  • Makes you able to use expressions like 3*2 (eval'ed to 6 by shell)
  • Doesn't enable you to use decimals like 2.45.
  • Ensures the number passed is an integer.
    • A structure that looks like [[:alpha:]_][[:word:]]* will be recognized as a varname, which gets further evaluated and defaults to 0 if undefined.

When an error is thrown by read, the whole variable is still uninitialized. You can catch it like this:

declare -i var1 var2
until ((${#var1[@]} && ${#var2[@]})); do read -p "INPUT! NOW!" var1 var2; done

Custom Extended Globbing Patterns can be used if you want to deal with decimals too (and exclude the variable-processing part). Note that I am too lazy to consider expressions:

shopt -s extglob # bash 3, regex =~ is bash 4.
until [[ $var1 == +([0-9])?(.*([0-9])) && $var2 == +([0-9])?(.*([0-9])) ]]; do
    read -p "Please input.. " var1 var2
done

You can even go further to allowing some MATLAB variables you want to use, since in this way it's passed in raw strings.

read separator

Just add IFS+=, or anything else that you want it to be a valid separator before read.


This answer is complement to and possibly a combination of those two answers above. It was originally edits 113859 and 113860. Read the GNU Bash Manual chapters 3.5.3 (initialized check), 3.5.7 (IFS), 3.5.8.1 (pattern) and 4.2 (builtin: declare) for more info.

I don't have Matlab on my computer, so I used GNU Octave to check for the validity of my syntax checks. There are also online Octave services for anyone wants to try the syntax.

4
  • This is all interesting information but I don't see how it answers the question. Are you suggesting that @HJY was providing numeric expressions such as 3*2 in response to the read var1 var2 statement rather than natural integers such as 6? There's nothing in the question that even hints at this.
    – roaima
    Oct 27 '15 at 17:19
  • @roaima 2*3 gets evaluated by bash and becomes 6. foo(2*3) is not a problem in matlab either. Oct 27 '15 at 17:20
  • With shell integers yes. But where in the question does it say that @HJY was entering 2*3 in response to the read statement?
    – roaima
    Oct 27 '15 at 17:21
  • @roaima This is only a part of the comparison with the pattern-based checking method. I am actually answering the 'how to make sure you are giving the input you want' part. Oct 27 '15 at 17:24
0

Bash variables are treated as character strings if not typed. I would start by attempting to declare a type for your variables. Something like this,

declare -i var1

I'm not optimistic that this type declaration will be a resolution for you but its worth a shot.

If it doesn't work, why not change the parameters of your function to a character string instead of numeric values? Let your mfile handle the conversion to the numeric type of your choice.

References:

2
  • the inputs are numbers since it calculates stuff with does numbers...Ill see if the first suggestion works
    – HJY
    Oct 24 '15 at 23:33
  • declare -i also allows some other expressions, like foo that points to a variable and so on (and MATLAB won't accept it), but it doesn't allow floats which should definitely be supported in MATLAB. A manual =~ regex check should be better. Oct 25 '15 at 8:40
0

Ok, I found a way to run the program

  #!/bin/bash

    echo "Please enter variables 1 and 2:"
    read var1 var2

    declare -i var1
    declare -i var2

    mystring="matlab -nodesktop -nosplash -r \"functionmat($var1,$var2);exit\""
    eval $mystring

Thanks for all your help if you answered

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.