Issues while create a file in shell scripting in jenkins pipeline script - shell

I am trying to create a multi line file in Jenkins pipeline script using the below commands.
sh "echo \"line 1\" >> greetings.txt"
sh "echo \"line 2\" >> greetings.txt"
echo "The contents of the file are"
sh 'cat greetings.text'
sh 'rm -rf greetings.txt'
Unforunately , I am not able to create the file named greetings.txt. Can any one please let me know, where I am going wrong.
Results in Jenkins console:
[tagging] Running shell script
+ echo 'line 1'
[Pipeline] sh
[tagging] Running shell script
+ echo 'line 2'
[Pipeline] echo
The contents of the file are
[Pipeline] sh
[tagging] Running shell script
+ cat greetings.text
cat: greetings.text: No such file or directory
Any suggestions would be helpful.
Thanks!

This can be solve this by using single quotes with sh, so you don't need to use escaping. Also you have to create an initial file with > and add content with >>:
pipeline{
agent any
stages{
stage('write file'){
steps{
sh 'echo "line 1" > greetings.txt'
sh 'echo "line 2" >> greetings.txt'
echo "The contents of the file is"
sh 'cat greetings.txt'
sh 'rm -rf greetings.txt'
}
}
}
}
output:
[test] Running shell script
+ echo line 1
[Pipeline] sh
[test] Running shell script
+ echo line 2
[Pipeline] echo
The contents of the file is
[Pipeline] sh
[test] Running shell script
+ cat greetings.txt
line 1
line 2
[Pipeline] sh
[test] Running shell script
+ rm -rf greetings.txt
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

It's not finding a file named greetings.text because you didn't create one (a litte typo in the extension in your cat line). Try sh 'cat greetings.txt', or even better adjusted your script:
sh "echo \"line 1\" >> greetings.txt"
sh "echo \"line 2\" >> greetings.txt"
echo "The contents of the file are"
sh 'cat greetings.txt'
sh 'rm -rf greetings.txt'
If you want to use multiline commands, you can also use this syntax:
sh """
echo \"line 1\" >> greetings.txt
echo \"line 2\" >> greetings.txt
echo "The contents of the file are:"
cat greetings.txt
rm -rf greetings.txt
"""
From the last example, this should generate an output like:
Running shell script
+ echo 'line 1'
+ echo 'line 2'
+ echo 'The contents of the file are:'
The contents of the file are:
+ cat greetings.txt
line 1
line 2
+ rm -rf greetings.txt

Related

SSH running sh script that works locally but not remotely

I am trying to run a script that will be called by some other software to run some parameters to get out objective values.
The script run.sh is as follows:
#!/bin/bash
set -e
ssh id#somehost '
/path/to/folder/solver arg1 arg2 arg3
res=$(</path/to/folder/res_data.txt)
echo "Final Result:"
echo "1 $res"
'
Running this file results in the following:
$ sh run.sh
OpenNN Exception: NeuralNetwork class.
void load(const std::string&) method.
Cannot load XML file ../data/neural_network.xml.
Final Result:
1 -285361 3.22136
Connection to somehost closed.
The Final Result above is from a previous output
If I run a similar script without the ssh
set -e
/path/to/folder/solver arg1 arg2 arg3
res=$(</path/to/folder/res_data.txt)
echo "Final Result:"
echo "1 $res"
Results in
$ sh run.sh 7 26 100
Final Result:
1 -285361 3.22136
$ sh run.sh 7 26 150
Final Result:
1 -421429 5.16397
Does anyone have any idea how to fix this?
Based on the comments above the solution of the error I was getting,
#!/bin/bash
set -e
ssh id#somehost '
cd /path/to/folder/
./solver '$1' '$2' '$3'
res=$(<./res_data.txt)
echo "Final Result:"
echo "1 $res"
'
I was simple enough just to add cd /path/to/folder/ and run the script from the folder it seems to work, in addition I also fixed the issue with the arguments rather than ./solver $1 $2 $3, having ./solver '$arg1' '$arg2' '$arg3' as the way to pass the inputted arguments to run on the solver.
The following output is from the corrected file above
$ sh run.sh 7 26 100
Final Result:
1 -285361 3.22136
$sh run.sh 7 26 150
Final Result:
1 -421429 5.16397

Jenkins, how to add variable content to file

How can I add variable content in file?
sh "ssh root#${host} 'echo '$vari' > text.txt'"
This gives empty file
Without variable it works:
sh "ssh root#${host} 'echo some text > text.txt'"
You can use the writeFile command offered by Jenkins:
writeFile file: "text.txt", text: YOUR_VARIABLE
This are 2 ways how you can write the content of a variable to a file:
pipeline {
agent any
environment {
VAR = "hello world!"
}
stages {
stage('Write to file'){
steps{
sh 'echo "${VAR}" > test.txt'
sh "echo ${VAR} >> test.txt"
sh 'cat test.txt'
}
}
}
}
Output:
[test] Running shell script
+ echo hello world!
[Pipeline] sh
[test] Running shell script
+ echo hello world!
[Pipeline] sh
[test] Running shell script
+ cat test.txt
hello world!
hello world!

Shell cmds in Jenkins Pipeline doesnt execute

