One option is to handle ~ yourself:

CopyString homeDir = System.getenv("HOME");
String[] cmd = { homeDir + "/path/to/shellscript.sh", "foo", "bar" };
Process p = Runtime.getRuntime().exec(cmd);

Another is to let Bash handle it for you:

CopyString[] cmd = { "bash", "-c", "~/path/to/shellscript.sh foo bar" };
Process p = Runtime.getRuntime().exec(cmd);
Answer from ruakh on Stack Overflow
🌐
Kevin Boone
kevinboone.me › exec.html
How to run a shell script from a Java application - Kevin Boone
That is, the kernel can actually ... on. To invoke the shell to run the script, we might try something like this: ... The -c switch tells the shell to process the next argument as a command....
🌐
Netjstech
netjstech.com › 2016 › 10 › how-to-run-shell-script-from-java-program.html
How to Run a Shell Script From Java Program | Tech Tutorials
You are trying to run shell script on a Windows system! What do you expect ??? Though there are ways to run sh from widows but that will require some work. You can't just rum a sh file from windows command line. Delete ... If you are using Windows replace "sh" with "cmd". The terminal of is "powershell" or "cmd". "sh", "/bin/bash", "/usr/bin/python" for other kinds of scripts.ReplyDelete ... This method works fine when I try to execute on local.
🌐
Blogger
obscuredclarity.blogspot.com › 2011 › 07 › executing-shell-script-from-java.html
OBSCURED CLARITY: Executing a Shell Script from Java
July 28, 2011 - package mysql; import java.util.Date; import com.xeiam.utils.ExecUtils; /** * This class demonstrates running a shell script from within Java */ public class MySQLDumpScript { public static void main(String[] args) { String fileName = "DUMPFILE.sql.gz"; String shellCommand = "/temp/dump.sh " + fileName; ExecUtils.execShellCmd(shellCommand); } } You should now see a file called DUMPFILE.sql.gz in /temp/dump.
Find elsewhere
Top answer
1 of 1
2

When the shell parses a command line, it removes quotes but remembers the text structure that they imply.  (That is a gross oversimplification; see bash(1) or Shell Command Language for more details.)  For example, the command-line input

-blah apple -secondfruit "green banana" -some more

causes the shell to identify six words, or tokens:

  1. -blah
  2. apple
  3. -secondfruit
  4. green banana
  5. -some
  6. more

which will be stored in memory as

-blahⓧappleⓧ-secondfruitⓧgreen bananaⓧ-someⓧmoreⓧ

where represents a null byte.  This will then sometimes be displayed or reported as

-blah apple -secondfruit green banana -some more

so you might believe that the quotes are just being ignored, and you have seven words, while, in fact, you have what you want.

Note:

In the above, represents a null byte.  What I'm describing here is standard shell argument-parsing processing.  If you type

ls -l fruit.sh "I came here for an argument" startScheduledTask.sh

the /bin/ls program gets invoked with the string

lsⓧ-lⓧfruit.shⓧI came here for an argumentⓧstartScheduledTask.shⓧ

in memory, and this gets interpreted as

  • argv[0] = ls
  • argv[1] = -l
  • argv[2] = fruit.sh
  • argv[3] = I came here for an argument
  • argv[4] = startScheduledTask.sh

This exact same process happens if you are

  1. typing a java command directly into your primary, interactive shell,
  2. executing a java command that is in a shell script, or
  3. running a shell script by typing a command like ./startScheduledTask.sh directly into your primary, interactive shell,

so this is not the problem.  Any program that cannot handle having its arguments separated by null characters cannot work in Unix & Linux.

TL;DR

Your first command is correct.  "$@" gives you what you want; it is the correct way for a shell script to pass its arguments to a program that it calls.  If you add debug code to your program to loop through its arguments, printing each one on a new line, and/or in brackets (but not all on one line, separated only by spaces), you will see that the "$@" is passing six arguments to the program.


