Is it possible to open a file in an running instance of Matlab from the command line? - matlab

If I already have an instance of Matlab running is it possible to tell open a file in the Matlab editor from outside the Matlab application? I'm wondering if there it is possible do something like this.
Launch an instance of Matlab
$ ./matlab
Open a file for editing using an already running instance of Matlab:
$ matlab_open_file.sh theFile.m
The GUI variant is dragging a file from a folder and then dropping it onto Matlab icon (this actually works under OS X)
Note I know that you can launch Matlab and have it immediately execute a command (you could use this to start the editor on launch). This is not what I want.

I scripted a workaround for Linux (functional on Mint 17.1 with R2014a and R2014b), which I then associated with the .fig and .m file extensions. Note that this requires xdotool to be installed, and the keystrokes are set for Windows shortcuts (by default, MATLAB ships with Emacs shortcuts on Linux, but virtually everyone changes them in my experience). This has the limitation that any text currently on the command line is erased, and there is a small window of time where MATLAB must not lose focus. But in the absence of a more robust solution, it works well enough for me.
#!/bin/bash
# Hacky way to open a MATLAB figure in an existing instance if there is
# one, and start a new instance if not.
# What are we trying to open?
FILENAME="$#";
# Try to identify the main MATLAB window.
MLWINDOW=$( comm -12\
<(xdotool search --name MATLAB\ R | sort)\
<(xdotool search --class "com-mathworks-util-PostVMInit" | sort) )
if [ -z "$MLWINDOW" ]; then
# MATLAB isn't open; we have to open it to proceed.
matlab -desktop -r "open('$FILENAME')"
else
# We use the first existing instance since MATLAB is open
set -- $MLWINDOW
# Jump to the command line and erase it
xdotool windowactivate --sync $1 key --delay 0 "control+0" Escape
# Put the filename on the command line
xdotool type --delay 0 "$FILENAME"
# Select the filename and press ctrl-D to open, then clean up command line
xdotool key --delay 0 "shift+Home" "control+d" Escape
fi

You can type the path+filename into the command line and if a matlab session is open it will open this file in the current matlab session.
Note that this only works if you make sure matlab is the default program to open this kind of file. (Tested with .m file)

