ocehb: (Default)
[personal profile] ocehb
Возникла задача получения pid последнего форкнутого процесса.
Проблема: если форкается труба (cmd1 | cmd2 | cmd3), то $! возвращает pid последнего процесса в трубе, а хотелось бы получить pid первого (в общем случае любого) для последующего отстрела, если он зависнет (e.g. ssh host cat big-file | sha1sum).


Рещение влоб: $[$!-1], $[$!-2] для доступа к cmd2, cmd1 etc.
Как временное решение подойдёт, но если ядро рандомизирует выдачу pidов, то работать не будет.

Решение через хеш jobstates:

     1  # function get-last-pipe-pids () {
     2  emulate -L zsh
     3  setopt extendedglob
     4  
     5  local -a ary; local elm
     6  for elm in ${(v)jobstates}; do
     7      ary=( ${(@s.:.)elm} )
     8      [[ ${ary[2]} == "+" ]] && break
     9      ary=()
    10  done
    11  
    12  [[ $#ary == 0 ]] && return 1
    13  if [[ $# == 0 ]]; then
    14      print -l ${${ary[3,-1]}%=*}
    15  else
    16      print ${${${ary[3,-1]}%=*}[$1]}
    17  fi
    18  return
    19  
    20  # }


jobstates содержит индексированные состояния таблицы заданий:

# sleep 60 | cat | cat &
[1] 20831 20832 20833
# sleep 60 | cat | cat &
[2] 20835 20836 20837
# print -l ${(v)jobstates}
running:-:20831=running:20832=running:20833=running
running:+:20835=running:20836=running:20837=running


Поля:

  1. Статус задания (running, suspended, done)

  2. Обозначение задания ("+" -- текущее, "-" -- предидущее, пустое поля для всех остальных)

  3. Список pidов процессов в трубе с их состоянием



  • Строки 2-3 -- стандартный заголовок для zsh-скриптов

  • Строка 5 -- заводим локальные переменные

  • Строки 6-10 -- ищем в значениях (v) jobstates текущее задание (последнее из запущеных) и складываем поля, поделённые по ":" в массив ary

  • Строка 12 -- если ничего нет, то выходим с кодом ошибки

  • Строка 14 -- если аргументов нет, то печатаем pidы всех процессов (первые два поля -- состояние процесса и его обозначение нам не нужны, а состояние конкретного процесса удаляется с помощью квалификатора %=*)

  • Строка 16 -- если есть аргумент то это номер монады в трубе, и печатаем только её pid.


Пример использования:
# sleep 60 | cat | cat &
[1] 21191 21192 21193
# sleep 60 | cat | cat &
[2] 21195 21196 21197
# get-last-pipe-pids
21195
21196
21197
# get-last-pipe-pids 1
21195



This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org

Profile

ocehb: (Default)
ocehb

January 2021

S M T W T F S
     12
345 6789
10111213141516
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 8th, 2025 12:24 am
Powered by Dreamwidth Studios