Interfaz de interfaz con nombre de proceso en lugar de PID

Interfaz de interfaz con nombre de proceso en lugar de PID

¿Cómo implemento un script contenedor pstraceen bash que cambia la interfaz de

[sudo] strace -c -p [PID]

a

[sudo] pstrace -c -p [PROCESS-NAME]

similar a cómo

killall [PROCESS-NAME]

se utiliza. Con terminación y todo.

Respuesta1

A partir de la versión 5.15, strace puede imprimir los nombres de comando/proceso:

  • Opción implementada --decode-pids=comm(y su alias -Y) para imprimir nombres de comandos para PID.

Respuesta2

Tu esto:

ps auxw | grep [PROCESS-NAME] | awk '{print"-p " $2}' | xargs strace

Respuesta3

Requisitos engañosamente complicados :-)

En dos partes, en primer lugar, el pstracescript contenedor para strace, que se utiliza pgreppara la operación de nombre a PID.

#!/bin/bash

IFS=$' \t\n'

# process the arguments to find "-p procname", only support one instance though
for ((nn=1; nn<=$#; nn++)); do
    if [ "${!nn}" = "-p" ]; then
        :
    elif [ "$prev" = "-p" ]; then
        pname="${!nn}"
    else
        args+=( "${!nn}" )    # just copy 
    fi
    prev="${!nn}"
done

pids=()
if [ -n "$pname" ]; then
    # skip this shell's PID, which pgrep -f will match
    # note the use of exec to avoid picking up a matching subshell too
    # uncomment  && printf for pid/pname list
    while read pp pname; do 
         [ "$pp" != "$$" ] && pids+=($pp) # && printf "%6i %s\n" "$pp" "$pname"
    done < <(exec pgrep -l -f "${pname}")
fi

npids=${#pids[*]}

if [ $npids -eq 0 ]; then
    echo "No PIDs to trace."; exit 2
elif [ $npids -eq 1 ]; then
    args=( "${args[@]}" -p ${pids[0]} )
elif [ $npids -le 32 ]; then
    read -p "$npids PIDS found, enter Y to proceed: " yy
    [ "$yy" != "Y" ] && echo "Cancelled..." && exit 1
    args=( "${args[@]}" ${pids[@]/#/-p } ) 
else 
    echo "Too many PIDs to trace: $npids (max 32)."; exit 2
fi 

strace "${args[@]}"

Para la segunda parte usaré bashla finalización programable para completar procesos por nombre, pon esto en tu ~/.bash_profileo similar:

# process-name patterns to ignore
PROCIGNORE=( "^\[", "^-bash" )

_c8n_listprocs ()
{
    local cur prv ignore IFS nn mm
    prv=${COMP_WORDS[COMP_CWORD-1]}
    cur=${COMP_WORDS[COMP_CWORD]}

    case "$prv" in
        '-p') 
              IFS=$'\n' COMPREPLY=( $(ps axwwo "args") ) IFS=$' \t\n'
              COMPREPLY=(${COMPREPLY[*]// */})  # remove arguments

              ignore="0" # ps header
              for ((nn=1; nn<${#COMPREPLY[*]}; nn++)); do
                  # filter by (partially) typed name in cur
                  # use  " =~ ^$cur " for prefix match, without ^ it's substr match
                  [[ -n "$cur"  &&  ! "${COMPREPLY[$nn]}" =~ $cur ]] && {
                      ignore="$nn $ignore"
                  } || { 
                      # skip names matching PROCIGNORE[]
                      for ((mm=0; mm<${#PROCIGNORE[*]}; mm++)); do
                          [[ "${COMPREPLY[$nn]}" =~ ${PROCIGNORE[$mm]} ]] && 
                              ignore="$nn $ignore"
                      done
                  }
              done
              # remove unwanted, in reverse index order
              for nn in $ignore; do unset COMPREPLY[$nn]; done

              ;;
        *)    COMPREPLY=()
              ;;
    esac
}
complete -F _c8n_listprocs pstrace

Probado y utilizado en Linux con bash-3.x y bash-4.x. psLas opciones pueden necesitar ajustes en plataformas que no sean Linux, también deberían admitirse trusscon un cambio de una línea.

Las limitaciones incluyen:

  • no hay un escape correcto del proceso similar al subproceso del núcleo [names], esto hará pgrepque (probablemente) no haga lo que desea
  • No coinciden los procesos con espacios en el nombre (" args" se usa en lugar de " comm" para que /pathspueda usarse, cuando esté disponible)

información relacionada