Missing something in the linux terminal after launching matlab from the command line - linux

I'm having a weird behaviour when launching matlab from the command line in linux.
I've a bash script in linux that execute a function in matlab from the command line and does other operations with custom functions written in C++ as follows:
#!/bin/bash
# prepare input data just to be sure it has not been written by other test!
matlab2011a -nodesktop -nosplash -r "prepare_data_matlab( 'A' ); quit"
# launch C++ program
...
# prepare more data
matlab2011a -nodesktop -nosplash -r "prepare_data_matlab( 'B' ); quit"
When the script is finished I can not see what I'm writing in the terminal, although the commands have effects. I need to reset the terminal.
The fact is that everything works fine if I only launch matlab with the prepare_data_matlab( 'A' ) but the problem comes when I execute the function with option prepare_data_matlab( 'B' ).
I have commented line by line and found that the problem is with option B that call the function
dlmwrite(file_name, B, ' ');
which is not used in prepare_data_matlab( 'A' ).
So, how should I execute the matlab from the command line to avoid this behaviour? Is there a known bug with the dlmwrite() function?
I'm using Ubuntu 12.04 64 bits, GNU bash, versiĆ³n 4.2.24(1)-release (x86_64-pc-linux-gnu) and matlab2011a.
EDITED: The output generated for prepare_data_matlab( 'A' ) is
The output generated for prepare_data_matlab( 'B' ) is
EDITED: file_name is created as strcat(path_to_data,f); where path_to_data = /tmp/ and f = data_out.txt. Matrix B is not displayed before or after.
The only output to the terminal before or after the MATLAB script is generated from the bash script as follow:
echo "#### SELECT DATA FROM WORKSPACE ####"
matlab2011a -nodesktop -nosplash -r "prepare_data_matlab( 'B' ); quit";
echo "#### Process Data as input in a C++ programs ####"
The MATLAB function select data from the workscape and save it to disk as follows:
function [ ] = prepare_data_matlab( type )
if strcmp(type,'A')
% load data from workscape
load ('workspace_with_my_arrays.mat', 'A');
% save data as a standalone variable
save('/tmp/A.mat', 'A');
elseif strcmp(type,'B')
% load data from workscape
load ('workspace_with_my_arrays.mat', 'B');
path_to_data = '/tmp/';
f = 'data_out.txt';
file_name = strcat(path_to_data,f);
% save data as a txt file
dlmwrite(file_name, B, ' ');
end
end
EDITED: whos -file workspace_with_my_arrays.mat
Name Size Bytes Class Attributes
A 610x340x103 170897600 double
B 610x340x103 170897600 double
P 610x340 1659200 double
t1 38855x100 31084000 double
t2 3921x2x100 6273600 double
There are more arrays in the workspace but those are which I load.
The prepare_data_matlab function is the same as posted above but with an argument error checking as follow:
%% Load data from file
% Data is saved in a MATLAB variable or in TXT
if nargin ~= 1
error('Use: prepare_data_matlab( [ A | B ] )')
end
and the following command:
cd /data/matlab;
which is executed after the arguments error check in both cases (option Aand option B), that is, before the if statement.

The problem is not with dlmwrite. This seems to be a bug in some versions of MATLAB, as reported in this link.
The proposed solution (if you have a buggy version of MATLAB) is to use nohup:
nohup matlab -nodesktop -nosplash -r ...........
UPDATE:
Per #Amro 's suggestion, #pQB reported the problem to MathWorks Support. Their response was:
The problem is a known issue in versions prior to R2012a. Run MATLAB under a different shell. For example, neither tcsh or zsh have this issue.
OLD answer:
The problem is not with dlmwrite, but with the content of your matrix. Furthermore, unless file_name points to stdout (e.g., file_name='/dev/stdout';), the dlmwrite function will not write anything to screen and will not mess your terminal. Either file_name points to stdout or you are displaying the matrix B right before (or after) the dlmwrite call.
In any case, the problem is with the contents of your matrix B (see the strange characters in your output). You need to fix the problem with your matrix B. Perhaps the method you are using to read its input data is faulty.

If you want to ignore output from MATLAB (like the banner printed at the beginning), launch the process and redirect both the standard input and error to /dev/null device:
#!/bin/sh
echo '### running MATLAB ###'
matlab -nodesktop -nosplash -r "..." > /dev/null 2>&1
echo '### done ###'
./other_script.sh
matlab -nodesktop -nosplash -r "..." > /dev/null 2>&1
Note that you should be careful since MATLAB process returns immediately possibly before it has finished running, which could cause problems if your next program depends on files produced by MATLAB. See here for a possible solution.

Related

How to make a .m file read an input csv file passed as a parameter?

