Difference between "./" and "sh" in UNIX
Categories:
Understanding './' vs. 'sh' for Script Execution in UNIX

Explore the fundamental differences between executing a script using './script.sh' and 'sh script.sh' in UNIX-like operating systems, including implications for permissions, shell invocation, and portability.
In UNIX-like operating systems, executing shell scripts is a common task. However, new users often encounter two primary methods for running a script: ./script.sh and sh script.sh. While both can achieve the goal of running a script, they operate under different mechanisms and have distinct implications for how the script is interpreted and executed. Understanding these differences is crucial for writing robust, portable, and secure shell scripts.
Method 1: Direct Execution with './'
When you execute a script using ./script.sh, you are instructing the operating system to run the file directly. For this to work, two conditions must be met:
- Executable Permissions: The script file must have executable permissions set for the current user. This is typically achieved using
chmod +x script.sh. - Shebang Line: The script must contain a 'shebang' line (e.g.,
#!/bin/bashor#!/usr/bin/env python) as its very first line. This line tells the operating system which interpreter to use to execute the script. The kernel reads this line and then invokes the specified interpreter, passing the script file as an argument to it.
#!/bin/bash
echo "Hello from direct execution!"
chmod +x example.sh
./example.sh
Method 2: Explicit Interpreter Invocation with 'sh'
When you execute a script using sh script.sh, you are explicitly telling the sh (Bourne shell or its compatible successor, often bash or dash) interpreter to read and execute the contents of script.sh. In this scenario:
- Permissions: The script does not need executable permissions. It only needs read permissions, as
shis simply reading the file's contents. - Shebang Line: The shebang line in the script is effectively ignored. The script will always be interpreted by the
shshell that you explicitly invoked, regardless of what the shebang line specifies. This can lead to unexpected behavior if the script was written for a different shell (e.g.,bashspecific features) but is executed with a more basicsh.
#!/bin/bash
echo "Hello from explicit sh invocation!"
chmod -x example2.sh # Ensure it's not executable
sh example2.sh
flowchart TD
A[User executes command] --> B{Command: './script.sh' or 'sh script.sh'?}
B -- './script.sh' --> C{Script has executable permissions?}
C -- No --> D[Error: Permission denied]
C -- Yes --> E{Script has Shebang?}
E -- No --> F[Error: No interpreter specified]
E -- Yes --> G[Kernel invokes Shebang interpreter]
G --> H[Script executed by Shebang interpreter]
B -- 'sh script.sh' --> I{Script has read permissions?}
I -- No --> J[Error: Permission denied]
I -- Yes --> K[Explicitly invoke 'sh' interpreter]
K --> L[Script executed by 'sh' interpreter (Shebang ignored)]
H & L --> M[Script execution complete]Execution Flow for './' vs. 'sh' Commands
sh script.sh. This makes your script self-documenting and allows for direct execution if permissions are set correctly.Key Differences and Best Practices
The choice between ./ and sh depends on your specific needs and the context of the script. Here's a summary of the key differences and some best practices:
- Permissions:
./requires executable permissions;shonly requires read permissions. - Interpreter:
./relies on the shebang line;shforces the script to be interpreted bysh(or its linked shell), ignoring the shebang. - Portability: Using
sh script.shcan sometimes be more portable if you want to ensure the script runs with a POSIX-compliant shell, even if the user's default shell isbashorzshwith non-POSIX features. However, if your script usesbash-specific features, forcingshmight break it. - Security: Direct execution (
./) is generally preferred for scripts intended to be run as standalone programs, as it leverages the system's shebang mechanism. Explicit invocation (sh script.sh) can be useful for testing or when you specifically want to override the shebang.
Best Practice: For most general-purpose scripts, use a shebang (e.g., #!/bin/bash or #!/usr/bin/env bash) and make the script executable (chmod +x). Then, execute it directly using ./script.sh. This ensures the script runs with its intended interpreter and is self-contained.
./. Always inspect the script's content before granting executable permissions or running it, as it could contain malicious commands.