使用 su -c 命令实现 sudo 命令的效果

1. 执行 root 命令的一般流程

2. sudo 命令

       sudo 是 linux 系统的一个特殊命令,可以让普通用户直接执行 root 命令(无需先切换到 root 用户)。

       一般用法:sudo cmd

       可以通过执行 sudo -h 查看具体用法,如下:

$ sudo -h
sudo - execute a command as another user

usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user]
            [command]
usage: sudo [-AbEHknPS] [-C num] [-g group] [-h host] [-p prompt] [-u user]
            [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-C num] [-g group] [-h host] [-p prompt] [-u user] file
            ...

Options:
  -A, --askpass               use a helper program for password prompting
  -b, --background            run command in the background
  -C, --close-from=num        close all file descriptors >= num
  -E, --preserve-env          preserve user environment when running command
  -e, --edit                  edit files instead of running a command
  -g, --group=group           run command as the specified group name or ID
  -H, --set-home              set HOME variable to target user's home dir
  -h, --help                  display help message and exit
  -h, --host=host             run command on host (if supported by plugin)
  -i, --login                 run login shell as the target user; a command may
                              also be specified
  -K, --remove-timestamp      remove timestamp file completely
  -k, --reset-timestamp       invalidate timestamp file
  -l, --list                  list user's privileges or check a specific
                              command; use twice for longer format
  -n, --non-interactive       non-interactive mode, no prompts are used
  -P, --preserve-groups       preserve group vector instead of setting to
                              target's
  -p, --prompt=prompt         use the specified password prompt
  -S, --stdin                 read password from standard input
  -s, --shell                 run shell as the target user; a command may also
                              be specified
  -U, --other-user=user       in list mode, display privileges for user
  -u, --user=user             run command (or edit file) as specified user name
                              or ID
  -V, --version               display version information and exit
  -v, --validate              update user's timestamp without running a command
  --                          stop processing command line arguments

3. android 下的 sudo 命令

       android 虽然是基于 linux 系统,但本身并没有提供 sudo 命令,而是将该功能集成到 su 命令里面。

       我们可以通过执行 su -c cmd 来实现 sudo 的效果。

       例如,在 adb shell 下执行 su -c id 命令,返回的用户信息是 root,而直接执行 id 命令,返回的则是 shell:

shell@hammerhead:/ $ su -c id
uid=0(root) gid=0(root) context=u:r:init:s0
shell@hammerhead:/ $ id
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0

4. android 下的 su

       通过执行 su --help 命令,可以查看 su 的具体用法:

shell@hammerhead:/ $ su --help
SuperSU v2.79 (ndk:armeabi-v7a) - Copyright (C) 2012-2016 - Chainfire

Usage: su [options] [--] [-] [LOGIN] [--] [args...]

Options:
  -c, --command COMMAND        pass COMMAND to the invoked shell
  -cn, --context CONTEXT       switch to SELinux CONTEXT before invoking
  -h, --help                   display this help message and exit
  -, -l, --login               pretend the shell to be a login shell
  -m, -p,
  -mm, --mount-master          connect to a shell that can manipulate the
                               master mount namespace - requires su to be
                               running as daemon, must be first parameter
  -mns, --mount-namespace PID  enter mount namespace used by PID
  --preserve-environment       do not change environment variables
  -s, --shell SHELL            use SHELL instead of the default detected shell
  -v, --version                display public version and exit
  -V                           display internal version and exit

Usage#2: su LOGIN COMMAND...

Usage#3: su {-d|--daemon|-ad|--auto-daemon|-r|--reload}
  auto version starts daemon only on SDK >= 18 or
  if SELinux is set to enforcing
  (call only from a root session)

Usage#4: su {-i|--install|-u|--uninstall}
  perform post-install / pre-uninstall maintenance
  (call only from a root session)

Usage#5: su --id pid
  identify eldest parent of pid
  (call only from a root session)

       而直接在 linux 系统执行 su --help 命令,则会输出如下内容(以下是 Mac 电脑的输出):

$ su --help
su: illegal option -- h
usage: su [-] [-flm] [login [args]]

       显然,android 的 su 是定制过的。如果你感兴趣,可以阅读系统源码:system/extras/su/su.c

5. 总结

       “上帝为你关了这扇门,必会为你再开另一扇门。”