Running a bash script from the JVM - jvm

I'm having trouble running a simple bash script from Java. Specifically:
...
try{
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command);
pb.directory(new File(dir));
Process shell = pb.start();
int exitVal = shell.waitFor();
...
where 'command' the absolute path to a bash script that is executable by all and 'dir' is the working directory.
When I run my program I get an exit code 127 ("command not found"). I've tried using the Java Runtime class and the process.exec method but neither have worked for me. Any suggestions?

If "command" is a bash script, then instead of passing "/bin/bash" (and the erroneous "-c" like you're doing) to ProcessBuilder, just make sure that command is executable (chmod +x command), that the first line is #!/bin/bash, and then pass the full path to it into ProcessBuilder.

No -c. That means the script is the argument to -c. You are passing it a pathname, and you don't use -c for that.

Related

how to run compound script statements from cmake?

I have a complex/compound command that I want to execute as patch command during execution of my ExternProject_Add using this macro
macro(SET_PATCH_CMD arg)
message(STATUS "Patch command : ${arg};${ARGN}")
set(${PROJECT_NAME}_patch_cmd ${arg};${ARGN})
endmacro(SET_PATCH_CMD)
I dont remeber or am not sure why I added a ; between ${arg} and ${ARGN}, but patch commands like
mkdir -p <SOURCE_DIR>/install
are working as expected in my cmake project.
When I set a simple command like
SET(PATCH_CMD <SOURCE_DIR>/scripts/my_schript.sh)
patch command executes as expected, but the moment I start adding arguments to script with spaces in between
SET(PATCH_CMD <SOURCE_DIR>/scripts/my_schript.sh arg1 arg2 arg3)
SET_PATCH_CMD(${PATCH_CMD})
I get Command failed: No such file or directory
clearly spaces in my command are messing up the way cmake runs the shell script/command. Any help on making it work is appreciated.

Why is $PATH different when executing commands via SSH and libssh?

I'm trying to run a command on a remote host via libssh2 as wrapped by the ssh2 Rust crate.
So I would like to run the command cargo build, but when I try to run it via libssh, I get the error:
cargo: command not found
However, when I ssh into the server manually from the command line everything works fine.
I have noticed that the $PATH is different when running ssh from the command line and libssh as well:
for instance when I echo $PATH
ssh gives me:
/home/<user>/.cargo/bin:/usr/share/swift/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bi
while libssh gives me:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
So it looks like what's happening is that the modifications made to $PATH inside .bashrc and .profile are not making it in when running via libssh.
I also get the same behavior if I run /bin/bash -c "echo ${PATH}"
Why would this be the case, and is there any way to get the same behavior in both these cases?
Please take a look at that question.
TL;DR A login shell first reads /etc/profile and then ~/.bash_profile. A non-login shell reads from /etc/bash.bashrc and then ~/.bashrc.

Run multiple commands using wsl

I have some scripts on my home folder that I would like to run from command line, actually from the task scheduler, but I don't find the way to do so.
I have tried
wsl -u Ubuntu -u jlanza "cd /home/jlanza/bin && ./myscript && ./myotherscript"
but it doesn't work.
How can I concatenate the execution of several commands under the same session?
You need to escape && so powershell does not see them as different commands, to pass && to wsl do the following:
wsl -d Ubuntu -u jlanza -- cd /home/jlanza/bin `&`& ./myscript `&`& ./myotherscript
You need to pass those commands to WSL without the quotes so that bash interprets them correctly as a series of commands chained together, rather than a single long command. Unfortunately, when you do that, the '&&' operator gets interpreted by the Windows command line interpreter and the commands following do not get passed to WSL.
What I've found to work is replacing the '&&' (run command only if the preceeding command exits with success) operator with simple ';' (run command regardless of how the preceeding command exited). In your case then, something like this should work:
cmd /c "wsl -u Ubuntu -u jlanza cd /home/jlanza/bin; ./myscript; ./myotherscript"
However, if your use cases neccesitates the use of the '&&' operator, I'd try saving the command you're running as a script or an shell alias in the WSL. Calling that would then save you the need of passing '&&' through the Windows command line interpreter.
C:\Windows\System32\wsl.exe -d Ubuntu -u jlanza sh -c ". ~/.profile && script-jlanza.sh"
This way I load my own own profile and then I'm able to run the commands.
The option is just to run sh or any shell and then execute the commands you'd like within that shell. The other answer is also valid, but I like mine most, as I'm able to use the user profile (path, aliases, etc.)

Running .sh scripts in Git Bash

I'm on a Windows machine using Git 2.7.2.windows.1 with MinGW 64.
I have a script in C:/path/to/scripts/myScript.sh.
How do I execute this script from my Git Bash instance?
It was possible to add it to the .bashrc file and then just execute the entire bashrc file.
But I want to add the script to a separate file and execute it from there.
Let's say you have a script script.sh. To run it (using Git Bash), you do the following: [a] Add a "sh-bang" line on the first line (e.g. #!/bin/bash) and then [b]:
# Use ./ (or any valid dir spec):
./script.sh
Note: chmod +x does nothing to a script's executability on Git Bash. It won't hurt to run it, but it won't accomplish anything either.
#!/usr/bin/env sh
this is how git bash knows a file is executable. chmod a+x does nothing in gitbash. (Note: any "she-bang" will work, e.g. #!/bin/bash, etc.)
If you wish to execute a script file from the git bash prompt on Windows, just precede the script file with sh
sh my_awesome_script.sh
if you are on Linux or ubuntu write ./file_name.sh
and you are on windows just write sh before file name like that sh file_name.sh
For Linux -> ./filename.sh
For Windows -> sh file_name.sh
If your running export command in your bash script the above-given solution may not export anything even if it will run the script. As an alternative for that, you can run your script using
. script.sh
Now if you try to echo your var it will be shown. Check my the result on my git bash
(coffeeapp) user (master *) capstone
$ . setup.sh
done
(coffeeapp) user (master *) capstone
$ echo $ALGORITHMS
[RS256]
(coffeeapp) user (master *) capstone
$
Check more detail in this question
I had a similar problem, but I was getting an error message
cannot execute binary file
I discovered that the filename contained non-ASCII characters. When those were fixed, the script ran fine with ./script.sh.
Once you're in the directory, just run it as ./myScript.sh
If by any chance you've changed the default open for .sh files to a text editor like I had, you can just "bash .\yourscript.sh", provided you have git bash installed and in path.
I was having two .sh scripts to start and stop the digital ocean servers that I wanted to run from the Windows 10. What I did is:
downloaded "Git for Windows" (from https://git-scm.com/download/win).
installed Git
to execute the .sh script just double-clicked the script file it started the execution of the script.
Now to run the script each time I just double-click the script
#!/bin/bash at the top of the file automatically makes the .sh file executable.
I agree the chmod does not do anything but the above line solves the problem.
you can either give the entire path in gitbash to execute it or add it in the PATH variable
export PATH=$PATH:/path/to/the/script
then you an run it from anywhere

How to make a command-line tool executable in OS X?

I just finished writing my very first command-line tool in Objective-C, compiled it, and now I'm curious about how one would go about making it executable as a command.
For example, right now to use the program I have to type in ./filename -args into Terminal. I'd like to be able to only type in filename and execute the program.
I tried using sudo chmod a+x filename but no go.
sudo cp filename /usr/local/bin/
Or add the directory containing filename into $PATH. Like as all other UNIX-derived OSs.