![使用进程名称而不是 PID 来连接 strace](https://linux22.com/image/1346347/%E4%BD%BF%E7%94%A8%E8%BF%9B%E7%A8%8B%E5%90%8D%E7%A7%B0%E8%80%8C%E4%B8%8D%E6%98%AF%20PID%20%E6%9D%A5%E8%BF%9E%E6%8E%A5%20strace.png)
如何pstrace
在 bash 中实现一个包装脚本来改变
[sudo] strace -c -p [PID]
到
[sudo] pstrace -c -p [PROCESS-NAME]
类似于
killall [PROCESS-NAME]
被使用。带有完成和一切。
答案1
从 5.15 版本开始,strace 可以打印命令/进程名称:
- 用于打印 PID 的命令名称的实现
--decode-pids=comm
选项(及其别名)。-Y
答案2
你的这个:
ps auxw | grep [PROCESS-NAME] | awk '{print"-p " $2}' | xargs strace
答案3
要求看似复杂:-)
分为两部分,首先pstrace
是的包装脚本strace
,用于pgrep
名称到 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[@]}"
对于第二部分,我将使用bash
可编程完成来按名称完成流程,将其放入您的~/.bash_profile
或类似的文件中:
# 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
在安装了 bash-3.x 和 bash-4.x 的 Linux 上进行了测试和使用。ps
在非 Linux 平台上,选项可能需要进行调整,也应该truss
通过一行更改进行支持。
限制包括:
- 没有正确转义类似内核线程的进程
[names]
,这将导致pgrep
(可能)无法执行您想要的操作 - 名称中带有空格的进程不匹配(
args
使用“ ”代替“comm
”,以便/paths
在可用时使用)