0

New to bash programming. Looking to program if/else by capturing the exit status of a command and printing a response to the screen.

For example, one of the commands may be to create a swap file.

printf ("Creating swap file...", %)
fallocate -l 4G swapfile

if [ $? ]
  echo "ok"
else
  echo "failed"
fi

The output to screen should look like:

Creating swap file...                 ok

Questions:

Is printf the proper command and if so, what do I use for the %?

How do I compare the exist status's for pass/fail?

If more than one command is used, will it just use the last exist status or will it take the fail of any of them to report 'failed'?

  • `echo -n 'Creating swap file... '` . The -n will omit the newline. Then just use the regular echo under your conditional compounds – pah Jul 01 '16 at 13:03

5 Answers5

3

You can do this:

printf "Creating swap file..."
if fallocate -l 4G swapfile; then
  echo "   ok"
else
  echo "   failed"
fi

The "condition" after if is an arbitrary command. If it succeeds (exit status 0), the then block is executed, otherwise the else block. The easiest way to satisfy your requirements is to just put your command(s) inside the if.

melpomene
  • 84,125
  • 8
  • 85
  • 148
3

The if statement's very purpose is to examine a command's exit code.

if fallocate -l 4G swapfile; then
    echo "Success."
else
    echo "Failure."
fi

If you put a compound command or pipeline, the last command's status is the result. This is how the shell works, and is in no way specific to if.

if false; true; then
    echo "Always true"
fi

The command [ examines its argument; it will return true if it is non-empty, as it always will be when the value you examine is $?. You could say [ $? -eq 0 ] but this is obviously just a needless complication. In fact, directly examining $? is almost never necessary; it's a common antipattern (though you see it a lot, because most shell scripts are written by beginners who never learned the language properly).

The printf command is generally to be preferred over echo, but your syntax is incorrect. Try

printf "Creating swap file...\n"

Omit the \n if you don't want a newline.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • See also [Why is testing "$?" to see if a command succeeded or not, an anti-pattern?](https://stackoverflow.com/questions/36313216/why-is-testing-to-see-if-a-command-succeeded-or-not-an-anti-pattern) – tripleee Jun 02 '23 at 08:13
1

This is your code:

printf ("Creating swap file...", %)
fallocate -l 4G swapfile

if [ $? ]
  echo "ok"
else
  echo "failed"
fi

You are using printf oddly. It's an ordinary shell command, so no parentheses are needed. Also, that trailing % look out of place. In this case, and at that point in the code, you have nothing more to output other than a static string, so no format specifier is needed. So, yes, printf is the proper command to use here, because it doesn't output a newline at the end of its output unless you tell it to.

If you'd just want to act on the exit status of fallocate, then you may put the command in the if-statement directly, like this:

printf "Creating swap file...\t"

if fallocate -l 4G swapfile; then
  echo "ok"
else
  echo "failed"
fi

If you have a pipeline, the exit status of the pipeline will be that of the last command in the pipeline:

if cmd1 | cmd2 | cmd3; then
# ...
fi

This is also true for compound commands like cmd;cmd, {cmd;cmd}, (cmd;cmd) etc.

To have pipelines return the exit status of the last command in a pipeline that fails in bash, you will need to set the pipefail option:

set -o pipefail

To get at the exit statuses of the intermediate pipeline commands in bash you may inspect the PIPESTATUS array after executing the pipeline:

$ false | true | true | false
$ echo ${PIPESTATUS[@]}
1 0 0 1
Kusalananda
  • 14,885
  • 3
  • 41
  • 52
0

You need to use an expression http://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html in the if statement:

#!/bin/bash
# ...
if [ $? -eq 0 ]; then
        echo "ok"
else
        echo "failed"
fi
exit 0

Best, Julian

Julian
  • 1,694
  • 22
  • 29
0

This should do what you need. It will omit the newline after printing Creating..... Then it will check the output and print "ok" or "error" on the same line.

echo -n "Creating swap file ... "
fallocate -l 4G swapfile
local status=$?
if [ $status -ne 0 ]; then
    echo "error"
else
    echo "ok"
fi
return $status
cb0
  • 8,415
  • 9
  • 52
  • 80