Karthik Divi
·4 min read

sh Online Compiler - Write Portable Shell Scripts in the Browser

If your script starts with #!/bin/sh, you are making a promise: this will run on any POSIX-compliant system. Not just Linux with Bash. Any system.

That is harder than it sounds. A lot of "sh" scripts quietly depend on Bash features like arrays, [[ ]], or $((...)) arithmetic. They work fine on Ubuntu where /bin/sh is usually linked to Bash (or dash), then break on Alpine, FreeBSD, or older Unix systems.

An sh online compiler lets you test scripts against a real POSIX shell so you can catch these issues before they surprise you in production.

sh vs Bash: Why It Matters

Bash is sh with extras. Lots of extras. Here is the thing: if you only target Bash, your scripts are less portable. If you write for sh, they run almost everywhere.

Some concrete differences:

  • sh has no arrays. If your script uses arr=(one two three), that is Bash.
  • sh uses [ ] for tests, not [[ ]]. The double-bracket syntax is a Bash extension.
  • No function keyword in POSIX sh. Functions are declared as myfunc() { ... }.
  • String substitution like ${var,,} (lowercase) is Bash-only.
  • echo -e behavior varies. Use printf in sh scripts for consistent output.

When you are writing Dockerfiles, init scripts, CI pipelines, or anything that might run on minimal systems, sticking to POSIX sh is the safer choice.

Example: A Portable System Info Script

This script uses only POSIX sh features. No Bash-isms. Try it on OneCompiler.

#!/bin/sh

# Portable system info script - POSIX compliant

get_uptime_desc() {
  seconds=$1
  days=$((seconds / 86400))
  hours=$(( (seconds % 86400) / 3600 ))
  mins=$(( (seconds % 3600) / 60 ))

  if [ "$days" -gt 0 ]; then
    printf "%d days, %d hours, %d minutes" "$days" "$hours" "$mins"
  elif [ "$hours" -gt 0 ]; then
    printf "%d hours, %d minutes" "$hours" "$mins"
  else
    printf "%d minutes" "$mins"
  fi
}

# Simulate some data since we're in a sandboxed environment
hostname="web-server-01"
user_count=3
uptime_seconds=284712

printf "=== System Report ===\n\n"
printf "Host:    %s\n" "$hostname"
printf "Users:   %d active\n" "$user_count"
printf "Uptime:  %s\n" "$(get_uptime_desc $uptime_seconds)"
printf "\n"

# Demonstrate POSIX-safe string handling
path="/usr/local/bin/myapp"
dir_part="${path%/*}"
file_part="${path##*/}"
printf "Path breakdown:\n"
printf "  Full:  %s\n" "$path"
printf "  Dir:   %s\n" "$dir_part"
printf "  File:  %s\n" "$file_part"

# POSIX-safe iteration (no arrays needed)
printf "\nChecking services:\n"
for service in httpd sshd crond; do
  printf "  [OK] %s\n" "$service"
done

Notice the deliberate choices: printf instead of echo -e, $(( )) for arithmetic (which is POSIX), parameter expansion with % and ## for string manipulation, and a simple for loop over a word list instead of an array.

Why Test sh Scripts on OneCompiler

Writing POSIX-compliant scripts means you need to be disciplined about which features you use. An online sh compiler helps because:

  • It runs your script in an actual sh environment, not Bash pretending to be sh. If you accidentally use a Bash feature, it will fail here.
  • You get instant feedback. Write, run, fix, repeat.
  • Sharing a link to a working POSIX script is useful when contributing to open-source projects that require sh compatibility.
  • No local setup needed. Helpful if your local machine runs Bash by default and you want to verify sh compatibility without installing dash or another minimal shell.

OneCompiler keeps the experience simple. The editor is clean, execution is quick, and you can share your scripts with a URL.

Try It

sh Online Compiler on OneCompiler

If you write scripts that need to be portable, test them in sh first. It will save you from the "works on my machine" problem.