OK, even more:

  • Your class path has asterisks (*s) in it?  Really?  I’m a little out of practice with Java, but that seems odd to me.  Please double-check that you’re doing that correctly for your system.  But, if it works correctly when you type the classpath with asterisks “directly” (i.e., directly into your main shell; your primary, interactive shell; your login shell), then that’s probably not the problem.

    But please humor me and put that string into quotes, anyway.

  • Your problem is too complicated.  When you’re building an airplane, you don’t build the entire plane and then try to fly it.  And then, when it doesn’t fly, you don’t step back and ask, “What’s wrong with the plane?”  No, you test it in pieces.  You need to simplify.

    • Stop running it in the background.
    • Stop saying nohup.
    • Stop redirecting the output.
    • Don’t show your 42-character long shell prompt in your question.
    • Your question is about an argument with spaces in it, so don’t take that out, but it doesn’t have to be 60 characters long with eight spaces.  green banana is a great test value.
    • Try it with arguments to your program not beginning with - (dash).
    • Maybe even comment out the new TaskRunner().run(args) part of your program, leaving only the DEBUG and System.exit(0);.

    None of these should make a difference.  But they are distractions that make it hard to see what’s important.  If you can demonstrate the problem in a minimal test configuration, we can rule out all those other things as being related to the problem.  But, if the problem goes away when you remove the irrelevant things, then one of them was probably causing the problem.

    Also, please stop mixing fake/test data and real data (i.e., fruits and tasks) in the question.

  • Please write this script (call it fruity.sh):

    #!/bin/sh
    
                    # classpath
    CP="/opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/*"
                    # package.name.classname
    PC=wib.runner.TaskRunner
    
    "$JAVA_HOME"/bin/java  -cp "$CP"  "$PC"  "$@"
    

    and run

    ./fruity.sh taskExtRef "green banana"
    

    If the debug says

    …[taskExtRef, green banana]
    

    then the "$@" is working correctly, and the problem lies elsewhere in your script.  Try to find it.  Make one change at a time and see how the behavior changes.  If you can’t figure it out, we may be able to help you, but only if you show us the part of the script that’s causing the problem. 

    But if the debug says

    …[taskExtRef, green, banana]
    

    then let us know.

🌐
Stack Abuse
stackabuse.com › executing-shell-commands-with-java
Executing Shell Commands with Java
May 18, 2020 - public Process exec(String command, String[] envp, File dir) - Executes the command, with the specified environment variables, from within the dir directory.
🌐
Unix.com
unix.com › shell programming and scripting
Running shell script from java - Shell Programming and Scripting - Unix Linux Community
October 19, 2017 - Hello All, Hope all is well. I was trying to scratch my head here with simple problem of running Shell script in Java. I tried to google and look through forums but was unable to understand how to solve it. Here is my simple Java class, which resides in different directory then my shell script.
🌐
Redpill Linpro
redpill-linpro.com › techblog › 2024 › 02 › 21 › java-21-shell-scripts.html
Portable Java shell scripts with Java 21 – /techblog
February 21, 2024 - By the way, JEP 330 suggests using ... cause env to run java: ... These are needed for two reasons. First, the --source argument allows the script to break the standard naming conventions for Java source files....
🌐
GitHub
gist.github.com › simonwoo › c21811eddf0392034946
execute a shell script from java.md · GitHub
Clone this repository at &lt;script src=&quot;https://gist.github.com/simonwoo/c21811eddf0392034946.js&quot;&gt;&lt;/script&gt; Save simonwoo/c21811eddf0392034946 to your computer and use it in GitHub Desktop. ... /** * execute shell script */ private static void executeScript() { try { String bash = "/bin/bash"; String script = "script.sh"; String[] command = { bash, script }; System.out.println("Starting execute the script"); ProcessBuilder processBuilder = new ProcessBuilder(command); Map<String, String> env = processBuilder.environment(); env.put("ENV_KEY", "ENV_VALUE"); Process process =
🌐
Stack Exchange
unix.stackexchange.com › questions › 237104 › how-to-run-java-program-in-bash-script-and-give-it-one-argument
directory - How to run Java program in Bash script and give it one argument? - Unix & Linux Stack Exchange
October 19, 2015 - ... There is Caja-actions Configration tool to add the open with ABC in context menu. There is command tab in Caja Action tool, there you can provide the script path and the directory argument.
🌐
Quora
quora.com › How-do-I-run-a-shell-script-from-Java-code
How to run a shell script from Java code - Quora
Answer (1 of 7): Here are multiple ways already suggested in stackoverflow and both are good: How to run Unix shell script from java code? Run shell script from Java Synchronously
🌐
Mkyong
mkyong.com › home › java › how to execute shell command from java
How to execute shell command from Java - Mkyong.com
January 3, 2019 - I used the same (similar) code for my ShellWrapper. When I use commands like echo it works fine, but when I use commands like cat it returns an empty String…. ... As a good practice, I wouldn’t catch Exception e. Just mention the two that need to be dealt with (IOException, InterruptedException) . ... I am trying to convert avro to json file through java, But it is not working String output = obj.executeCommand(“java -jar /Users/xyz/Desktop/1server/jboss-as-7.1.1.Final/standalone/deployments/Command.war/WEB-INF/lib/avro-tools-1.7.7.jar tojson /Users/xyz/Desktop/avro/4.avro > /Users/xyz/Desktop/avro/D8EC9CC2A3E049648AFD4309B29D2A0F/4.json”); But this is not working through java file,