comportamiento impar de pgrep en el script bash

1

Tengo un script para eliminar un árbol de proceso que funciona bien en Linux, pero estoy experimentando un comportamiento extraño en osx. Realmente funciona bien con mis pruebas de unidad y también cuando intento ejecutarlo manualmente en osx, pero por alguna razón, cuando se ejecuta como un trabajo de Jenkins, actúa de manera diferente.

Esta es la función bash actual con un poco de debug echo y 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 llamada a pgrep que desde una ejecución fallida puede ser pgrep -P 9651 imprime todos los procesos en la máquina, y los scripts se cuelgan cuando intenta eliminar el pid 0.

¿Pero por qué obtendría todos los procesos? Cuando finaliza la ejecución, el proceso 9651 aún se está ejecutando y si emito el comando en la línea de comando pgrep -P 9651 , no hay salida (lo cual se espera ya que este proceso no debería tener hijos).

Agregué una llamada de depuración para imprimir el árbol del proceso justo antes de listar los elementos secundarios:

+ 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'

Me parece normal, el sleep 10 no tiene hijos.

¿Alguna idea? Estoy un poco atascado después de haber intentado depurar esto durante algunas horas?

El proceso que se intenta eliminar es en este caso un simple sleep 10 que se usa para la prueba.

    
pregunta Zitrax 10.03.2014 - 11:06

1 respuesta

3

¿De dónde obtienes tu versión de pgrep?

La versión que tengo de MacPorts está codificada de manera que si no proporciona un patrón, coincidirá con todos los procesos, incluso si tiene calificadores como la opción -P .

Cuando emito pgrep -P<ppid> , obtengo una lista completa de procesos. Si agrega un patrón como en pgrep -P<ppid> \. , entonces funciona como se espera y solo proporciona procesos con el ppid dado.

En cuanto a la diferencia de comportamiento, tal vez tenga un par de versiones de pgrep en su máquina y los trabajos de jenkins tengan un PATH diferente, ¿están encontrando una versión diferente?

Desde la ventana del terminal puede buscar varias versiones con:

mdfind -name pgrep

También sugiero que compare la variable PATH utilizada en el trabajo con la interactiva.

Para ver qué archivo utilizará el shell, puede usar type -p pgrep y type -a pgrep mostrará todos los lugares en la RUTA donde se puede encontrar pgrep.

    
respondido por el KenB 16.03.2014 - 21:33

Lea otras preguntas en las etiquetas