I want to execute a cURL command, extract Json variable(using jq) & save in variable in Jenkins Pipeline. In Freestyle project under Build when I select Execute Shell and give below commands & I am getting valid Success output with all the values.
,
deployment_info=$(curl -H "Authorization: Basic a123=" "https://api.sample.com/v1")
rev_num=$(jq -r .environment[0].revision[0].name <<< "${deployment_info}" )
env_name=$(jq -r .environment[0].name <<< "${deployment_info}" )
api_name=$(jq -r .name <<< "${deployment_info}" )
org_name=$(jq -r .organization <<< "${deployment_info}" )
declare -r num1=1
pre_rev=$(expr "$rev_num" - "$num1")
echo $rev_num
echo $api_name
echo $org_name
echo $env_name
echo $pre_rev
Now I want to execute the same set of commands in a Pipeline. So this is my Pipeline,
def deployment_info
def rev_num
def env_name
def org_name
def api_name
def pre_rev
def num1
node {
stage('Integration Tests') {
sh "deployment_info=\$(curl --header 'Authorization: Basic abc123=' 'https://api.sample.com/v1')"
sh "rev_num=\$(jq -r .environment[0].revision[0].name <<< \"${deployment_info}\")"
sh "env_name=\$(jq -r .environment[0].name <<< \"${deployment_info}\" ) "
sh "api_name=\$(jq -r .name <<< \"${deployment_info}\" ) "
sh "org_name=\$(jq -r .organization <<< \"${deployment_info}\" )"
sh "declare -r num1=1"
sh "pre_rev=\$(expr \"$rev_num\" - \"$num1\")"
sh "echo $rev_num"
sh "echo $api_name"
sh "echo $org_name"
sh "echo $env_name"
sh "echo $pre_rev"
}
}
The cURL cmd is getting executed & a valid JSON response is seen in console, but after that, I am getting this error,
[Pipeline] sh
[curlpip] Running shell script
++ jq -r '.environment[0].revision[0].name'
+ rev_num=null
[Pipeline] sh
[curlpip] Running shell script
++ jq -r '.environment[0].name'
+ env_name=null
[Pipeline] sh
[curlpip] Running shell script
++ jq -r .name
+ api_name=null
[Pipeline] sh
[curlpip] Running shell script
++ jq -r .organization
+ org_name=null
[Pipeline] sh
[curlpip] Running shell script
+ declare -r num1=1
[Pipeline] sh
[curlpip] Running shell script
++ expr null - null
expr: non-integer argument
+ pre_rev=
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 2
Finished: FAILURE
Any help is appreciated.

Passing arguments from a file to shell in Pipeline

Basically I'm trying to pass properties to shell from a file.
I have a file "docker_info" with following content in workspace
IMAGE_NAME='Docker-image'
IMAGE_VERIONS='Docker-1.3.5'
Here is my pipeline script:
node
{
load "${WORKSPACE}/docker_info"
sh " echo ${IMAGE_NAME}" // here getting expected output: Docker-image
stage('Executing SHELL SCRIPING TO CHECK DOCKER IMAGE')
sh '''
echo "$DOCKER_IMAGE"
if [ -z "${IMAGE_NAME}" ] //(also tried "$IMAGE_NAME")
then
echo "Docker image not found."
exit 0
fi
echo "${IMAGE_NAME}:started pushing image"
'''
}
OUTPUT:
[Test_BUILD_PIPELINE] Running shell script
+ echo Docker-image
Docker-image
**Entering stage Executing SHELL SCRIPTING TO CHECK DOCKER IMAGE**
Proceeding
[Pipeline] sh
[Test_BUILD_PIPELINE] Running shell script
+ echo ''
+ '[' -z '' ']'
+ echo 'Docker image not found. Skip pushing Docker image'
Docker image not found. Skip pushing Docker image
+ exit 0
Kindly note after entering into the stage I Won't see the expected value(Docker-image)instead displaying: echo ' '
I tried with several ways but that haven't worked.
sh '''
. /path/to/the/docker_info
if [ -z "$IMAGE_NAME" ]
then
echo "Docker image not found"
exit 0
fi
echo "$IMAGE_NAME:started pushing image"
'''
Try
sh """
echo '$DOCKER_IMAGE'
if [ -z '$IMAGE_NAME' ]
then
echo 'Docker image not found.'
exit 0
fi
echo '$IMAGE_NAME:started pushing image'
"""

Get command used to start a script

How to get the command previously used to start a shell script?
for example:
nohup /script_name.sh &
Inside the script itself, how to check if "nohup" has been used?
Thanks.
You want to use the $_ parameter in your script.
Example: shell.sh
#!/bin/bash
echo $_;
user#server [~]# sh shell.sh
/usr/bin/sh
user#server [~]#
Additionally:
If you want to get rid of that full path - /usr/bin/sh - utilize basename command.
#!/bin/bash
echo `basename $_`;
user#server [~]# sh shell.sh
sh
user#server [~]#
well that depends on the script in question.There're many ways to execute a script like:
./<scriptname> #chmod 700 <scriptname> should be done before executing this script
bash <scriptname> # provided bash is used for executing the script.
or if you just want to get the name of script2 in script1, then use sed or awk for parsing the script1 with regular expression => /script2/.
Try this:
cat <script1> | awk '{ if( $0 ~ /^[^#].* \/scriptname.sh/ ){ print $1}}'
#codebaus thanks, doing something like this works but using strace definitely not.
#!/bin/bash
# echo $_
# echo $0
if grep "sh" $_ >/dev/null ; then
exit 1
fi ;
echo "string" ;
I believe you want to run this?:
#!/bin/bash
# echo $_
# echo $0
if grep "sh" $_ 2> /dev/null ; then
exit 1
fi ;
echo "string";
user#server [~]# sh shell.sh
Binary file /usr/bin/sh matches
user#server [~]#
Not sure what you are trying to accomplish in the end game. But $_ should give you what you need based on your initial question.
Additionally:
As I did not answer your strace comment, apologies. Based on the previous code above.
strace sh shell.sh
wait4(-1, Binary file /usr/bin/strace matches
[{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 874
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD (Child exited) # 0 (0) ---

Resources