TheDataGuy
TheDataGuy

Reputation: 3108

Shell - run bunch of commands in IF else

I would like to prepare a shell script, that will execute my all commands if my all commands went success then it'll print "SUCCESS" and any one single command failed then print "FAILED".

My shell script commands:

cd /home/lin

mkdir logs

cp /tmp/filelog.log logs/

rm /tmp/log*

touch /tmp/log

Save this file test.sh

Here is my query,

While executing this, if any one of my commands failed then it should stop execution and print "Failed"

Else print "SUCCESS"

Upvotes: 0

Views: 214

Answers (4)

Walter A
Walter A

Reputation: 19982

Make a function that will print optional parameters.

stop()
{
   if [ $# -gt 0 ]; then
      echo "Failed: $@"
   else
      echo "Failed."
   fi
   exit 1
}

You can use the function without parameters when you do not want to write much code.

cd /home/lin || stop
mkdir logs || stop
cp /tmp/filelog.log logs/ || stop
rm /tmp/log* || stop
touch /tmp/log || stop
echo Success

You can put more effort into it.
The first command shows how to fetch stderr and use it in your output.

errmsg=$(cd /home/lin 2>&1) || stop ${errmsg}
# You do not want an error when the dir already exists
mkdir -p logs || stop
# You can test in front
test -f /tmp/filelog.log || stop File filelog.log not found
cp /tmp/filelog.log logs/ || stop
rm -f /tmp/log* || stop
touch /tmp/log || stop
echo Success

Other possibilities are using set -e (will exit after a failure, but will not have the "Failure" message), this is shown in the answers of @Kusalananda and @HenkLangeveld.
Or make a chain of commands:

cd /home/lin &&
mkdir -p logs &&
test -f /tmp/filelog.log &&
cp /tmp/filelog.log logs/ &&
rm -f /tmp/log* &&
touch /tmp/log || stop

Upvotes: 0

Kusalananda
Kusalananda

Reputation: 15603

A solution for bash (or ksh):

#!/bin/bash

set -e
trap 'echo FAILED' ERR

mkdir test/test
# etc.

echo 'SUCCESS'

The ERR trap will execute when the -e (errexit) shell option causes the shell to exit due to a command returning a non-zero exit status.

Testing this script in a directory where mkdir test/test fails:

bash-4.4$ bash script.sh
mkdir: test/test: No such file or directory
FAILED

Testing this script in a directory where mkdir test/test succeeds:

bash-4.4$ bash script.sh
SUCCESS

Upvotes: 0

F. Hauri  - Give Up GitHub
F. Hauri - Give Up GitHub

Reputation: 70772

Sample of proper script

#!/bin/sh

die() { echo >&2 "$0 Err: $@" ; exit 1 ;}


cd /home/lin               || die "Can't change to '/home/lin' dir"

mkdir logs                 || die "Can't create '$PWD/logs' dir"

cp /tmp/filelog.log logs/  || die "Can't copy 'filelog.log' to '$PWD/logs'"

rm /tmp/log*               || die "Can't remove '/tmp/log*'"

touch /tmp/log             || die "Can't touch /tmp/log"


echo SUCCESS: All done!

Upvotes: 1

Henk Langeveld
Henk Langeveld

Reputation: 8446

Because each command is dependent on its predecessor this is a perfect use case for set -e. Perform all the work in a subshell, and you only have to check for the result of the subshell.

The set -e will exit the current shell on the first error encountered. (I.e., when a non-zero exit status is returned.)

(set -e
  cd /home/lin
  mkdir logs
  cp /tmp/filelog.log logs/
  rm /tmp/log*
  touch /tmp/log
) && echo "SUCCESS" || echo "FAILED"

Upvotes: 2

Related Questions