22

我正在编写一个脚本,我需要在其中提供我的应用程序的 PID。我可以通过以下命令列出所有进程及其 PID,并且可以看到我的应用程序的条目。

adb 外壳 ps

这给了我一个巨大的进程列表。而且我需要一个条目(我可以进一步提供给另一个命令),所以我想用包名过滤这个结果。grep 命令在我的 Windows 机器上不起作用。还尝试了以下命令,但没有帮助。

adb shell ps 名称:my_app_package

4

4 回答 4

33

从 Android 7.0 开始,通过包名找出进程 ID 的最简单方法是使用pidof命令:

usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME]...

Print the PIDs of all processes with the given names.

-s      single shot, only return one pid.
-o      omit PID(s)

像这样运行它:

adb shell pidof my.app.package

在 7.0 之前的 Android 中,人们使用ps命令,然后使用内置的按comm值过滤器(对于 android 应用程序是包名称的最后 15 个字符)或grep命令来解析其输出。如果名称的comm最后 15 个字符以数字开头并且在grepAndroid 4.2 之前默认不包含 ,则过滤器不起作用。但即使在找到合适的工艺线之后,PID仍需要提取该值。

有多种方法可以做到这一点。以下是如何使用单个sed命令完成查找进程和提取 PID 的方法:

adb shell "ps | sed -n 's/^[^ ]* *\([0-9]*\).* my\.app\.package$/\1/p'"

同样的问题是sed直到 Android 6.0 才默认包含它。

但如果您必须使用较旧的设备,您始终可以使用以下 Android 版本独立解决方案。它不使用任何外部命令 - 只是 Android shell 内置:

adb shell "for p in /proc/[0-9]*; do [[ $(<$p/cmdline) = my.app.package ]] && echo ${p##*/}; done"

寻找 PID 的最常见原因是在其他命令中使用它,例如kill. 假设我们有多个logcat正在运行的实例,我们希望一次优雅地完成它们。只需将最后一个命令中的echo替换为:kill -2

adb shell "for p in /proc/[0-9]*; do [[ $(<$p/cmdline) = logcat ]] && kill -2 ${p##*/}; done"

如果从 Linux/OSX shell 运行命令,请替换"为。'

于 2013-03-25T19:04:01.957 回答
14

代替使用adb shell ps,先进入adb shell再使用ps

一步步:

  1. 连接设备(或仿真器)时输入adb shell命令。
    (命令行前缀将shell@android:/ $在执行此命令之后。)

  2. 输入ps | grep <package_name_to_be_filtered>(即ps | grep com.google)。


C:> adb shell
shell@android:/ $ ps | grep com.google
u0_a64  3353  2467  903744 52904 ffffffff 00000000 S com.google.process.location
u0_a64  3426  2467  893964 49452 ffffffff 00000000 S com.google.process.gapps
于 2014-12-16T11:53:47.870 回答
1

ps 显示的进程可以限制为属于任何给定用户的进程,方法是通过 grep(用于搜索文本的过滤器)管道输出。例如,属于用户名为 adam 的用户的进程可以显示如下:

ps -ef | grep adam

-e 选项生成有关当前运行的每个进程的信息列表。-f 选项生成的列表包含的每个进程的信息项比 -l 选项少。

于 2013-03-25T06:43:22.793 回答
0

Alex P. 的回答在技术上回答了“按进程名称查找正在运行的进程 ID ”的问题,而不是“按包名称查找正在运行的进程 ID ”的问题。<activity>区别是微妙的,并且通过标签中的“android:process”属性体现在进程重命名中。

我担心正确的解决方案会涉及更多内容,您可以阅读 Android Studio 为在此处找到真正的进程名称所做的解决方法。您将在 下看到适用于 pre-Android OreoresolveLegacyPidresolveApplicationId适用于 Android Oreo+ 的相关 shell 脚本:

  /**
   * Asynchronously resolves to the application ID. The application ID is the package name that is
   * ultimately given to the application on the device, which usually comes from the manifest.
   * Note that this may be different from {@link ClientData#getClientDescription()} or
   * {@link ClientData#getPackageName()} due to the manifest containing a process rename XML
   * option via "android:process".
   *
   * <p>When the manifest option is specified, the two aforementioned {@link ClientData }methods
   * will return the process name, not the application ID. Therefore, this method guarantees the
   * application ID if it's possible to resolve. Only if it's not possible will this fall back to
   * using the process name instead.
   */
  private void resolveApplicationId(@NotNull Process process) {
    myResolverExecutor.execute(() -> {
      String command = String.format(Locale.US, "stat -c %%u /proc/%d | xargs -n 1 cmd package list packages --uid", process.getPid());
      CollectingOutputReceiver receiver = new CollectingOutputReceiver();
      try {
        myIDevice.executeShellCommand(command, receiver);
      }
      catch (IOException | TimeoutException | AdbCommandRejectedException | ShellCommandUnresponsiveException e) {
        Logger.getInstance(Device.class).warn("Could not resolve application ID", e);
        return;
      }
      String output = receiver.getOutput();
      if (output.isEmpty()) {
        return;
      }
      Matcher m = PACKAGE_NAME_PATTERN.matcher(output);
      while (m.find()) {
        process.addApplicationId(m.group(1));
      }
    });
  }
  @NotNull
  private Future<Void> resolveLegacyPid(@NotNull String applicationId) {
    return myResolverExecutor.submit(
      () -> {
        // This shell command tries to retrieve the PID associated with a given application ID.
        // To achieve this goal, it does the following:
        //
        // 1) Gets the user name (e.g. u0_a01) using run-as with the application ID and
        //    the whoami command.
        // 2) Runs the ps command under the application ID to get a list of all running
        //    processes running under the user associated with the given application ID.
        //    The output of ps looks something like: "<user> <pid> ..."
        // 3) The output of ps is piped into grep/tr/cut to parse out the second parameter,
        //    of each line, which is the PID of each process.
        // 4) The PID is then used in the readlink command to follow the symbolic links of
        //    the symlinked exe file under the PID's /proc directory.
        // 5) If the symlink resolves to any of the 32 or 64 bit zygote process, the PID is
        //    printed to the console, serving as the output of the script.
        String command =
          String.format(
            "uid=`run-as %s whoami` && " +
            "for pid in `run-as %s ps | grep -o \"$uid[[:space:]]\\{1,\\}[[:digit:]]\\{1,\\}\" | tr -s ' ' ' ' | cut -d ' ' -f2`; do " +
            "  if [[ `run-as %s readlink /proc/$pid/exe` == /system/bin/app_process* ]]; then " +
            "    echo $pid; " +
            "  fi; " +
            "done",
            applicationId, applicationId, applicationId);
        CollectingOutputReceiver receiver = new CollectingOutputReceiver();
        myIDevice.executeShellCommand(command, receiver);
        String output = receiver.getOutput();
        if (output.isEmpty()) {
          return null;
        }
        String[] lines = output.split("\n");
        // We only handle the first return value for now.
        try {
          for (String line : lines) {
            int pid = Integer.parseInt(line.trim());
            myPidToProcess.computeIfPresent(pid, (ignored, process) -> {
              process.addApplicationId(applicationId);
              return process;
            });
          }
        }
        catch (NumberFormatException ignored) {
        }
        return null;
      });
  }
于 2020-08-01T01:04:24.203 回答