How to Create and Run a Bash Script in Termux
How to Create and Run a Bash Script in Termux (Step-by-Step Guide)
Turning your Android smartphone into a functional Linux automation powerhouse is one of the most compelling reasons to use Termux. By leveraging a bash script in Termux, you can automate repetitive tasks, execute multi-step terminal operations with a single trigger, and build lightweight local server management workflows right from your pocket. However, moving from typing individual shell commands to writing executable script files often comes with unexpected roadblocks—most notably permission errors, path issues, and file system restrictions unique to Android.
This comprehensive tutorial walks you step-by-step through creating, editing, granting execution permissions, and running shell scripts in Termux. We will also address the infamous run .sh file termux permission denied error in depth, ensuring you possess the technical foundation needed to automate anything on your Android device cleanly and efficiently.
Quick Summary: How to Run a Bash Script in Termux
If you need an immediate reference to create and execute a script right away, follow these four core commands directly inside your Termux terminal:
# Step 1: Create or open a script file using Nano
nano myscript.sh
# Step 2: Add your shebang and script code inside the editor
#!/data/data/com.termux/files/usr/bin/bash
echo "Termux script is running!"
# Step 3: Save and exit (Press CTRL + O, Enter, then CTRL + X)
# Step 4: Grant execution permissions and run
chmod +x myscript.sh
./myscript.sh
| Action | Command / Syntax | Purpose |
|---|---|---|
| Create / Edit | nano filename.sh |
Opens text editor to write shell commands. |
| Grant Permission | chmod +x filename.sh |
Makes the .sh file executable by the terminal. |
| Direct Execution | ./filename.sh |
Runs the script directly from the current directory. |
| Interpreter Execution | bash filename.sh |
Runs the script using Bash without needing chmod +x. |
Prerequisites: Preparing Your Termux Environment
Before writing shell scripts, you must ensure your Termux environment is properly updated and equipped with a command-line text editor. Standard Linux distributions usually come pre-loaded with various tools, but Termux provides a minimal base installation to keep file sizes low.
1. Update Existing Packages
First, update the package list and upgrade existing binaries to prevent dependency conflicts during software installations:
pkg update && pkg upgrade -y
2. Install a Text Editor
You need a terminal-based text editor to create and modify script files. Nano is the most beginner-friendly editor available in Termux, though experienced users can opt for Vim or Micro.
pkg install nano -y
3. Set Up Storage Access (Optional but Recommended)
If your script needs to read or write files to your Android device’s internal storage (such as your Downloads folder or Documents), grant Termux permission to access shared storage:
termux-setup-storage
A popup prompt will appear on your Android screen requesting storage access. Tap Allow to proceed.
Step 1: Understanding the Shebang Line in Termux
Every proper bash script in Termux starts with a specialized line called a Shebang (or Hashbang). It starts with #! followed by the absolute path to the shell interpreter that will execute the commands inside the file.
In standard Linux desktop systems (like Ubuntu or Debian), the path to the Bash interpreter is usually #!/bin/bash or #!/usr/bin/bash. However, Termux does not follow standard Linux filesystem hierarchy standards (FHS). Because Termux operates within an Android app sandbox without root privileges, its binary files reside deep inside the app directory structure.
The precise Termux Bash shebang path is:
#!/data/data/com.termux/files/usr/bin/bash
Alternatively, you can use the environment locator shebang, which makes your script portable across both Termux and standard Linux operating systems:
#!/usr/bin/env bash
Using #!/usr/bin/env bash instructs Termux to look up the location of Bash dynamically through your environment’s $PATH variable, avoiding absolute path hardcoding errors.
Step 2: Creating Your First Bash Script
Now that your environment is ready and you understand the shebang structure, let's create a simple script that collects user input and outputs system status info.
1. Open Nano and Create the File
In your Termux home directory, type the following command to launch Nano with a new file named system_info.sh:
nano system_info.sh
2. Write the Script Code
Type or paste the following code block into your Nano interface:
#!/data/data/com.termux/files/usr/bin/bash
# Clear terminal screen
clear
# Display welcome message
echo "======================================"
echo " Termux System Information Tool "
echo "======================================"
# Read user input
echo -n "Enter your operator name: "
read operator_name
echo ""
echo "Hello, $operator_name!"
echo "Today is: $(date)"
echo "Current Directory: $(pwd)"
echo "Termux Storage Path: $HOME"
echo "======================================"
3. Save and Exit Nano
Follow these quick keyboard combinations to save your file inside Nano:
- Press
CTRL+O(WriteOut) to save the file changes. - Press
Enterto accept the default file name (system_info.sh). - Press
CTRL+Xto exit the Nano text editor.
Step 3: Executing the Script & Terminal Output
Once saved, try running the script directly using its relative path:
./system_info.sh
If this is your first time creating a file in Termux, you will immediately encounter the following error:
bash: ./system_info.sh: Permission denied
Do not panic—this behavior is completely intentional under Linux security policy. Newly created files lack execute permissions by default. Let's fix this in the next section.
Fixing the "run .sh file termux permission denied" Error
The error message run .sh file termux permission denied occurs because the Linux file system protection layer flags newly created files as read-and-write only. To turn a plain text file into a runnable script, you must explicitly grant the execute permission bit (+x).
$ ./system_info.sh
bash: ./system_info.sh: Permission denied
$ ls -l system_info.sh
-rw-r--r-- 1 u0_a245 u0_a245 342 Oct 24 10:15 system_info.sh
$ chmod +x system_info.sh
$ ls -l system_info.sh
-rwxr-xr-x 1 u0_a245 u0_a245 342 Oct 24 10:16 system_info.sh
$ ./system_info.sh
======================================
Termux System Information Tool
======================================
Enter your operator name: Alex
Hello, Alex!
Today is: Thu Oct 24 10:17:02 UTC 2024
Current Directory: /data/data/com.termux/files/home
Termux Storage Path: /data/data/com.termux/files/home
======================================
Fix Method 1: Using chmod to Grant Execute Permissions (Recommended)
To grant permission to execute your .sh file, run the chmod command in Termux:
chmod +x system_info.sh
Alternatively, you can set permission bits numerically using octal mode (755 grants full permission to the file owner and read/execute rights to others):
chmod 755 system_info.sh
Now, run the file again:
./system_info.sh
The script will now execute successfully without any permission warnings.
Fix Method 2: Running via Bash Directly (Bypass Execution Bits)
If you choose not to alter file permissions with chmod, you can bypass permission checks by passing the file as an argument directly into the Bash interpreter binary:
bash system_info.sh
This method works regardless of whether the script has the execute (+x) flag enabled, provided your user profile retains read access to the file.
Fix Method 3: Script Saved on Shared Storage (/sdcard)
If you stored your .sh script in your phone's main storage (e.g., inside /sdcard/ or /storage/emulated/0/Download/), executing chmod +x script.sh will fail silently or return permission errors.
Why does this happen? Android mounts internal shared storage using host file systems (such as FAT32, exFAT, or sdcardfs) configured with strict noexec mount flags. This prevents any script located outside of Termux’s internal app sandbox from obtaining direct execution flags.
Solutions for files on shared storage:
- Option A: Call the script explicitly using the shell binary:
bash /sdcard/Download/myscript.sh - Option B: Copy the file to Termux's local home directory before executing:
cp /sdcard/Download/myscript.sh $HOME/ cd $HOME chmod +x myscript.sh ./myscript.sh
Advanced Practical Examples for Termux Scripts
To give you a better understanding of practical scripting automation, here are two real-world operational scripts tailored specifically for Termux users.
Example 1: Termux Auto-Updater and Maintenance Script
This script updates packages, removes unnecessary cached file bloat, and checks storage usage in a single step.
#!/data/data/com.termux/files/usr/bin/bash
echo "[+] Starting Termux System Cleanup & Maintenance..."
echo "----------------------------------------------------"
# Update package index and packages
pkg update -y && pkg upgrade -y
# Remove outdated package caches
pkg clean
# Display local storage usage
echo "----------------------------------------------------"
echo "[+] Maintenance complete. Checking storage space:"
df -h $HOME
echo "----------------------------------------------------"
echo "[+] All tasks finished successfully."
Example 2: Interactive Backup Script to Shared Storage
This script compresses files inside your Termux home directory into a single tar archive and safely copies them to your Android device’s Download folder.
#!/data/data/com.termux/files/usr/bin/bash
# Configuration
BACKUP_DIR="$HOME/backups"
DESTINATION="/sdcard/Download"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
ARCHIVE_NAME="termux_backup_$TIMESTAMP.tar.gz"
# Ensure local backup directory exists
mkdir -p "$BACKUP_DIR"
echo "=========================================="
echo " Termux Interactive Backup Script "
echo "=========================================="
echo "[+] Compressing home folder files..."
tar -czf "$BACKUP_DIR/$ARCHIVE_NAME" --exclude="backups" -C $HOME .
if [ -f "$BACKUP_DIR/$ARCHIVE_NAME" ]; then
echo "[+] Archive created: $ARCHIVE_NAME"
echo "[+] Transferring archive to Downloads folder..."
cp "$BACKUP_DIR/$ARCHIVE_NAME" "$DESTINATION/"
echo "[SUCCESS] Backup stored safely at $DESTINATION/$ARCHIVE_NAME"
else
echo "[ERROR] Backup process failed!"
exit 1
fi
Troubleshooting Common Errors in Termux Scripting
Beyond execution permission problems, shell scripting inside Android brings specific edge cases. Use this troubleshooting table to quickly resolve syntax or operational issues.
| Error Message | Probable Cause | Exact Solution |
|---|---|---|
bash: ./script.sh: Permission denied |
Missing executable file flag, or file is stored on /sdcard/. |
Run chmod +x script.sh or execute using bash script.sh. Move file to $HOME if on SD card. |
bash: ./script.sh: No such file or directory |
Incorrect Shebang path OR Windows CRLF line endings in script file. | Fix shebang path to #!/data/data/com.termux/files/usr/bin/bash. Convert line endings via dos2unix script.sh. |
command not found |
Missing Linux package utility or typo in script text. | Install required missing package using pkg install package-name. |
Permission denied (when accessing files) |
Termux lacks access permissions to Android storage. | Run termux-setup-storage and grant access on the device popup screen. |
Fixing Line-Ending Issues (CRLF vs LF)
If you create or edit shell scripts on Windows using text editors like Notepad or VS Code and transfer them to Termux, your execution might fail with perplexing errors like bash: ./script.sh: No such file or directory.
This happens because Windows uses CRLF (Carriage Return + Line Feed) line breaks, while Linux/Termux requires standard LF line breaks. To fix Windows line format issues inside Termux, install the dos2unix utility:
pkg install dos2unix -y
dos2unix myscript.sh
Running this command immediately strips bad carriage return characters (\r), turning your file into a clean, working Linux shell script.
Best Practices for Writing Termux Scripts
- Keep Scripts in the Termux Home Directory: Store script files under
$HOME(/data/data/com.termux/files/home) instead of internal storage paths (/sdcard) to maintain native file permission functionality without mount restrictions. - Always Use Double Quotes Around Variables: Path names on mobile devices frequently contain spaces or unusual characters. Always wrap string variables in double quotes (e.g.,
"$FILE_PATH"instead of$FILE_PATH). - Set Safety Flags: Include
set -enear the top of complex scripts to instruct Bash to abort execution instantly if any single command encounters an error. - Use Meaningful Exit Codes: Exit scripts cleanly with
exit 0on success, or non-zero codes (likeexit 1) when failures occur to assist conditional tracking.
Frequently Asked Questions (FAQs)
1. How do I run a bash script in Termux automatically when the app opens?
To run a script automatically upon opening Termux, append the execution command to your shell startup file located at ~/.bashrc. Open it using Nano: nano ~/.bashrc, add the line ./myscript.sh at the bottom, and save the file.
2. Can I run Bash scripts in Termux without root access?
Yes, absolutely. The vast majority of standard Bash scripting capabilities—including file management, network requests, loops, conditional statements, package management, and variable declarations—work fully without requiring device root access.
3. Why doesn't #!/bin/bash work in Termux scripts?
Unlike regular Linux distributions, Termux does not place binary files under standard root directories like /bin/ or /usr/bin/ unless you install the termux-exec package or use root environment hacks. Use #!/data/data/com.termux/files/usr/bin/bash or #!/usr/bin/env bash instead.
4. How do I stop a running bash script stuck in an infinite loop?
Press CTRL + C on your soft keyboard or physical keyboard to send an interrupt signal (SIGINT) to terminating active foreground scripts in Termux.
What to Do Next
Now that you know how to build, permission-test, and execute shell scripts on Android, you are ready to explore advanced system automation techniques.
Take your skills to the next level by reading our detailed follow-up guide: How to Automate Script Execution in Termux Using Cron Jobs. Learn how to schedule your freshly written scripts to run automatically in the background at set intervals, times, or days!
Join the conversation