0
for i in `cat foo.txt`
do
    $i
done

And I have a input file "foo.txt", with list of commands.

ls -ltr | tail
ps -ef | tail
mysql -e STATUS | grep "^Uptime"

when I run the shell script, it executes, but splits the commands in each line at spaces i.e for first line it executes only "ls", then "-ltr" for which I get command not found error.

How can I run each list as one command?

why am I doing this?

I execute lot of arbitrary shell commands including DB commands. I need to have a error handling as I execute each command(each line from foo.txt), I can't think of what can go wrong, so the idea is put all commands in order and call them in loop and check for error (#?) at each line and stop on error.

1
  • 1
    See @lasrks answer. Additionally, for i in `cat foo.txt` is a UUOc (Unnecessary Use Of cat) If you ever find yourself doing cat something and you are not concatenating something with another file -- it's likely a UUOc. Instead redirect your file to the loop, e.g. while read -r line; do ##stuff with line; done < foo.txt Do not eval $line to try and execute each line. eval is only once character away from evil. Source the file as the answer shows. Commented Dec 22, 2019 at 1:03

2 Answers 2

2

Why not just do this?

set -e
. ./foo.txt

set -e causes the shell script to abort if a command exits with a non-zero exit code, and . ./foo.txt executes commands from foo.txt in the current shell.


but I guess I can't send notification (email).

Sure you can. Just run the script in a subshell, and then respond to the result code:

#!/bin/sh

(
set -e
. ./foo.txt
)

if [ "$?" -ne 0 ]; then
  echo "The world is on fire!" | mail -s 'Doom is upon us' [email protected]
fi

Sign up to request clarification or add additional context in comments.

4 Comments

This does stop on error - but I guess I can't send notification (email).
@arsks - I tried your modified script, it does not stop on error, its does show "command not found error" I guess that is is raised by the subshell. I even tried adding "exit 1" after your echo statement in IF block. It does not stop it continues to next command in list.
This code works just fine (I even tested it!). If you're getting a "command not found" error you're making a basic mistake (e.g., not providing the correct path to a command).
sorry - yes it does works, I did not notice that the error check does not have "exit" due to which it was continuing (after error), I just added "exit", so it stops on error.
0

Code mentioned.

for i in `cat foo.txt`
do
    $i
done     

Please use https://www.shellcheck.net/

This will result    _ 
    $ shellcheck myscript

Line 1:
for i in `cat foo.txt`
^-- SC2148: Tips depend on target shell and yours is unknown. Add a shebang.
         ^-- SC2013: To read lines rather than words, pipe/redirect to a 'while read'   loop.
         ^-- SC2006: Use $(...) notation instead of legacy backticked `...`.

Did you mean: (apply this, apply all SC2006)
for i in $(cat foo.txt)

$ 

Will try while loop, and for test purpose content of foo.txt mentioned below

cat foo.txt
    ls -l /tmp/test
    ABC
    pwd



 while read -r line; do $line; if [ "$?" -ne 0 ]; then echo "Send email Notification stating  $line Command reported error "; fi; done < foo.txt

 total 0
-rw-r--r--. 1 root root 0 Dec 24 11:41 test.txt
bash: ABC: command not found...
Send email Notification stating  ABC Command reported error
/tmp

In case error reported you can break the loop. http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_05.html

while read -r line; do $line; if [ "$?" -ne 0 ]; then echo "Send email Notification  stating  $line Command reported error "; break; fi; done < foo.txt

total 0
-rw-r--r--. 1 root root 0 Dec 24 11:41 test.txt
bash: ABC: command not found...
Send email Notification stating  ABC Command reported error




 while read -r line; do eval $line; if [ "$?" -ne 0 ]; then echo "Send email Notification stating  $line Command reported error "; break; fi; done < foo.txt
total 0
-rw-r--r--. 1 root root 0 Dec 24 11:41 test.txt
   bash: ABC: command not found...
Send email Notification stating  ABC Command reported error

2 Comments

I tried your solution as well, I still see 2 issues. The commands are split at space eg: ls -ltr | tail will give error "ls: |: No such file or directory " and "ls: tail: No such file or directory" Its traps/shows error, but it continues to following line/command
man7.org/linux/man-pages/man1/eval.1p.html In above code use eval while read -r line; do eval $line; if [ "$?" -ne 0 ]; then echo "Send email Notification stating $line Command reported error "; break; fi; done < foo.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.