I am new in Matlab and facing difficulty in making a .m file read the input csv file that I am passing as an argument from the command prompt. I understand that a function has to be written to read the input file as a parameter. Here is the code I wrote inside the .m file to accept the input file:
function data=input(filename);
addpath(genpath('./matlab_and_R_scripts'));
tic
D=csvread(filename,1,1);
I want the filename passed as an argument to be read by the function "csvread" and save it in D. I am using the following command to execute the script:
matlab -nodisplay -nosplash -nodesktop -r "input 'exp2_1_DMatrix.csv';run('matlab_filename.m');exit;"
I am able to execute the script without any errors but it is not reading the input file as the downstream analysis should have saved a new file if it was able to read the file and execute some functions on it.
Can anyone please suggest how to read the input file in my matlab script and the proper command to pass?
Try using this function. Take care on not using reserved names:
readdat.m
function data=readdat(filename);
addpath(genpath('./matlab_and_R_scripts'));
tic;
data=csvread(filename,1,1);
toc;
For testing, you can execute this function directly in the Command Window and editing in the Matlab Editor, which is where most functions, most of the time, are tested until you are fully satisfied with your processing.
>> data=readdat(filename);
Looking at data you can realize if the file was or not read as it should.
>> data(:,1)
You can keep running other scripts, such as matlab_filename.m. But the best choice is having a function working with everything:
processdat.m
function data=processdat(filename)
% Original Function
addpath(genpath('./matlab_and_R_scripts'));
tic;
data=csvread(filename,1,1);
toc;
% Paste in here all the matlab_filename.m code, or do a call:
matlab_filename;
% Do not uncomment this exit in here, since you want to keep working until the function do what you need
% exit;
Later, if you want some serious automation and want some programming tasks having repetitions of your code under some schedule, you can of course arrange a Windows bat command, and in this case, you can uncomment that exit; terminator at the end of processdat.m.
processdat.bat
matlab -nodisplay -nosplash -nodesktop -r processdat
Remember to ensure the OS can access matlab, and that Matlab can access processdat. If in doubt, place the proper paths:
processdat.bat
c\programs\bin\matlab -nodisplay -nosplash -nodesktop -r c\files\processdat.m
I solved the problem by gaining some insight from #Brethlosze's answer. If you want to avoid a local function then function shouldn't have a name but start with an []. Here is what I did to pass an input argument in my myScript.m script:
function [] = myScript(input_file, output_file)
addpath(genpath('../matlab_and_R_scripts'));
tic
D=csvread(input_file,1,1);
% Some code operations
save(output_file,'save_what_you_want')
toc
end
And I executed the script from command line using the following command:
matlab -nodisplay -nosplash -nodesktop -r "myScript 'example.csv' 'example.mat'"
The input_file is 'example.csv' and output_file is 'example.mat'.

BASH - Is there a way to save output of a command to a file with the source formatting?

