I need to perform some task based on exit value of commands run and ensure the run command should not exit with 1, for this I'm using the following:
grep jenkins_build_number build_details.py && echo "jenkins_build_number = \"${COPYARTIFACT_BUILD_NUMBER_FLASH_IMG}\"" > build_details.py || echo "jenkins_build_number = \"${COPYARTIFACT_BUILD_NUMBER_FLASH_IMG}\"" >> build_details.py
grep build_version build_details.py || echo "build_version = \"X.X.X\"" >> build_details.py
grep build_date build_details.py || echo "build_date = \"XXX\"" >> build_details.py
This works fine in Linux, but it's not working in the Jenkins shell environment, how can I do this so it works?
How can I achieve above commands using if else?
Related
There is a simple cron job:
#reboot /home/user/scripts/run.sh > /dev/null 2>&1
run.sh starts a binary (simple web server):
#!/usr/bin/env bash
NPID=/home/user/server/websrv
if [ ! -f $NPID ]
then
echo "Not started"
echo "Starting"
nohup home/user/server/websrv &> my_script.out &
else
NUM=$(ps ax | grep $(cat $NPID) | grep -v grep | wc -l)
if [ $NUM -lt 1 ]
then
echo "Not working"
echo "Starting"
nohup home/user/server/websrv &> my_script.out &
else
ps ax | grep $(cat $NPID) | grep -v grep
echo "All Ok"
fi
fi
websrv gets JSON from user, and runs work.sh script itselves.
The problem is that sh script, which is invoked by websrv, "does not see" commands and stops with exit 1.
The script work.sh is like this:
#!/bin/sh -e
if [ "$#" -ne 1 ]; then
echo "Usage: $0 INPUT"
exit 1
fi
cd $(dirname $0) #good!
pwd #good!
IN="$1"
echo $IN #good!
KEYFORGIT="/some/path"
eval `ssh-agent -s` #good!
which ssh-add #good! (returns /usr/bin/ssh-add)
ssh-add $KEYFORGIT/openssh #error: exit 1!
git pull #error: exit 1!
cd $(dirname $0) #good!
rm -f somefile #error: exit 1!
#############==========Etc.==============
Usage of the full paths does not help.
If the script has been executed itself, it works.
If run.sh manually, it also works.
If I run the command nohup home/user/server/websrv & if works as well.
However, if all this chain of tools is started by cron on boot, work.sh is not able to perform any command except of cp, pwd, which, etc. But invoke of ssh-add, git, cp, rm, make etc., forces exit 1 status of the script. Why it "does not see" the commands? Unfortunately, I also cannot get any extended log which might explain the particular errors.
Try adding the path from the session that runs the script correctly to the cron entry (or inside the script)
Get the current path (where the script runs fine) with echo $PATH and add that to the crontab: replacing the string below with the output -> <REPLACE_WITH_OUTPUT_FROM_ABOVE>
#reboot export PATH=$PATH:<REPLACE_WITH_OUTPUT_FROM_ABOVE>; /home/user/scripts/run.sh > /dev/null 2>&1
You can compare paths with a cron entry like this to see what cron's PATH is:
* * * * * echo $PATH > /tmp/crons_path
Then cat /tmp/crons_path to see what it says.
Example output:
$ crontab -l | grep -v \#
* * * * * echo $PATH >> /tmp/crons_path
# wait a minute or so...
$ cat /tmp/crons_path
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ echo $PATH
/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
As the commenter above mentioned, crontab doesn't always use the same path as user so likely something is missing.
Be sure to remove the temp cron entry after testing (crontab -e, etc.)...
#!/bin/sh
ssh [username]#[ip] "bash -s" <<EOF
if [condition]
then
echo "success"
else
echo "failure"
fi
EOF
After running these commands, I want to save the result (ie success/failure) in a file on local machine. How do I go about it?
Good to try is the IO redirection:
ssh [username]#[ip] "bash -s" > file.txt <<EOF
[...]
Exit status of ssh is the exit status of the remote command so this should work:
( ssh [username]#[ip] [command] && echo success || echo failure ) > result.txt
Whats the best way to switch user run multiple commands and send output from all commands to file?
Needs to be done in one line so something like:
sudo -u user (command1; command2; command3; command4; command5) > out.log 2&1
Thanks in advance.
Running multiple commands separated by semicolons requires a shell. To get such shell features, you must invoke a shell like, in this case, bash:
sudo -u user bash -c 'command1; command2; command3; command4; command5' > out.log 2&1
Here, sudo -u user bash runs bash under user. The -c option tells bash which commands to run.
sudo -u user command1 > outFile; command2 >> outFile; command3 >> outFile; command3 >> outFile; command4 >> outFile;
If you want subsequent command to not execute if the previous one failed then...
command1 > outFile && command2 >> outFile && command3 >> outFile && command3 >> outFile && command4 >> outFile;
Note that command1 output is piped to the outFile by '>' (which will create a file and add output) whereas all subsequent commands are piping through '>>' (which will append the output)
I wrote a script which does some operations with SVN, everything is working fine, but I want to suppress the output of certain commands executed by the script. The following code is a minor part of this script and i want to hide all output when it executes a section containing "sudo svn add *"
ng1=$(svn stat 2>&1 | grep "?")
if [[ "$ng1" != "" ]];
then
echo ' '
echo '[NGINX]New files in work folder, add???[y/n]?'
echo ' '
read qyn
case $qyn in
[yY]* ) sudo svn add *;; #Add all to repo
[nN]* ) echo ' ';; #Proceed further
esac
else
echo ' '
echo '[NGINX]No new files'
echo ' '
fi
I tried to redirect ouput this way - {sudo svn add *} &>/dev/null but it's not working.
Is there any way to hide this output, but still execute sudo svn add *
To suppress both stdout and stderr use this:
sudo svn add * >& /dev/null
OR:
sudo svn add * &> /dev/null
for i in `cat ip_list` ; do
ping -c 1 $i 2&>1 > /dev/nul && echo $i good || echo $i bad ;
done
This loop works in bash 4 but not in bash 3... what should I change in the loop for the older RedHat 5 machines running version 3?
Three problems,
/dev/nul should be /dev/null
2&>1 should be 2>&1
some systems don't support -c option in command ping. Please confirm your command by manually run the command, if you get any error message.
ping -c 1 IP_ADDRESS
If you successfully run the ping -c command, then the code can be replaced by
for i in `cat ip_list` ; do
ping -c 1 $i 2>&1 > /dev/null && echo $i good || echo $i bad ;
done