comportamento strano di pgrep nello script di bash

1

Ho uno script per uccidere un albero del processo che funziona bene in linux ma sto vivendo un comportamento strano su osx. Funziona davvero bene con i miei test unitari e anche quando provo ad eseguirlo manualmente su osx, ma per qualche ragione quando viene eseguito come un lavoro jenkins agisce in modo diverso.

Quindi questa è la funzione di bash corrente con un po 'di debug echo e sleeps:

killtree() {
  local _pid=$1
  local _sig=${2:--TERM}
  echo "Stopping ${_pid}"
  sleep 1
  kill -stop ${_pid} # stop parent to avoid creation of new children
  children='pgrep -P ${_pid}'
  echo "Children=$children"
  sleep 1
  for _child in $children; do
      killtree ${_child} ${_sig}
  done
  echo "Killing child ${_pid}"
  sleep 1
  kill -${_sig} ${_pid}
}

La chiamata a pgrep che da una corsa fallita può essere pgrep -P 9651 stampa tutti i processi sulla macchina, e gli script si bloccano quando tenta di uccidere pid 0.

Ma perché otterrebbe tutti i processi? Al termine dell'esecuzione, il processo 9651 è ancora in esecuzione e se si esegue il comando sulla riga di comando pgrep -P 9651 non viene generato alcun output (il che è previsto poiché questo processo non dovrebbe avere figli).

Ho aggiunto una chiamata di debug per stampare la struttura del processo subito prima di elencare i bambini:

+ pstree='-+= 00001 root /sbin/launchd
 \-+= 09774 root /usr/sbin/sshd -i
   \-+- 09777 jenkins /usr/sbin/sshd -i
     \-+= 09783 jenkins bash -c cd '\''/var/jenkins'\'' && java  -jar slave.jar
       \-+- 09784 jenkins /usr/bin/java -jar slave.jar
         \-+- 09807 jenkins /Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/bin/java -classpath/     
          \-+- 09817 jenkins /Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/bin/java -
            \--- 09828 jenkins sleep 10'

Mi sembra normale, il sleep 10 non ha figli.

Qualche idea - Sono un po 'bloccato dopo aver provato a eseguire il debug di questo per alcune ore?

Il processo che sta tentando di essere ucciso è in questo caso un semplice sleep 10 utilizzato per il test.

    
posta Zitrax 10.03.2014 - 11:06
fonte

1 risposta

3

Da dove viene la versione di pgrep?

La versione che ho da MacPorts è codificata in modo tale che se non fornisci un pattern esso corrisponderà a tutti i processi anche se hai qualificatori come l'opzione -P .

Quando rilascio pgrep -P<ppid> ottengo un elenco completo di processi. Se aggiungi un pattern come in pgrep -P<ppid> \. , allora funziona come previsto fornendo solo processi con il dato ppid.

Per quanto riguarda la differenza di comportamento, forse hai un paio di versioni di pgrep sulla tua macchina e i lavori di jenkins hanno un PATH diverso, quindi stai trovando una versione diversa?

Dalla finestra del terminale puoi cercare più versioni con:

mdfind -name pgrep

Suggerisco anche di confrontare la variabile PATH utilizzata nel lavoro rispetto all'interattivo.

Per visualizzare il file che verrà utilizzato dalla shell, puoi utilizzare type -p pgrep e type -a pgrep mostrerà tutte le posizioni nel PERCORSO in cui è possibile trovare pgrep.

    
risposta data 16.03.2014 - 21:33
fonte

Leggi altre domande sui tag