I modified Aoeuid's approach because
it did not work for me, as I had reassigned Ctrl+0 which jumps to the command line (and I don't see where I could set this to another value) → I replaced it with the “open file” dialog (Ctrl+O).
I might want to open scripts that are not on the current matlab path → I use $PWD/$filename instead of $filename. You could modify his version by using open($PWD/$FILENAME) and KP_Enter instead of $FILENAME and shift+Home/control+d.
This is the result:
#!/bin/bash
filename="$1"
# Try to identify the main MATLAB window.
MLWINDOW=$( comm -12\
<(xdotool search --name MATLAB\ R | sort)\
<(xdotool search --class "com-mathworks-util-PostVMInit" | sort) )
if [ -z "$MLWINDOW" ]; then
# MATLAB isn't open; we have to open it to proceed.
matlab -desktop -r "open('$PWD/$filename')"
else
## Activate window:
xdotool windowactivate --sync $MLWINDOW && \
## Press Ctrl+O to open the "open" dialog:
xdotool key --delay 0 "control+o" && \
## Wait for the file dialog to open:
sleep 0.5 && \
## Type the file name including the current directory
xdotool type --delay 0 "$PWD/$filename" && \
## Press enter:
xdotool key "KP_Enter"
fi
However, using key presses for an automated process might cause unwanted results.

Make sure that you added you folder to path.
Then you go to folder you need.
and just type in Matlab terminal
your_program_name
Then your program will run.

Related

How to open a new terminal window with running command with Swift on macOS? [duplicate]

I can launch an xterm from the command line (or a program, via a system call) like so:
/usr/X11/bin/xterm -fg SkyBlue -bg black -e myscript
That will launch an xterm with blue text and a black background, and run an arbitrary script inside it.
My question: How do I do the equivalent with Terminal.app?
You can open an app by bundle id too, and give other parameters.
If there's an executable script test.sh in the current directory, the following command will open and run it in Terminal.app
open -b com.apple.terminal test.sh
The only down side that I can find is that Terminal doesn't appear to inherit your current environment, so you'll have to arrange another way to pass parameters through to the script that you want to run. I guess building the script on the fly to embed the parameters would be one approach (taking into account the security implications of course...)
Assuming you already have the colors you want in one of your Terminal profiles, here's what I came up with (with some help from Juha's answer and from this Serverfault answer).
Update:
On reflection, I think this echo business is too complicated. It turns out you can use osascript to make an executable AppleScript file with a shebang line:
#!/usr/bin/osascript
on run argv
if length of argv is equal to 0
set command to ""
else
set command to item 1 of argv
end if
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application "Terminal"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application "Terminal" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
Save that as term.scpt, make it executable with chmod +x, and use it the same way as below, e.g. term.scpt "emacs -nw" "Red Sands".
Original answer:
Assuming we save the script below as term.sh...
#!/bin/sh
echo '
on run argv
if length of argv is equal to 0
set command to ""
else
set command to item 1 of argv
end if
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application "Terminal"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application "Terminal" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
' | osascript - "$#" > /dev/null
...it can be invoked as follows:
term.sh
opens a new terminal window, nothing special
term.sh COMMAND
opens a new terminal window, executing the specified command. Commands with arguments can be enclosed in quotes, e.g. term.sh "emacs -nw" to open a new terminal and run (non-windowed) emacs
term.sh COMMAND PROFILE
opens a new terminal window, executing the specified command, and sets it to the specified profile. Profiles with spaces in their names can be enclosed in quotes, e.g. term.sh "emacs -nw" "Red Sands" to open a new terminal and run (non-windowed) emacs with the Red Sands profile.
If you invoke it with a bad command name, it'll still open the window and set the profile, but you'll get bash's error message in the new window.
If you invoke it with a bad profile name, the window will still open and the command will still execute but the window will stick with the default profile and you'll get an error message (to stderr wherever you launched it) along the lines of
525:601: execution error: Terminal got an error: Can’t get settings set 1 whose name = "elvis". Invalid index. (-1719)
The invocation is slightly hacky, and could probably be improved if I took the time to learn getopt (e.g., something like term.sh -p profile -e command would be better and would, for instance, allow you to easily open a new terminal in the specified profile without invoking a command). And I also wouldn't be surprised if there are ways to screw it up with complex quoting. But it works for most purposes.
Almost all (every?) osx program can be launched from command line using:
appName.app/Contents/MacOS/command
For terminal the command is:
/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
You can use the autocomplete (tab) or ls to find the correct filenames. ".app" is basically a folder.
To change the colors and run a script... I think you cannot do it with shell scripts as Terminal does not accept arguments ("Terminal myScript.sh" does not launch myScript). With iTerm this works.
Workaround is to use applescript (wrapped in a shell script):
#!/bin/sh
osascript -e '
tell application "Terminal"
activate
tell window 1
do script "sleep 5; exit"
set background color to {0, 11111, 11111}
set win_id to id
end tell
set w_ids to (id of every window)
repeat while w_ids contains win_id
delay 1
set w_ids to (id of every window)
end repeat
end tell'
Ok, now it should behave exactly the same as the xterm example. The drawback is the constant polling of the window ids (which is bad programming).
edit: A bit more elegant applescript would use the 'busy' property of Terminal. I will leave the original code as is works for a general program (not just terminal).
tell application "Terminal"
tell window 1
do script "sleep 2"
set background color to {0, 11111, 11111}
repeat while busy
delay 1
end repeat
close
end tell
end tell
Also for perfectly correct program, one should check that whether the terminal is running or not. It affects the number of windows opened. So, this should be run first (again a nasty looking hack, that I will edit later as I find a working solution).
tell application "System Events"
if (count (processes whose name is "Terminal")) is 0 then
tell application "Terminal"
tell window 1
close
end tell
end tell
end if
end tell
br,
Juha
You can also go into terminal GUI, completely configure the options to your heart's content, and export them to a ".terminal" file, and/or group the configurations into a Window Group and export that to a terminal file "myGroup.terminal". Then
open myGroup.terminal
will open the terminal(s) at once, with all your settings and startup commands as configured.
you can launch terminal with the following command, not sure how to specify colors:
open /Applications/Utilities/Terminal.app/
The answer from #david-moles above works but run the terminal and command in ~ rather the current working directory where term was launched. This variation adds a cd command.
#!/usr/bin/env bash
# based on answer by #david-moles in
# https://stackoverflow.com/questions/4404242/programmatically-launch-terminal-app-with-a-specified-command-and-custom-colors
echo "
on run argv
if length of argv is equal to 0
set command to \"\"
else
set command to item 1 of argv
end if
set command to \"cd '"$PWD"' ;\" & command
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application \"Terminal\"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application \"Terminal\" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
" | osascript - "$#" > /dev/null
There may be a way to set PWD this with applescript.
Note: When I use this, I sometimes two Terminal windows, one a shell running in ~ and a second which runs the cd command and command from argv[1]. Seems to happen if Terminal is not already running; perhaps it is opening old state (even tho I had no open terminals when I closed it).

