Keywords: ADB Shell | su command | Android script execution
Abstract: This article provides an in-depth exploration of how to correctly use the su command via ADB Shell to execute scripts on rooted Android devices. It begins by analyzing the working principles of the su command and its behavioral differences in interactive shells versus script execution. The article then details the proper method for executing single commands using the su -c parameter, with concrete code examples to avoid common syntax errors. Additionally, it compares variants of the su command across different operating system environments and offers practical debugging tips and best practice recommendations.
In Android development and system administration, executing device commands remotely via ADB (Android Debug Bridge) Shell is a common task. For devices with root access, using the su command to elevate privileges for sensitive operations is essential. However, many developers encounter issues such as failed privilege escalation or abnormal command execution when scripting. This article systematically analyzes the correct usage of the su command in ADB Shell from a technical perspective, providing reproducible code examples.
Working Principles of the su Command and Common Misconceptions
The su (substitute user) command is used in Unix-like systems to switch user identities, and in Android environments, it is typically employed to gain root privileges. When entered directly in an interactive shell, su initiates a new shell session with root permissions, allowing subsequent commands to be executed within that session. However, in scripts or when executed via ADB Shell, this mode causes problems: the su command itself returns immediately, while subsequent commands run in the original shell, thus losing root privileges.
For example, the following code snippet illustrates a typical incorrect usage:
adb shell "
su
mv /sdcard/Download/app_test /data/local
cd /data/local
./app_test
exit
exit
"
In this example, su starts a new root shell, but commands like mv and cd are actually executed in the original shell, potentially failing due to insufficient permissions. This misunderstanding stems from a lack of clarity regarding the differences between the interactive and scripted modes of the su command.
Executing Single Commands with the su -c Parameter
The correct solution is to use the su -c parameter, which allows direct execution of a specified command after elevating privileges. Its basic syntax is:
adb shell "su -c '[command]'"
Here, [command] is the command to be executed with root permissions. For instance, to view product information in the system property file, execute:
adb shell "su -c 'cat /system/build.prop | grep "product"'"
This command invokes root privileges via su -c and then performs the cat and grep pipeline operation. Note that quotation nesting must be correct: outer double quotes are for ADB Shell parameters, while inner single quotes wrap the command parameter for su -c. If the command contains special characters (e.g., double quotes), proper escaping is required, as shown in:
adb shell "su -c 'echo "Hello, World!" > /data/test.txt'"
Cross-Platform Compatibility and Variant Handling
Implementations of the su command may vary across different Android devices or Linux distributions. For example, some systems (e.g., Linux-based environments) might not support the su -c syntax and instead require the su 0 '[command]' format. This stems from historical variants of the su command: in traditional Unix systems, su could accept a user ID parameter (such as 0 for root) followed by a command.
In practice, it is advisable to first test the su support on the target device. For example, try the following command:
adb shell su -c 'whoami'
If it returns "root", then su -c is available; if an error like "invalid uid/gid '-c'" occurs, switch to:
adb shell su 0 'whoami'
This variation reminds developers to include appropriate error handling and fallback logic when writing cross-platform scripts.
Execution Strategies for Complex Scripts
For complex scripts requiring multiple commands, several feasible approaches exist. The simplest is to combine multiple commands into a single shell script string and execute it via su -c. For example:
adb shell "su -c 'cd /data/local && ./app_test && echo "Done"'"
Another method involves writing a local script file, pushing it to the device via ADB, and then executing it. For instance:
echo -e '#!/system/bin/sh
mv /sdcard/Download/app_test /data/local
cd /data/local
./app_test' > script.sh
adb push script.sh /data/local/tmp/
adb shell "su -c 'sh /data/local/tmp/script.sh'"
This approach is more suitable for lengthy scripts, facilitating maintenance and debugging.
Debugging Tips and Best Practices
Common errors when executing su commands include permission denials, command not found, or syntax errors. The following debugging tips can help identify issues:
- Verify Root Privileges: Execute
adb shell su -c 'id'to check if the user ID is 0. - Check Command Paths: Use absolute paths for commands to avoid "command not found" errors due to environment variable issues.
- Stepwise Execution: Break down complex scripts into individual commands and test them one by one.
- Logging: Add output redirection in scripts, e.g.,
su -c 'command > /data/log.txt 2>&1'.
Additionally, it is recommended to adhere to the following best practices:
- Avoid using root privileges when unnecessary to minimize security risks.
- Use
su -cinstead of interactive shells to ensure command atomicity. - Validate user input to prevent command injection attacks.
- Add error checks at the beginning of scripts, such as
set -e(exit on error).
Through the above analysis and examples, developers should be able to more effectively use the su command in ADB Shell for executing scripts on Android devices. Correctly understanding command behavior, handling cross-platform differences, and adopting robust coding practices are key to ensuring successful task execution.