0

Trying to implement self syntax checking in bash script test.sh to run syntax check before script will be executed.

error_exit()
{
        echo -e "$1" 1>&2
        exit 1
}
bash -n "$(basename $BASH_SOURCE)"
RESULT=$?
if [ $RESULT == 0 ]; then
  echo "[OK] Test pass"
else
  error_exit "Something is not right :( \n check the sytntax"
fi
starting-script

bash -n , same as bash -x does the job if there are some serous syntax errors but minor errors like:

echo "somthing" && sleep5&&
./test.sh: line 14: sleep5: command not found

are ignored...

is there any way to process a full syntax check plus may be running scrip in some sort of "sandbox mode"/"simulation mode" to catch all possible errors, and return with error if any?

edited In cases when script has to copy some part of the script in tot the remote server, for instance script to install nagios on hundreds of slave(monitored servers) etc. Unfortunately text copying do not always goes smoothly, and errors can be caused by occurred errors while automatically copying script as a text, and it is important to check and end script, if any errors are detected.

4
  • I don't know how you can test for all runtime errors without actually running the script. What you are describing is some sort of global error handling and the closest you can get is with set -e such that the script exits on the first error so that you can address the situation without cascading effect. Feb 17, 2017 at 3:12
  • 1
    I don't know what you mean by text copying does not go smoothly? You need error handling to resolve this problem. This is starting to sound like an X Y Problem. Feb 17, 2017 at 3:13
  • Aaron Copley , :) Unfortunately in real life this things happen, when transferring data remotely anything may happen ;), this is why it is a gud practice to implement a "total check and then run system" :) , of cause depends who u are working for, and what can be the consequences :)
    – Zaza
    Feb 17, 2017 at 13:04
  • I am new to computers and the World Wide Web. I had to get my son to show me how to get to this page. Feb 20, 2017 at 23:09

3 Answers 3

2

As @techraf and @Wice22 pointed out, there is no such thing as a complete check at run-time.

You could create "unit" tests for your bash script though. One framework which helps with it is BATS: https://github.com/sstephenson/bats
Those tests could be run by a CI system on every commit to your git repo, so you would see if you messed up way before those scripts hit production.

However with BATS there is no automatic test for your scripts, but you have to implement every test on your own.

EDIT: In regards to your edit: you could create a md5sum of the script that would be copied, copy them both (remote script and md5sum file) and check remotely if the script is still matching the md5sum.

2
  • Brilliant Idea with md5sum, wondering how I did not come with it by my self :) , Comparing with some set "etalon" would do too, using diff compare result in IF statement...
    – Zaza
    Feb 17, 2017 at 13:08
  • using a hash ((md5|sha*)sum) has the advantage that it changes even on transmission errors where the overall size (for example) stays the same - this may be a small risk, but nevertheless it is there. so comparing size, lines of code, or similar stuff may work, but hashes give you a bigger level of security. Feb 17, 2017 at 14:40
5

You might have a look at the ShellCheck project which performs a more thorough validation of shell script syntax; including best practices and potential pitfalls.

However, even ShellCheck won't report the example from your question as incorrect, because there is no syntax error.

You are calling an external command sleep5 which is a syntactically valid action.

Use variables and check if commands exist before calling them, and fail gracefully if they don't.

5
  • yes , you are right, to catch all errors something more that a simple syntax check is required... updating a question
    – Zaza
    Feb 17, 2017 at 2:01
  • You asked a question and I answered it. Users who change the question, because they got an answer and realised they asked a wrong one are pretty annoying, you know...
    – techraf
    Feb 17, 2017 at 2:05
  • techraf, I understand your frustration but, I'm trying to get a solution, which never been discussed on the site.. your answer points to right direction...described error is not a syntax error, you are right, but do not answers to main question, How to catch such errors, even if they are not syntax ones.
    – Zaza
    Feb 17, 2017 at 2:16
  • You are supposed to ask a new question if you notice this one was the wrong question asked in the first place. Just give @techraf the credit he/she deserves and open another question for your problem. Feb 17, 2017 at 8:03
  • I do appreciate techrafs effort, and I did give him a like point +1, but answer Do Not solves the problem described, only clarifies the course of the problem! And I do not think it is a gud practice creating a duplicate questions around the same issue. The credit was given to Phillip, his answer Solves the problem described !
    – Zaza
    Feb 17, 2017 at 13:14
1

There is no such thing ans "sandbox mode" in bash as far I'm aware of, no try/catch eater To catch the errors in bash you need to run the script. Try this thread https://stackoverflow.com/questions/22009364/is-there-a-try-catch-command-in-bash You may simulate a bailing outs by using sub shells as shown there, Using that techniques you may be able to stop the script on any point, if "exception" is detected, but this is not a simulation. so it would be something like this:

#!/bin/bash
script_name=$(basename $0)
error_exit() { echo -e "${script_name} file:  ${1:-"Unknown Error"}" 1>&2
exit 1
}
bash -n "$(basename $BASH_SOURCE)"
RESULT=$?
if [ $RESULT == 0 ]; then
  echo $" ${green}[OK] Test pass${reset} "
else
  error_exit "syntax error detected"
fi
echo "Check pass ok"

bash -e <<TRY
  echo "" && sleep5
  echo"and_somthing else"
  echo"and_some_more stuff"
  echo"and some_more"
TRY
if [ $? -ne 0 ]; then
  error_exit "error detected"
fi
echo "continuing if all goes well"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .