I am wondering if there is a way to execute bash scripts (.sh) from a macro?
If you want to execute native commands it might be best to use ImageJ1’s built-in
In the examples page you kindly provided, all examples seems like single bash commands, and no room for loops, variables etc., If I dont get it wrong.
Basically I need a way to run a bash script with parameters feed from ImageJ, open for further advises.
That’s perfectly fine. The
exec function doesn’t really care about the contents of your shell script. Wrap the loops and all the calls into a shell script and store it as
script-with-complicated-calls.sh file. The
exec call will look something like:
If you want to pass parameters (e.g.
arg2) to that shell script, use
exec as following:
exec("sh", "/path/to/script-with-complicated-calls.sh", "arg1", "arg2");
I would also like to raise your attention to script parameters which might make the user interface development for your task less involved:
// @String stringArgument // @Integer integerArgument exec("sh", "/path/to/script-with-complicated-calls.sh", stringArgument, integerArgument);
@stelfrich Thanks for clarification and additional info you provided. My “script-with-complicated-calls.sh” worked perfectly well, in a single line and I was very happy, until I realize one of the lines in the script totally skipped;
python2 somefile.py inputfile.txt outputfile.txt
The script works well when I run it from terminal (bash somefile.sh)
May I hope for anything?
Although I am not familiar with the implementation of
exec I suspect that you issue has to do with the
$PATH not being set properly for the user who executes the shell script.
Why don’t you check the absolute path to
in the bash and replace
python2 with that absolute path in script-with-complicated-calls.sh?
At that point, I decided to move python execution into imageJ macro, tried the following;
It returns a response in log window about usage (USAGE: thepythonscript.py infile, outfile etc…) but this time, I couldnt find how to feed required parameters, in that line.
exec("python", "/path/to/thepythonscript.py infile.txt outfile.txt")
exec("python", "/path/to/thepythonscript.py /path/to/infile.txt /path/to/outfile.txt")
Ok parameter problem solved, exec (“python”, “thescript.py”, “parameter1”, “parameter2”) makes it.
But I still want to keep python line in bash script, if its possible.
@Bio7 do you have any idea why a python line contained in a bash script which exec’ed from imageJ fails to work? Thanks!
Actually, it does work for me when I execute test.ijm from the script editor. It prints someString to ImageJ’s log window. Does that setup work for you?
// test.ijm exec("sh", "/home/stefan/Documents/PythonTest/test.sh");
#!/bin/bash python script.py someString
#!/usr/bin/python import sys print(sys.argv);
@stelfrich Now this is interesting… I tried whats available above, and nothing happened (nothing come out in Log window). In my case, exec seems like responding a certain list of commands and skips the rest. I have tried some other commands in the bash script (test.sh), like;
python --version or
java -version to see something, no way…
My OS is Ubuntu 14.04.
Fiji version is 1.51K, as in about box, which also reports java 1.8.0_66 (64-bit).
But from terminal:
$ java -version java version "1.7.0_121" OpenJDK Runtime Environment (IcedTea 2.6.8) (7u121-2.6.8-1ubuntu0.14.04.1) OpenJDK 64-Bit Server VM (build 24.121-b00, mixed mode)
Can you please mention about your SW versions? Maybe thats the problem… Also wondering whether you are using original ImageJ or Fiji ?
I am on Ubuntu 16.04 running an up-to-date Fiji (ImageJ1 1.51k, ImageJ2 RC57) with bundled JRE.
Also, now that I have restarted Fiji it doesn’t work anymore I’ll investigate…
@stelfrich Thank you for your interest. In my current work, job is done in three major steps and since this python execution is the second step in the middle, and cant be completed in bash script, users have to switch back and forth between imageJ and bash terminal. It will be fantastic if this problem can be handled, everything will be solved within single imageJ macro, therefore I am impatiently waiting for a solution. Also, should we declare a ‘bug’ for this?
Many thanks again.
Note that version 1.51k is the version of the bundled ImageJ 1.x, not the version of Fiji itself. Actually, at the moment, Fiji does not advertise its version explicitly—the status bar only shows the version of ImageJ2, followed by the version of ImageJ 1.x.
exec command eats the stderr stream. The bash script is executed successfully; the problem is that the
python line returns an error code (because it cannot find the Python script; see below). But bash scripts continue after errors, unless you tell them to do otherwise.
If you change the bash script to:
#!/bin/bash echo "== Starting python ==" python script.py Quick brown fox echo "== Python complete =="
Then you will see that both “Starting python” and “Python complete” get echoed. If you then change it again:
#!/bin/bash set -e echo "== Starting python ==" python script.py Quick brown fox echo "== Python complete =="
You will see that the “Python complete” line is no longer printed, because the
set -e fails the script once something goes wrong.
If you change the script a third time:
#!/bin/bash set -e echo "== Starting python ==" dir=$(cd "$(dirname "$0")" && pwd) python "$dir/script.py" Quick brown fox echo "== Python complete =="
You will now finally see that python is being executed; it’s just that the path to
script.py needs to be set, because the CWD did not match the bash script directory.
Here are the contents of configuration that works for me:
$ head * ==> script.py <== #!/usr/bin/python import sys print("~~~ WELCOME! TO PYTHON ~~~") print(sys.argv); print("~~~ NOW LEAVING PYTHON ~~~") ==> test.ijm <== // test.ijm result = exec("sh", "/Users/curtis/odrive/Box - UW/support/forum/4819/test.sh"); print("--> EXECUTION RESULTS <--"); print(result); print("--> HOPE YOU LIKED IT <--"); ==> test.sh <== #!/bin/bash set -e echo "== Starting python ==" dir=$(cd "$(dirname "$0")" && pwd) python "$dir/script.py" Quick brown fox echo "== Python complete =="
You will of course need to change the path in
test.ijm to match the directory of your ImageJ macro.
@ctrueden Thank you very much for detailed information, It worked flawlessly. I believe many people will benefit from this, since I was able to find very little info about usage details of exec function.