Bash Gotchas That Will Surprise JavaScript and C# Developers
- AI-GENERATED published: October 24, 2025 estimate: 2 min read view-cnt: 0 views
Introduction
If you’re a JavaScript or C# developer venturing into bash scripting, prepare for a culture shock. Here are the gotchas that will make you question everything.
Spaces Are Syntax
In most languages, whitespace is forgiving. Not in bash.
# This works - spaces required around brackets
if [[ $x -eq 5 ]]; then
# This works - NO spaces around =
x=5
# This FAILS - spaces make bash think "x" is a command
x = 5
Assignment requires NO spaces around equals. Conditionals require spaces around brackets. Miss one space and you’ll get cryptic “command not found” errors.
Single vs Double Brackets
Speaking of conditionals, [ ] and [[ ]] look similar but behave very differently.
[ ] is a command (old POSIX test) with word splitting. [[ ]] is a safer bash keyword:
x="" # empty variable
# FAILS - word splitting breaks it
if [ $x -eq 5 ]; then
# Works - quoted variable
if [ "$x" -eq 5 ]; then
# Works - no word splitting in [[]]
if [[ $x -eq 5 ]]; then
[[ ]] supports pattern matching and regex. Prefer [[ ]] for bash; use [ ] for POSIX compatibility.
Exit Codes Are Backwards
Success is zero. Failure is non-zero. Opposite of JavaScript’s truthy/falsy.
# 0 means success!
if [ $? -eq 0 ]; then
echo "Command succeeded"
fi
It makes sense: there’s one way to succeed, many ways to fail.
String Comparison Traps
Bash needs different operators for strings vs numbers.
[ "5" = "5" ] # String comparison (correct)
[ "5" -eq "5" ] # Numeric comparison (also works)
[ "05" = "5" ] # False - strings differ
[ "05" -eq "5" ] # True - numeric comparison
Use -eq, -ne, -lt, -gt for numbers. Use =, != for strings.
Arrays Start at Zero, But…
Arrays are zero-indexed, but the syntax is bonkers:
arr=(one two three)
echo ${arr[0]} # "one"
echo $arr # Also "one" - without brackets!
echo ${arr[@]} # All elements
echo ${#arr[@]} # Array length
Curly braces and @ required beyond the first element.
Quotes Matter Everywhere
files="file with spaces.txt"
rm $files # Tries to delete "file", "with", "spaces.txt"
rm "$files" # Deletes the correct file
Unquoted variables split on whitespace. Always quote.
Return Values Are Limited
Functions can only return integers 0-255. Want to return a string? Use echo and capture it with command substitution:
get_name() {
echo "John"
}
name=$(get_name) # Capture stdout
Conclusion
These gotchas stem from bash’s shell heritage. Learn them once, and muscle memory takes over.
Happy scripting!
No comments yet
Be the first to comment!