zsh: command not found: flutter?

I've tried to install flutter multiple times, and could run flutter doctor once, but after closing the terminal I couldn't. Don't know how I did it, and this keeps coming on the screen.
user#users-MacBook-Pro flutter % export PATH="$PATH: /Users/user/Desktop/flutter/bin"
user/users-MacBook-Pro flutter % flutter --version
zsh: command not found: flutter
user#users-MacBook-Pro flutter %
So I have changed my path, changed the shell to -zsh, because I work with macOS Catalina, but nothing seems to work. What should I do?
As Lesiak said, you need to remove the space in your string, leaving you with export PATH="$PATH:/Users/user/Desktop/flutter/bin". However, this will only change the current shell (terminal) you have open.
To make this permanent, you need to change your zsh configuration file. This is located at $HOME/.zshrc. Run this command:
$ echo 'export PATH="$PATH:/$HOME/Desktop/flutter/bin"' >> $HOME/.zshrc
This appends export PATH="$PATH:/$HOME/Desktop/flutter/bin" to the end your .zshrc file. Note that it is crucial that you use >> and not >. >> appends to the file, > overwrites it.
To further explain what's going on here:
$HOME refers to your home directory. On your machine, and if your user is called user, this would be /Users/user. This would vary based on the type of operating system you have and your username, therefore we use $HOME to be device-independent.
$PATH is where your shell looks for programs to execute when you type a command in the shell. If you do echo $PATH you can see its content. It could look something like this: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin. All the parts separated by : is a segment of the path, and your shell looks in each of those directories for a program that matches the command you gave.
Open Terminal and Type:
vim $HOME/.zshrc
After that, we need to edit that file!
Press command I
Now on a new line Type:
export PATH="$PATH:/YOUR_FILE_PATH/flutter/bin Don't forget to update YOUR_FILE_PATH!
Now press esc
Now type :wq! to exit
Now restart your terminal
Remove the empty space in
export PATH="$PATH: /Users/user/Desktop/flutter/bin"
source ~/.zshrc
Type this command in Terminal. This work for me.
export PATH=$PATH:/'Your Path'/flutter/bin\
example :-
export PATH=$PATH:/Applications/Flutter/flutter/bin\
this is work for me
Open Terminal and Type:
vim $HOME/.zshrc
After that, we need to edit that file!
Press command I
Now on a new line Type:
export PATH="$PATH:/YOUR_FILE_PATH/flutter/bin
Don't forget to update YOUR_FILE_PATH!
Now press esc
Now type :wq! to exit
Now restart your terminal
Open terminal
Write => vim .bash_profile
OR => vim $HOME/.zshrc
Click on (i) to be able to insert the following:
Write => export PATH="$PATH:[PATH_OF_FLUTTER_GIT_DIRECTORY]/bin"
OR => export PATH=[PATH_OF_FLUTTER_GIT_DIRECTORY]/bin:$PATH
Click on (esc) to be able back from inserting mode
Write => :wq! [This will exit]
Restart terminal then Write => flutter doctor
The problem will be easily solved ^_^
Type this command in Terminal. This work for me.
export PATH="$PATH:`pwd`/flutter/bin"
Try this one that is in the official documentation. https://docs.flutter.dev/get-started/install/macos
export PATH="$PATH:`pwd`/flutter/bin"
The .zshrc file is not present by default sometimes, we need to create it.
Steps for creation:
Open Terminal ->
type touch ~/.zshrc to create the respective file.
To open the file -> type open $HOME/.zshrc
or
Open Finder > Press Cmd + Shift + ~

