Keywords: Linux permissions | sudo command | PATH environment variable | chmod | command not found
Abstract: This article provides a comprehensive analysis of 'Permission denied' and 'command not found' errors when executing scripts with sudo in Linux systems. By examining file permission mechanisms and PATH environment variable differences, it explains the root causes and solutions, including chmod permission settings, PATH environment variable workings, and environmental isolation during sudo execution. The article combines practical cases to offer complete troubleshooting procedures and effective repair methods.
File Permissions and Execution Rights Fundamentals
In Linux systems, executing script files requires appropriate execution permissions. When users attempt to run ./foo.sh and encounter -bash: ./foo.sh: Permission denied error, this indicates the file lacks execution permission bits.
The Linux file permission system is based on three fundamental permissions: read (r), write (w), and execute (x). These permissions are allocated to the file owner, group, and other users respectively. Detailed permission information can be viewed using the ls -l command:
$ ls -l foo.sh
-rw-r--r-- 1 rkielty users 0 2012-10-21 14:47 foo.shIn the permission string -rw-r--r--, the first character - indicates a regular file, followed by three sets of rwx representing owner, group, and other users' permissions. In this example, the owner has read and write permissions (rw-), but lacks execution permission (x).
Setting Execution Permissions with chmod
The chmod command is used to modify file permission modes. To add execution permission to foo.sh, use:
$ chmod +x foo.sh
$ ls -l foo.sh
-rwxr-xr-x 1 rkielty users 0 2012-10-21 14:47 foo.shAfter executing chmod +x, the permission string changes to -rwxr-xr-x, indicating that owner, group, and other users all have execution permissions. At this point, directly executing ./foo.sh should work normally.
PATH Environment Variable Issues with sudo Execution
When using sudo ./foo.sh results in sudo: foo.sh: command not found error, this is unrelated to file permissions but caused by differences in PATH environment variables.
The sudo command executes commands with superuser (root) privileges, but the root user's PATH environment variable may differ from ordinary users. The PATH variable defines the list of directories where the system searches for executable files. When a command is entered, the system looks for corresponding executable files in these directories in the order defined by PATH.
Comparing PATH variables of ordinary users and root users:
$ env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
$ sudo env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/binAlthough both PATH variables contain similar system directories, their specific contents differ. More importantly, the current directory (.) is typically not in root's PATH, so sudo foo.sh cannot find script files located in the current directory.
PATH Environment Variable Working Mechanism
The PATH environment variable works as follows: when a user enters a command, the system sequentially searches for corresponding executable files in directories listed in PATH. For example, if PATH is set to /usr/local/bin:/usr/bin:/bin, when entering the ls command, the system will check /usr/local/bin/ls, /usr/bin/ls, and /bin/ls in order.
When using relative paths (like ./foo.sh), the system directly searches for files at the specified path without relying on the PATH variable. However, when using sudo foo.sh (without path prefix), the system only searches in directories defined by PATH, and the current directory is typically not included.
Solutions and Best Practices
For the sudo: foo.sh: command not found problem, the following solutions are available:
Solution 1: Use Full Path
Specify the script's complete path directly:sudo /home/user/foo.sh
Solution 2: Maintain Relative Path
Even with sudo, continue using relative paths:sudo ./foo.sh
But ensure the script has execution permissions.
Solution 3: Modify Root's PATH Variable
Preserve current user's environment variables through sudo -E:sudo -E env "PATH=$PATH" ./foo.sh
This method temporarily passes the current user's PATH to the sudo execution environment.
Solution 4: Create Aliases
Create aliases for frequently used commands to simplify operations:alias mysudo='sudo -E env "PATH=$PATH"'
Then use:mysudo ./foo.sh
Practical Case Analysis
The Maven installation case mentioned in the reference article further illustrates PATH environment variable issues. After users add Maven path to /etc/profile and execute source /etc/profile, ordinary users can normally execute mvn --version, but using sudo mvn --version results in command not found error.
This occurs because environment variable settings in /etc/profile only affect ordinary user sessions, while sudo execution uses root user's environment configuration. The fact that sudo su - switching to root user can find the mvn command confirms the existence of environment variable differences.
Summary and Recommendations
The Linux permission and environment variable system design ensures system security and isolation. Understanding file permission mechanisms and PATH environment variable workings is crucial for effective system management.
In practical operations, it is recommended to:
- Always set correct execution permissions for script files that need execution
- Understand environmental isolation mechanisms during sudo execution
- Choose appropriate solutions based on specific requirements
- Consider creating aliases or modifying system configurations for frequently used commands
By deeply understanding these underlying mechanisms, users can more effectively diagnose and resolve permission and environment variable related issues in Linux systems.