getting arguments of matlab when launched in background

Hi everybody,
I often run matlab in background (under linux and mac OS), using a command like
nohup matlab -nodesktop -nodisplay -nosplash < script.m &> output.txt &
For several reasons I'd like to access the name of the output file (here 'output.txt') from inside the script (here 'script.m'). I found out that I can access the PID of the job through the undocumented function 'feature', but so far I did not find a way to get the name of the stream where the stdout is redirected. Is that possible at all?
Thanks a lot for your assistance Francesco

Respuestas (3)

José-Luis
José-Luis el 18 de Dic. de 2013
A workaround that might make your life less complicated: make your script into a function and pass the output name as an argument to this function.
pfb
pfb el 18 de Dic. de 2013
José-Luis, thanks for your suggestion.
I had thought of that, and it's actually what I'm doing now, sort of.
Still, it would be useful to me to get the name of the stream into which the stdout is redirected by the nohup command.
I wonder whether I can do that via a system call.
Thanks anyway
Francesco
Walter Roberson
Walter Roberson el 18 de Dic. de 2013
You can use code to fstat() standard output (file id 1) in order to find the device and inode number associated with the output. You can use code to ftw() to find a name associated with that inode. But a file can have multiple "real" names in OS-X and Linux. If you are not lucky enough that the link count is exactly 1, then you have to find all of the names and figure out which is the "right" one for the circumstances.
Remembering that output.txt might have been a symbolic link to a completely different name: do you want the name "output.txt" or do you want the name linked to?
You can get the process ID (PID). You can system() of 'ps' to get the public command line associated with the process. Unfortunately, when that public command line is being created, the shell has already stripped out all I/O redirection and $ constructs, so the output name just isn't there. The operating system does not know what it is, as it is the shell that works it all out, does fopen() on the output file, does the appropriate fclose() and fdup() to get the file descriptors in place, and then does a fork() and exec() or popen(), What the operating system gets is at best the command line arguments passed to the routine; redirection has been removed from those as individual programs are not expected to have to handle redirection themselves. The shell might still have a copy of the command line (maybe), but you would have to root around in the shell memory to find it.
Thus, José-Luis's answer is the correct one: if you need to know the name of the output file, pass it in as an argument.

4 comentarios

pfb
pfb el 18 de Dic. de 2013
Walter,
thank you for your reply. I am not sure I understand the first part (due to my ignorance), but I'll definitely try.
Actually I have tried ps but, as you say, I found out that the result lacks the I/O redirections.
About your question: what I would like to have is the name of the file (possibly including the path) where the stdout is redirected by the above nohup command. I'd like to print that in a different file which should list all of the running jobs, and the corresponding stdout files. I can do that for the job's PID, using 'feature' , and I was hoping that there was a way to do the same for the stdout file.
About José-Luis's answer. If I am not missing something obvious, I think I should change all of my fprintf('whatever') into fprintf(fh,'whatever'), where fh is the handle to the output file. I might end up doing that, but I was hoping for a quicker, if perhaps dirty, solution.
Also, it is not entirely clear to me how can I run a function in background, as opposed to a script. I tried to look that up and I found old posts claiming that it's not possible. Of course I could wrap my function in a script, and feed that to matlab.
Thanks again F
It's still me. Your comment about rooting in the shell memory got me thinking. After all what I want is the last issued command. That should be in the history.
history | tail -2 | head -1
gives the last command (the last but one, actually, since the current command is listed in the history as well).
There is something I'm not getting, though. In matlab using system for the above command does no seem to work. Also, it's not entirely clear to me where the history is recorded. The file ~/.bash_history does not seem to be the right answer.
Better go to bed and think about it tomorrow. Thanks a lot to both of you. F
cat > start_script <<EOF
  #!/bin/sh
  scriptname="script"
  logfile="$HOME/${scriptname}.log"
    thispid=$$
    thisfile="output${thispid}.txt"
    thisdir=$pwd
    nohup matlab -nodesktop -nodisplay -nosplash -r "try cd $thisdir;$scriptname;catch ME; end;quit" &> $thisfile &
    echo "$(date) started $thispid to $pwd/$thisfile" >> $logfile
    EOF
    chmod +x start_script

Now after that you can just

./start_script

to start it running, with the information being appended to a log file (in your home directory)

Walter,
thanks a lot for your detailed suggestion. It's very interesting.
I get the gist of it, although I'm not sure I grasp the details.
I'm not very proficient in shell scripting.
My only thought here is that perhaps while I'm at it I'll give the script some arguments (script, output, logfile), rather than writing them in it.
I think I can do that.
Anyway, this is not what you (and José-Luis) meant by using a function instead of a script, right?
Thanks again F

Iniciar sesión para comentar.

Categorías

Preguntada:

pfb
el 18 de Dic. de 2013

Comentada:

pfb
el 19 de Dic. de 2013

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by