Run a program in debug mode in eclipse in command line

For several reasons I must test my program with multiple computer restart.
So I need at the computer startup, eclipse open and the tested program runs in eclipse (in debug mode if possible).
Can you give me a command line or another way to do that. I just need when I open eclipse or when I use the given command line, the program automatically start
Thank you
For Linux OS (not sure on Win, Mac), Eclipse (or other apps) can be automated with xdotool utility. Assuming your app has run at least once in debug mode within Eclipse so it exists an entry on Debug history, a Bash script could do the following actions
-Edit the script below to set the correct position value for the app.
-Launch Eclipse.
-Wait some time until is fully up.
-Execute the following command sequence:
#!/bin/bash
position=6
#find Eclipse app window IDs, keep the last one
e_wid=$(xdotool search --class Eclipse | gawk 'END{print $0}')
# Create basic command string
cmd="xdotool windowactivate --sync $e_wid"
# Send key strokes with some delay in between
# Open Run menu
$cmd key Alt+r
sleep 1
# select Debug option
$cmd key h
sleep 0.5
# pick the sixth option in that menu
$cmd key $position
It's recommended to mark the app as a favorite so it gets a constant order in the menu.
To see another example, check this mluis7 gist at Github.

Running a MATLAB script from Notepad++

Is there a way of running a MATLAB script from Notepad++?
Obviously I have MATLAB installed on my computer. I know you can set a path for Notepad++to run when you hit F5, but when I set this path to my MATLAB.exe file, it simply opens another instance of MATLAB.
This is not what I want, I want the actual script in Notepad++ to be executed in the already open and running instance of MATLAB.
I'm afraid I'm not on my home computer at the moment to test this out, so the following is just a suggestion for you to try.
If you take a look at the NppExec plugin for Notepad++, you'll see that with it you can specify a command to be run when you hit F6 (like an enhanced version of hitting F5 in the regular Notepad++). You can also give it variables such as the path to the current file, and the name of the current file.
MATLAB (on Windows at least - I assume you're on Windows) makes available an API over ActiveX/COM. If you search in the MATLAB documentation for details, it's under External Interfaces -> MATLAB COM Automation Server. By running (in MATLAB) the command enableservice('AutomationServer') you will set up your running instance of MATLAB to receive instructions over this API.
You should be able to write a small script (perhaps in VBScript or something similar) that will take as input arguments the path and filename of the current file in Notepad++, and will then connect to a running instance of MATLAB over the COM API and execute the file's contents.
Set this script to be executed in NppExec when you hit F6, and it should then run the current file in the open instance of MATLAB.
As I say, the above is just speculation as I can't test it out right now, but I think it should work. Good luck!
Use NppExec add-on and press F6, copy paste the following and save the script:
NPP_SAVE
set local MATPATH=C:\Program Files\MATLAB\R2015a\bin\matlab.exe
cd "$(CURRENT_DIRECTORY)"
"$(MATPATH)" -nodisplay -nosplash -nodesktop -r "try, run('$(FILE_NAME)'),
catch me, fprintf('%s / %s\n',me.identifier,me.message), end"
then run (press F6; enter). Matlab Console and Plot windows still open and stay open. Error messages will be displayed in opening Matlab command window. Adding
, exit"
to the last command will make it quit and close again. If you want to run an automated application with crontabs or the like, check Matlab external interface reference for automation.
matlab.exe -automation ...
Also works in cmd terminal, but you have to fill in the paths yourself.
This is a usable implementation upon Sam's idea. First, execute MATLAB in automation mode like this.
matlab.exe -automation
Next, compile and execute this following VB in NppExec plugin. (which is to use MATLAB automation API)
'open_matlab.vb
Imports System
Module open_matlab
' connect to a opened matlab session
Sub Main()
Dim h As Object
Dim res As String
Dim matcmd As String
h = GetObject(, "Matlab.Application")
Console.WriteLine("MATLAB & Notepad++")
Console.WriteLine(" ")
'mainLoop
while True
Console.Write(">> ")
matcmd = Console.ReadLine()
' How you exit this app
if matcmd.Equals("!!") then
Exit while
End if
res=h.Execute(matcmd)
Console.WriteLine(res)
End while
End Sub
End Module
Then you'll get a matlab-like terminal below your editor. You can then code above and execute below. type !! to exit the terminal.
What it looks like
Tips: don't use ctrl+c to interrupt the MATLAB command, because it will kill the whole process instead.

Calling a command line program

I have a executable that when double clicked opens in a command line window.
Now there is a input file (i.e named "sphere_15000.inp") in the same directory where the executable apame_win64.exe is located. So we can inter the file name in the command line.
The question is how this can be done from mathematica front end? With the RunThrough command I tried to do it with no avail.
RunThrough["Executable Location", "sphere_15000"]
Do I need to put this file location in my Windows 7 environment path variable? Hope for some suggestion in this regard.
UPDATE
Found a solution to my problem.
First set the Mathematica directory to the folder where the executable is located.
path="C:\Users\FlowCrusher\Desktop\CUSP solver\Apame_build_2011_01_09\solver";
SetDirectory[path];
Then use the following style of input.
Run["\"\"apame_win64.exe\" \"input\"\""]
Here "apame_win64.exe" is the executable one want to run and "input" is the input file for the executable. This solves the problem. But a new item in the wishlist.
Is there a way to hide the console window in the background?
Here is how it looks on my screen.
As Chris suggested if we use minimized console in the Run command we get a minimized window but the program does not execute.
I hope that a solution exists.
BR
Yes, you might put the folder of you executable into the Path variable, or provide the full path name.
However, RunThrough seems to have been superseeded (on Windows) by
Import["!command ","Text"], which will execute command and read the comaand line output into Matheamtica as a string.
E.g.:
Export["testit.txt", "bla", "Text"];
Import["!dir" <> " testit* > dir.log", "Text"];
FilePrint["dir.log"]
--
Otherwise, I also had good results in the past using NETLink (not sure if WScript.shell
still works on Windows7/8 or if one should use something else).
Emulating Run (RunThrough is not really needed I think):
Run2[cmd_String] := Module[{shell},
Switch[$OperatingSystem,
"Windows",
Needs["NETLink`"];
shell = NETLink`CreateCOMObject["WScript.shell"];
shell # run[cmd,0,True],
"Unix",
Run # cmd,
"MacOSX",
Run # cmd ] ];
Can you run your application with input from a basic command window instead of the application console? This might be the form of command you would need:
apame_win64 -input sphere_15000.inp
or simply
apame_win64 sphere_15000.inp
You can probably check the available switches by running apame_win64 -help
A multi-part command can be run from Mathematica, e.g.
Run["type c:\\temp\\test.txt"]
Alternatively, also returning output to the Mathematica session:
ReadList["!type c:\\temp\\test.txt", String]
I landed here wanting to run abaqus command line on windows.
The solutions provided here worked out for me (Windows 7, Mathematica 9):
SetDirectory#path;
Run["start /min abaqus job=" <> fileName <> " interactive ask_delete=OFF >> log.txt"]
(Here the abaqus option ask_delete=OFF overwrites an existing simulation results and the >> redirects all the output to a file)
I think, minimizing the window did not run in your case since the executable throws open that window. In that case, this might be of some help