Получить только PID из списка задач, используя заголовок cmd - PullRequest
0 голосов
/ 27 мая 2018

Желаемый выход:

1234

Только PID.Ничего другого - никаких других символов, цифр или символов.

Я пытаюсь запустить tasklist, поэтому он дает мне только PID именованного или озаглавленного процесса.

tasklist | findstr /i "cmd.exe"ближе всего я получил, но результат слишком многословен.Мне просто нужен номер PID.

Бонусные баллы за то, что связали меня с описанием того, что означают операторы фильтра списка задач - "eq", "ne" и т. Д., Поскольку их нет нигде в документации.

Ответы [ 3 ]

0 голосов
/ 28 мая 2018

Я не уверен, что вы ожидаете.Может быть запущено несколько cmd снарядов.Если они запускают программу, заголовок их окна обычно меняется.

Достаточно легко получить процессы cmd и получить PID (поле Id).Заголовок окна также доступен.

PS C:\src\t\s1> Get-Process | Where-Object { $_.ProcessName -eq 'cmd' }

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    152      15    10280      16432      10.80   2808   1 cmd
    153      13     8472      12220       3.68   7232   1 cmd

PS C:\src\t\s1> Get-Process | Where-Object { $_.ProcessName -eq 'cmd' } | ForEach-Object { $_.MainWindowTitle }
cmd.exe
dirlist.bat (C:\src\t) - VIM

Получить PID только для отображения достаточно просто.Но какой из них вы хотите?

PS C:\src\t\s1> Get-Process | Where-Object { $_.ProcessName -eq 'cmd' } | ForEach-Object { $_.Id }
2808
7232
0 голосов
/ 28 мая 2018

Сложной вещью с tasklist является ее формат вывода по умолчанию.Например, когда выполняется командная строка:

tasklist /FI "ImageName eq cmd.exe" /FI "Status eq Running"

, мы получаем:

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
cmd.exe                      12740 Console                    1      3'328 K
cmd.exe                      11020 Console                    1      3'304 K

Если ширина столбцов не фиксирована, на которую я бы не рассчитывализвлечение PID не так тривиально, потому что имя изображения может содержать ПРОБЕЛЫ , поэтому использование таких разделителей не будет работать.
Возможный способ - подсчитать число =-символы во второй строке до первой SPACE , поэтому мы знаем количество символов, которые нужно обрезать, чтобы удалить имя изображения, но для этого требуется какой-то цикл (использующий goto), поэтомупроизводительность может быть довольно плохой.

Однако есть и другие выходные форматы, доступные для tasklist.Командная строка:

tasklist /FI "ImageName eq cmd.exe" /FI "Status eq Running" /FO CSV

приводит к таким выводам:

"Image Name","PID","Session Name","Session#","Mem Usage"
"cmd.exe","12740","Console","1","3'328 K"
"cmd.exe","11020","Console","1","3'304 K"

Теперь довольно просто извлечь PID:

@echo off
for /F "delims=" %%R in ('
    tasklist /FI "ImageName eq cmd.exe" /FI "Status eq Running" /FO CSV /NH
') do (
    set "FLAG1=" & set "FLAG2="
    for %%C in (%%R) do (
        if defined FLAG1 (
            if not defined FLAG2 (
                echo %%~C
            )
            set "FLAG2=#"
        )
        set "FLAG1=#"
    )
)

Другие выходные форматы используются следующей командной строкой:

tasklist /FI "ImageName eq cmd.exe" /FI "Status eq Running" /FO LIST

, что приводит к таким выводам:

Image Name:   cmd.exe
PID:          12740
Session Name: Console
Session#:     1
Mem Usage:    3'328 K

Image Name:   cmd.exe
PID:          11020
Session Name: Console
Session#:     1
Mem Usage:    3'304 K

При этом получить еще прощежелаемый вывод:

@echo off
for /F "tokens=2" %%K in ('
   tasklist /FI "ImageName eq cmd.exe" /FI "Status eq Running" /FO LIST ^| findstr /B "PID:"
') do (
   echo %%K
)

Кстати, для параметров фильтра /FI доступны следующие операторы:

  • eq - равно;
  • ne - не равно;
  • gt - больше чем;
  • lt - меньше чем;
  • ge - больше или равно;
  • le - меньше или равно;

Документация Microsoft и сообщение справки (tasklist /?) делаютНе объяснить их значение, но я нашел следующие внешние ресурсы:

0 голосов
/ 27 мая 2018

Используйте for /f для разбора вывода.PID является разделенным пробелом 2-го столбца.Разделителем / разделителем по умолчанию является пробел, соседние разделители считаются за единицу.

Итак, этот пример вывода:

> tasklist | findstr /i "cmd.exe"
cmd.exe                      14924 Console                    9         6.008 K

Анализируется в строке cmd

for /f "tokens=2" %A in ('tasklist ^| findstr /i "cmd.exe" 2^>NUL') do @Set "PID=%A"

Или в пакете:

@Echo off & SetLocal EnableDelayedExpansion
set "PID="
for /f "tokens=2" %%A in ('tasklist ^| findstr /i "cmd.exe" 2^>NUL') do @Set "PID=!PID!,%%A"
if defined PID Echo cmd.exe has PID(s) %PID:~1%

cmd.exe имеет PID 14924,11268,3652

Последний предположительно временный, используемый самой for /f.


РЕДАКТИРОВАТЬ позднее добавление к моему ответу.

Инструмент cmdow от Ritchie Lawrence может выполнить вашу задачу.

С этим вопросом, открытым в firefox:

> cmdow.exe "get only PID from task*" /f
Handle  Lev Pid -Window status- Image    Caption
0x0103DE 1 9532 Max Ina Ena Vis firefox  Get only PID from tasklist using cmd title - Stack Overflow - Mozilla Firefox

Чтобы получить PID только для строки cmd

> for /f "tokens=3" %A in ('cmdow.exe "get only PID from task*" /B /F') Do @Echo:%A
9532

В пакетном файле удвойте знаки процента %%A.

Демонстрация с использованием start для запуска другого cmd.exe с указанным заголовком:

:: Q:\Test\2018\05\27\SO_50555929_2.cmd
@Echo off
set "MyTitle=This is a quite long title to distinguish from other"
start "%MyTitle%" cmd.exe /k cmdow.exe @ /F

:: wait to get other cmd instance get started
timeout /t 3 >NUL

set "PID="
for /F "tokens=3" %%A in ('cmdow.exe "%MyTitle%*"') do set "PID=%%A"
if defined PID Echo %PID%
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...