0

So I have an array full of commands, I want to run each each element and output the commands output to the screen and also check if there's an error in each command and echo "Command failed". I can't seen to find a way to do this programmatically I basically want to run the commands without the command's errors output flooding the screen.

example:

array=(
"cat something"
"grep something"
"rm something"
"read -r -p 'something' something"
)
length=${#array[@]}
for (( i=1; i<${length}+1; i++ ));
do
    if echo ${array[$i-1]} | sh 2>/dev/null; then
        echo "command succeded"
    else
        echo "command failed"
    fi
done
Jake Leroy
  • 87
  • 2
  • 7
  • 1
    Works for me with `bash`, if I add a `fi` to fix syntax error. – Cyrus Jun 27 '19 at 05:45
  • Except that `i=1` skips the 1st element of the array, and you can simply use `length` instead of `${length}+1` (one past the end of array) in the `for` loop definition (the `((...))` behaves just like the arithmetic `((...))`) allowing you to simply use `${array[i]}` instead of `${array[$i-1]}` which would technically need to be `${array[$((i-1))]}`. – David C. Rankin Jun 27 '19 at 05:55
  • 1
    The lack of double-quotes around `${array[$i-1]}` can cause weird parsing for some commands. – Gordon Davisson Jun 27 '19 at 05:59
  • You can use `eval` instead of piping to `sh`. – Barmar Jun 27 '19 at 06:09

1 Answers1

-1

I guess this is what you are looking for:

command_list="command1;command2"
       #I tried it with command_list="ls;ls <sub-directory>"
while IFS=';' read -ra command_array; do
      for i in "${command_array[@]}"; do
          # process "$i"
           if ( $i &>/dev/null )
           then
                echo "Success"
           else
                echo "Failed"
           fi
      done
 done <<< $command_list

If you want to know why the while loop is being used read : https://stackoverflow.com/a/918931/11571342

EDIT: As mentioned in the comments there is no way of knowing the exit_status of a command in bash beforehand. You will have to execute the command to check it. But there is a way which could work ( but it usually fails when rm or insatll is used)

while IFS=';' read -ra command_array; do
   for i in "${command_array[@]}"; do
          # process "$i"
          $i &>/dev/null 
          exit_status=$?
          if (( exit_status == 0 ))
          then
          $i
          echo "Success...."
          else
          echo "Failed"
          fi
      done
 done <<< $command_list
  • But what if one of the commands is taking input like "read". I also need to see the output of the command. – Jake Leroy Jun 27 '19 at 08:00
  • @Jake Leroy If you want to see the output of the command then remove `&>/dev/null ` from `if ( $i &>/dev/null )` . If I understood you correctly then you want to print "Command Failed" if it fails otherwise print its output along with "Success". What you are looking for is the `exit_status` of the command which is `$?` in bash. But you won't know the status till you execute the command. You could do this in the for loop as a work-arround`$1 &>/dev/null exit_status=$? if (( $exit_status==0 )) then $1 else echo "Failed" fi` This might fail if you are using commands like install. – Davis080498 Jun 27 '19 at 09:10
  • It's outputting this error: syntax error near unexpected token `$1' – Jake Leroy Jun 27 '19 at 10:35
  • I am sorry....that should have been `$i`. My bad :(. And yes note that this might not always work. The best example I can give you is when you use an `rm ` command. As mentioned earlier you can not know the status of the command till you execute it. – Davis080498 Jun 27 '19 at 11:24
  • I'll make changes in the answer as per this discussion. – Davis080498 Jun 27 '19 at 11:31