How to Execute a .sh File in Linux: Methods, Permissions, and What to Know First

Shell scripts are one of Linux's most powerful features — a way to bundle commands, automate repetitive tasks, and control system behavior through a simple text file. But if you've just downloaded or created your first .sh file, the path from "I have this file" to "this file is running" isn't always obvious. Here's what's actually happening under the hood, and the key variables that determine which approach works for your situation.

What a .sh File Actually Is

A .sh file is a plain text file containing a sequence of shell commands. When executed, a shell interpreter — most commonly Bash (/bin/bash) or sh (/bin/sh) — reads those commands line by line and runs them as if you'd typed them yourself in a terminal.

The first line of a well-written shell script usually looks like this:

#!/bin/bash 

This is called a shebang. It tells the operating system which interpreter to use. If that line is missing, the system falls back to a default — which may or may not be what the script expects.

Method 1: Call the Interpreter Directly

The simplest way to run a .sh file — and the one that requires no special permissions on the file itself — is to call the interpreter explicitly:

bash script.sh 

Or with sh:

sh script.sh 

This works because you're not asking Linux to execute the file directly. You're invoking the interpreter and passing the file as an argument. The file doesn't need to be marked as executable for this to work, which makes it a practical starting point when you're testing a new script or working with files you've just received.

When this matters: If you receive a .sh file and run bash script.sh without thinking about permissions, that's not sloppy — it's often the right call.

Method 2: Make the File Executable and Run It Directly

The more "proper" Linux approach involves two steps: granting execute permission, then running the file directly.

Step 1 — Grant execute permission:

chmod +x script.sh 

chmod modifies file permissions. The +x flag adds execute permission for the file owner (and by default, for the group and others too, depending on your umask). You can be more specific:

  • chmod u+x script.sh — only the file owner can execute it
  • chmod 755 script.sh — owner can read/write/execute; group and others can read/execute

Step 2 — Execute the file:

./script.sh 

The ./ prefix tells the shell to look in the current directory for the file. Without it, the shell searches only the directories listed in your $PATH environment variable — and your current working directory typically isn't one of them by default.

If the script is stored in a directory that's already in your $PATH (like /usr/local/bin), you can run it by name alone:

script.sh 

Understanding File Permissions 🔐

Linux uses a three-tier permission model: owner, group, and others. Each tier can have read (r), write (w), and execute (x) permissions.

Permission StringMeaning
-rw-r--r--Owner can read/write; no one can execute
-rwxr-xr-xOwner can execute; group and others can too
-rwx------Only owner can read, write, or execute

You can view a file's current permissions with:

ls -l script.sh 

If you try to run ./script.sh without execute permission set, Linux returns a "Permission denied" error — not because the file is corrupted, but because the execute bit simply isn't set.

Running Scripts with Elevated Privileges

Some scripts need to modify system files, install packages, or interact with hardware — tasks that require root-level access. In those cases, you'll prefix the command with sudo:

sudo bash script.sh 

or, if the file is already executable:

sudo ./script.sh 

⚠️ Running scripts with sudo carries real risk. A script with root access can delete system files, overwrite configurations, or expose security vulnerabilities. Before running any script with elevated privileges, read through its contents first. If you can't read it, that's a meaningful signal.

Running Scripts in the Current Shell vs. a Subshell

This distinction trips up a lot of users. When you run ./script.sh or bash script.sh, the script executes in a subshell — a child process. Any variables set or directory changes made inside the script don't persist in your current terminal session after the script finishes.

If you want the script's changes to apply to your current shell environment, use the source command:

source script.sh 

Or the shorthand:

. script.sh 

This is how tools like virtual environment activators (common in Python development) work — they modify your current shell's state rather than running in isolation.

The Variables That Shape Your Approach

Which method makes sense depends on factors specific to your situation:

  • Where the script came from — a script you wrote yourself is different from one downloaded from the internet or provided by a package
  • What the script does — reading files is very different from modifying system configurations
  • Your permission level — regular user, sudoer, or root access each opens or closes different paths
  • Whether the script needs to modify your environment — that determines subshell vs. source execution
  • The interpreter the script expects — a script written for Bash may behave differently or fail when run with sh on systems where sh is dash rather than Bash

Most Linux distributions use Bash as the default interactive shell, but /bin/sh may point to a lighter interpreter like dash, which doesn't support all Bash-specific syntax. If a script starts with #!/bin/bash, calling it with sh can cause unexpected errors — even if the individual commands look standard.

The method that works cleanly for one script, on one system, for one user may not be the right default for every scenario you encounter.