Testing a bash shell script [duplicate] - bash

This question already has answers here:
Bash and Test-Driven Development
(8 answers)
Unit testing Bash scripts
(16 answers)
Closed 5 years ago.
Can someone explain how to test for a bash shell script?
For example i've got a .sh file with this code in it...
#!/bin/sh
for file in *.txt; do
mv "$file" "`basename $file .txt`.doc"
done
How do I write a test for it? Like in Java you've got unit testing where you write code like assertEquals to test the code gives the desired output.

Try this out: assert.sh
source "./assert.sh"
local expected actual
expected="Hello"
actual="World!"
assert_eq "$expected" "$actual" "not equivalent!"
# => x Hello == World :: not equivalent!

You can do asserts in Bash. Check out this from the Advanced Bash-Scripting Guide:
http://tldp.org/LDP/abs/html/debugging.html#ASSERT

I'd add an echo in front of the mv to verify that the right commands are being created, for starters. (Always a good idea with commands that make possibly difficult to undo changes.)
Some possibly useful resources:
shUnit2 — xUnit framework for script unit testing
Bash IDE for Vim
Bash debugger

Related

BASH echo showing some unusual behaviour [duplicate]

This question already has answers here:
Strange "echo" behavior in shell script
(3 answers)
Variables overwriting text problem with "echo" in Bash
(2 answers)
Closed 3 years ago.
This is the simple command that is giving me problems -
echo hafsda sfsdfdsfs $ymn $ymx $range
The output of this command is coming -
2.568 sfsdfdsfs 86.72
Where ymn = 86.72 ymx = 89.28 and range = 2.56. This only happens when I am using variables. The following command works fine -
echo hafsda sfsdfdsfs 1 2 $range
Also, the same command (the first one) works fine if I try running it directly in the terminal. This is only happening is a script. I also tried to use printf but encountered similar results.
I don't even understand what to google for to resolve this. I am unable to understand what is happening at all. So, what is happening here? Is this reproducible or is this just some error on my system, and if it is, what might be the problem?
Your script probably has DOS-style CRLF line endings. I suspect you actually have ymn="86.72\r" ymx="89.28\r" and range="2.56\r". You can test this in your script with
echo hafsda sfsdfdsfs $ymn $ymx $range | od -c
You can fix your script with dos2unix or sed -i 's/\r$// script.sh`.
Make sure you change the settings of your text editor do use unix line endings.

Why does this for loop run in terminal but not via script? [duplicate]

This question already has answers here:
How can I trigger brace expansion inside a script?
(2 answers)
Difference between sh and Bash
(11 answers)
Closed 4 years ago.
I have a perfectly functional script
for i in {1..15}
do
amixer -D pulse sset Master 1%+;
done
But the command only runs once when i call it as ./volume.sh. If I copy and paste the code into the terminal, it runs fine. What's the difference?
I'm posting this answer because I found it very hard to find the solution anywhere else.
You need to add #!/bin/bash to the top of the script
#!/bin/bash
for i in {1..15}
do
amixer -D pulse sset Master 1%+;
done
This header hints the terminal to run this script as bash instead of something else. It's not just a decoration.

unable to run shell script compiler binary which having dependency internally with another shell script [duplicate]

This question already has an answer here:
Cannot `source` shc-compiled scripts
(1 answer)
Closed 6 years ago.
I have two shell scripts which have dependencies. Using shc compiler i created two binaries. But while running one binary, it is unable to resolve dependent binary. I am seeing below error:
line 1 : ???? :command not found
How to deal with shell scripts which have dependencies.
//first_shellscript.sh
#!/bin/bash
get_network_status()
{
network_status=`ifconfig`
if [ $network_status -eq 0 ]; then
echo $network_status
else
echo "1"
fi
} is shell script used by below shell script
//second_shellscript.sh
#!/bin/bash
source /path/first_shellscript.sh
get_network_status;
shc is not exactly a compiler but it rather encrypts and places the script within a C file.
It is not possible to use multiple scripts and source to work within a script that has to be "compiled" by shc. Only way out is to put everything in a single script.
Please read this reference post

How to know which line in a bash script is causing trouble? [duplicate]

This question already has answers here:
How can I debug a Bash script? [closed]
(12 answers)
Closed 8 years ago.
For example, I'm writing a bunch of iptables rules in a bash script. When I run the script, shell says iptables: No chain/target/match by that name. I don't know what's going on so I copy and paste every line into shell and run them separately to figure out which line is causing trouble. BTW. it turns out that I put "OUTUT" instead of "OUTPUT" in one rule.
Is there anyway that shell can tell me like [line 53]: iptables: No chain/target/match by that name., so I know where the problem is?
I'm not bash expert but what I was doing is adding echo with information regarding the progress and read (wait until keypressed) that will let me do the process step by step.
Nearly all programs return success and error conditions. You can include error checking for each program your script calls, and take appropriate action on error (like undoing previous work, exiting out, etc). This is particularly useful if line 4 should never execute if line 3 fails.
The exit status of the program you just called is stored in $? .
Example (pseudocode - you'll need to modify the syntax to be correct)
Iptables foo bar baz; if ($? != 0) echo 'failed to update iptables' && exit 1; fi
additionally, you can turn on various levels of tracing with set -f , set -v , and set -x . See the links below for full details.
http://tldp.org/LDP/abs/html/exit-status.html
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html

Bash syntax error: "[[: not found" [duplicate]

This question already has answers here:
Difference between sh and Bash
(11 answers)
Closed 2 years ago.
The community is reviewing whether to reopen this question as of 5 days ago.
I'm working with a bash script that is currently working on a server (RHEL4). I'm developing on my laptop with Ubuntu 10.04, but I don't think the platform is causing the problem.
Here's what's happening:
I have a skeleton script that calls another script that does most of the work. However, it makes calls to getConfig.sh a lot. getConfig.sh basically just parses some command line argument (using getopts) and calls a Java program to parse some XML files. Anyways, getConfig.sh is throwing up lots of errors (but still seems to work).
Here's the message that I'm getting
getconfig.sh: 89: [[: not found
getconfig.sh: 89: [[: not found
getconfig.sh: 94: [[: not found
I get those three errors every time it runs; however, the script completes and the Java code runs.
Here's the relavent code section
parseOptions $*
if [[ "${debugMode}" == "true" ]] ; then
DEBUG="-DDEBUG=true"
echo "${JAVA_HOME}/bin/java ${DEBUG} -Djava.endorsed.dirs=${JAXP_HOME} -jar $(dirname $0)/GetXPath.jar ${XML_File} ${XPath_Query}"
fi
Line 89 is "parseOptions $* and line 94 is "fi"
Thanks for the answers.
If your script is executable and you are executing it like ./getconfig.sh, the first line of your script needs to be:
#!/bin/bash
Without that shebang line, your script will be interpreted by sh which doesn't understand [[ in if statements.
Otherwise, you should run your script like bash getconfig.sh, not sh getconfig.sh. Even if your default shell is bash, scripts run with sh will use a reduced set of bash's features, in order to be more compliant with the POSIX standard. [[ is one of the features that is disabled.
Use:
bash scriptname.sh
instead of:
sh scriptname.sh
If you are checking for equality, shouldn't the if be ?
if [[ "${debugMode}" = "true" ]]; then
....
fi

Resources