Is it possible to run commandLine in gradle with bash -c? - gradle

I have a task in a build.gradle file, in which I'd like to run this command:
(export ENV_VAR=/my/path ; /path/to/build.sh)
I tried running this in gradle:
task myTask {
doLast {
exec {
commandLine ['bash', '-c', '"(export ENV_VAR=/my/path ; /path/to/build.sh)"']
}
}
}
Unfortunately, I have an error that says
Successfully started process 'command 'bash''
bash: (export ENV_VAR=/my/path ; /path/to/build.sh): No such file or directory
Now I'm sure the file exists and the specified paths are correct. Running this command manually in the terminal works.
Is there something in gradle that makes a bash -c like this not work? I can't think of another way to make an export like this otherwise.

Try without the extra quotes:
commandLine ['bash', '-c', '(export ENV_VAR=/my/path ; /path/to/build.sh)']
When you run that in the command line, your shell needs the quotes to pass to the command (which happens to be bash) as a single argument, but gradle is already doing that with that syntax, so bash is receiving literally one argument "(export ENV_VAR=/my/path ; /path/to/build.sh)" and since it does not recognize this as internal syntax, tries to run a command with this name.

Related

Unable to run shell script in Terraform

I am trying to run a shell script with the local-exec command in Terraform. When I run this, it keeps coming up with the error "Can't open appsettings.sh". This script runs fine when run manually. Any ideas what I am missing?
resource "null_resource" "sp" {
triggers = {
shell_hash = "${sha256(file("${path.module}/appsettings.sh"))}"
}
provisioner "local-exec" {
command = "appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"
interpreter = ["sh"]
working_dir = "${path.module}"
}
}
error message:
Error: Error running command 'appsettings.sh 59942507-xxxx-xxxx-xxxxx 4c64-xxxx-xxxx-xxxxx': exit status 127. Output: sh: 0: Can't open appsettings.sh 59942507-xxxx-xxxx-xxxxx 4c64-xxxx-xxxx-xxxxx'
The issue here is, terraform run the command as
["/bin/sh" "-c" "appsettings.sh arg1 arg2"]
So the command interpreter take appsettings.sh as the command name which is very similar to running as below
$appsettings.sh arg1 arg2
which cannot be done as there is no command like this. So to run that shell script you either has to provide the absolute path of the shell script or relative as shown below
$ ./appsettings.h
$ /home/user/appsettings.sh # Example
To achieve this rearrange your command attr as below
command = "./appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"
OR
command = "${path.module}/appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"
i.e. add ./appsettings
The error message is stating that it "Can't open" the script file.
The reason might be:
The script file is not present (may be it is not yet created on machine)
Permission issue
If you are running command through a program (e.g terraform or script) you need to specify the shell and or proper path.
Example:
/bin/sh /path/to/script/myscript.sh
or
/bin/bash /path/to/script/myscript.sh
I am not sure but I think local-exec is used to run the local commands like ls, echo, mkdir etc and remote-exec is used to run the script.
Though I have not yet used this provisioner but you can play around this.
Refrances:
https://www.terraform.io/docs/provisioners/local-exec.html
https://www.terraform.io/docs/provisioners/remote-exec.html
OK I get it now.
TLDR version
Remove interpreter (interpreter = ["sh"]) at all or add -c as another parameter, like this: interpreter = ["sh", "-c"] or even better interpreter = ["/bin/sh", "-c"]. Additionally you need to provide path to script so add ./ or ${path.module}/.
NOTE: also as far as I see script needs to be executable (chmod +x appsettings.sh).
Full version
The problem is with default interpretation of local-exec. If you do not set interpreter then the default one is /bin/sh -c (Linux) and if you add command/script with parameters/arguments it looks like this
["/bin/sh", "-c", "./appsettings.sh a b"]
but what you were trying to do is to run something like this
["/bin/sh", "./appsettings.sh a b"]
If we test both this approaches in terminal then we will see:
$ /bin/sh -c "./appsettings.sh a b"
Params: a b
$ /bin/sh "./appsettings.sh a b"
/bin/sh: 0: Can't open ./appsettings.sh a b
In /bin/sh and /bin/bash shells -c parameters is responsible for:
Read commands from the command_string operand instead of from the standard input.
NOTE: if you want to read more check this out: https://askubuntu.com/questions/831847/what-is-the-sh-c-command
Final corrected script should looks like this:
resource "null_resource" "sp" {
triggers = {
shell_hash = "${sha256(file("${path.module}/appsettings.sh"))}"
}
provisioner "local-exec" {
command = "./appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"
}
}
If you would like to use bash instead of sh then it should be like this:
resource "null_resource" "sp" {
triggers = {
shell_hash = "${sha256(file("${path.module}/appsettings.sh"))}"
}
provisioner "local-exec" {
command = "./appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"
interpreter = ["/bin/bash", "-c"]
}
}```

Sbt external process can't process `eval` command

Running in sbt command "eval $(minikube docker-env)" !! log give exception.
[error] java.io.IOException: Cannot run program "eval": error=2, No such file or directory
but same command in bash script
#!/usr/bin/env bash
eval $(minikube docker-env)
Runn as "eval.sh" !! log
Work fine.
I can't understand why. Please explain.
eval is a shell feature. There is no way to call it from java to set up the environment for future commands the way you can for a shell.
If you want to run a second command from Java that depends on doing eval "$(minikube docker-env)" first, you can instead run a single shell with both commands:
String shellCommand = "eval \"$(minikube docker-env)\"; your-second-command";
Runtime.exec(new String[] { "sh", "-c", shellCommand });

Script not working as Command line

i've created simple bash script that do the following
:
#!/usr/bin/env bash
cf ssh "$1"
When I run the command line from the CLI like cf ssh myapp its running as expected, but when I run the script like
. myscript.sh myapp
I got error: App not found
I dont understand what is the difference, I've provided the app name after I invoke the script , what could be missing here ?
update
when I run the script with the following its working, any idea why the "$1" is not working ...
#!/usr/bin/env bash
cf ssh myapp
When you do this:
. myscript.sh myapp
You don't run the script, but you source the file named in the first argument. Sourcing means reading the file, so it's as if the lines in the file were typed on the command line. In your case what happens is this:
myscript.sh is treates as the file to source and the myapp argument is ignored.
This line is treated as a comment and skipped.
#!/usr/bin/env bash
This line:
cf ssh "$1"
is read as it stands. "$1" takes the value of $1 in the calling shell. Possibly - most likely in your case - it's blank.
Now you should know why it works as expected when you source this version of your script:
#!/usr/bin/env bash
cf ssh myapp
There's no $1 to resolve, so everything goes smoothly.
To run the script and be able to pass arguments to it, you need to make the file executable and then execute it (as opposed to sourcing). You can execute the script for example this way:
./script.bash arg1 arg2

Jenkins fails with Execute shell script

I have my bash script in ${JENKINS_HOME}/scripts/convertSubt.sh
My job has build step Execute shell:
However after I run job it fails:
The error message (i.e. the 0: part) suggests, that there is an error while executing the script.
You could run the script with
sh -x convertSubt.sh
For the safe side, you could also do a
ls -l convertSubt.sh
file convertSubt.sh
before you run it.
make sure that the script exist with ls
no need to sh , just ./convertSubs.sh ( make sure you have run permissions)

How can I run new gradle task?

I have created a new gradle task in build.gradle:
task callCL(type: Exec) {
println "hello"
commandLine './rerun.sh'
}
Which suppose to run rerun.sh:
#!/bin/bash
cucumber -f rerun --out rerun.txt
file="rerun.txt"
if [ -f "$file" ] then
cucumber #rerun.txt
rm $file
fi
I'm using IntelliJ as an IDE. How can I run this task?
I have tried to run in the zshell console and got this error:
gradle callCL
zsh: command not found: gradle
But in the IDE I use gradle all the time so it must be installed.
How can I fix this? And is my writing ok?
Try this:
1. Make sure GRADLE_HOME, GRADLE_OPTS are set.
2. Make sure $PATH has GRADLE_HOME/bin in it.
3. which gradle should return you a valid output.
4. then, see below, if this works on command prompt, then your IDE setting just need to know where's is GRADLE_HOME aka its installed / executable (either gradle or gradle.bat)
NOTE: I have used my own dummy rerun.sh file, you can you use build.gradle (as shown below).
$ cat rerun.sh
#!/bin/bash
echo Im re-running a command echo
echo something
echo ...
echo
$ cat build.gradle
task callCL(type: Exec) {
println "-----"
println "hello"
println "-----"
executable "bash"
args "-c", "bash ./rerun.sh"
//The following will do as well as magic number in bash is already set to #!/bin/bash
//args "-c", "./rerun.sh"
}
$ /cygdrive/c/gradle-2.0/bin/gradle callCL
-----
hello
-----
:callCL
Im re-running a command echo
something
...
BUILD SUCCESSFUL
Total time: 2.006 secs
This looks like problem with gradle not being found on path (in your shell).
You may use GVM to easily install gradle so that its available on your PATH.

Resources