So to put it less confusing:
I run a command which prints some formatted values in the bash e.g.:
NodeID (lot of whitespace) Heap_size (again) Time
And when i try to save the output with Name:~$ script > file.txt, the output is:
ESC[93mnode_s1aESC[0m^MESC[25C1.0g
Expected output:
node_s1a 1.0g ...
node_s2aaaaa 2.0g ...
Is there a way to save raw output with the formatting into a text file ?
You can use the printf command which is like the printf function in C or Java.
printf "%-20s%s" Name:~$ script >> test.txt
I'm assuming Name:~$ and script are variables because I've never seen them before.

How do you append a string built with interpolation of vars and STDIN to a file?

Can someone fix this for me.
It should copy a version log file to backup after moving to a repo directory
Then it automatically appends line given as input to the log file with some formatting.
That's it.
Assume existence of log file and test directory.
#!/bin/bash
cd ~/Git/test
cp versionlog.MD .versionlog.MD.old
LOGDATE="$(date --utc +%m-%d-%Y)"
read -p "MSG > " VHMSG |
VHENTRY="- **${LOGDATE}** | ${VHMSG}"
cat ${VHENTRY} >> versionlog.MD
shell output
virufac#box:~/Git/test$ ~/.logvh.sh
MSG > testing script
EOF
EOL]
EOL
e
E
CTRL + C to get out of stuck in reading lines of input
virufac#box:~/Git/test$ cat versionlog.MD
directly outputs the markdown
# Version Log
## version 0.0.1 established 01-22-2020
*Working Towards Working Mission 1 Demo in 0.1 *
- **01-22-2020** | discovered faker.Faker and deprecated old namelessgen
EOF
EOL]
EOL
e
E
I finally got it to save the damned input lines to the file instead of just echoing the command I wanted to enter on the screen and not executing it. But... why isn't it adding the lines built from the VHENTRY variable... and why doesn't it stop reading after one line sometimes and this time not. You could see I was trying to do something to tell it to stop reading the input.
After some realizing a thing I had done in the script was by accident... I tried to fix it and saw that the | at the end of the read command was seemingly the only reason the script did any of what it did save to the file in the first place.
I would have done this in python3 if I had know this script wouldn't be the simplest thing I had ever done. Now I just have to know how you do it after all the time spent on it so that I can remember never to think a shell script will save time again.
Use printf to write a string to a file. cat tries to read from a file named in the argument list. And when the argument is - it means to read from standard input until EOF. So your script is hanging because it's waiting for you to type all the input.
Don't put quotes around the path when it starts with ~, as the quotes make it a literal instead of expanding to the home directory.
Get rid of | at the end of the read line. read doesn't write anything to stdout, so there's nothing to pipe to the following command.
There isn't really any need for the VHENTRY variable, you can do that formatting in the printf argument.
#!/bin/bash
cd ~/Git/test
cp versionlog.MD .versionlog.MD.old
LOGDATE="$(date --utc +%m-%d-%Y)"
read -p "MSG > " VHMSG
printf -- '- **%s** | %s\n' "${LOGDATE}" "$VHMSG" >> versionlog.MD

Shell Script code yields same output on update input

I have written script to add pattern of directories in exclude-list of Deja-Dup (backup softaware). Even I have updated values for gsettings get org.gnome.DejaDup include-list and tested on terminal that it gives desired output, my code is producing same output which was to old input.
I have tried running clear and reset on terminal but it did not helped.
y=$(gsettings get org.gnome.DejaDup include-list)
# Code to show included directory
ILS="" read -ra "x" <<<y
declare p INCLUDE_LIST
for y in ${x[#]}
do
cat $y
done

Executable octave script: 'usr/local/bin/octave: invalid option -- '

I am trying to write an Octave script that I can run as an executable.
I am using octave version 3.6.0. I am running the following script downloaded form here:
#!/usr/local/bin/octave -qf
# An example Octave script
len = input( "What size array do you wish to use for the evaluation: " );
clear a;
tic();
for i=1:len
a(i) = i;
endfor
time1 = toc();
a = [1];
tic();
for i=2:len
a = [a i];
endfor
time2 = toc();
a=zeros( len, 1 );
tic();
for i=1:len
a(i) = i;
endfor
time3 = toc();
printf( "The time taken for method 1 was %.4f seconds\n", time1 );
printf( "The time taken for method 2 was %.4f seconds\n", time2 );
printf( "The time taken for method 3 was %.4f seconds\n", time3 );
However when I run the script on the command line, I get the following error:
'usr/local/bin/octave: invalid option -- '
However, when I type the same command at the command line:
/usr/local/bin/octave -qf
I get the octave command prompt. What am I doing wrong?
I assume you're on some sort of Unix/Linux system. Is the file in "DOS" format, with DOS-style line endings? This could cause problems with how the command is interpreted.
Your shebang line (which, btw, has a space it shouldn't) is calling /usr/local/bin/octave, but the error is coming from /usr/bin/octave. Is that a mistake? If so, you need to copy-and-paste code and errors for things like that. If not, the local version may be a script that calls the binary with an incorrect option when run non-interactively. In particular, it looks like the script (or something, at least) is trying to use a long option (--option), and the binary doesn't support it (so it's interpreting it as a short option).
Firstly the posted script runs fine on my system.
I type nano test.sh, I copy it to the file, I change the first line to be #!/usr/bin/octave -qf.
I press Ctrl-O and Ctrl-X.
I then make the script executable using chmod +x test.sh.
I then run the script using ./test.sh or octave -qf test.sh and it works as expected.
Notes:
Octave on my system is
$ which octave
/usr/bin/octave
$ file /usr/bin/octave
/usr/bin/octave: symbolic link to `octave-3.6.1'
$file /usr/bin/octave-3.6.1
/usr/bin/octave-3.6.1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x061b0a703928fc22af5ca93ee78346a7f5a0e481, stripped
And on my system /usr/bin and /usr/local/bin are in $PATH
The only way I can generate the error you mention is by changing the first line of the script to
#!/usr/bin/octave - - or #!/usr/bin/octave -q -f.
This gives
$ ./test.sh
/usr/bin/octave: invalid option -- ' '
This means that in the script on your machine the shebang line is incorrect or is being interpreted incorrectly.
Verify that the first line is correct in the script.
Also identify what happens if the line is changed to #!/usr/local/bin/octave -q or to #!/usr/local/bin/octave -f.
For more information on the parsing of shebang line see :
The #! magic, details about the shebang/hash-bang mechanism on various Unix flavours.
how to use multiple arguments with a shebang (i.e. #!)?
Bug in #! processing - One More Time

Resources