我这里有一段漂亮的小代码,如果有另一个脚本实例正在运行,它将从脚本中退出:
single_instance(){
if pidof -x "${0##*/}" -o %PPID >/dev/null; then
exit 0
fi
}
但我正在寻找的是一个只有在脚本被执行时才会退出的函数使用相同的参数调用。
我知道我可以通过解决方案破解我的方式cat | grep | awk | cut | sed | tac | sort | uniq
,但我想知道是否有一种简单的方法可以使用 、 等实用程序来实现此pidof
目的ps
。
你会怎样做呢?
答案1
你可以这样做:
#!/bin/bash
single_instance() {
pid=$(pidof -x "${0##*/}" -o %PPID)
if [[ $(xargs -0 < /proc/$pid/cmdline) == $@ ]]
then
echo QUITTING
exit 1
fi
}
single_instance $(xargs -0 < /proc/$$/cmdline)
while :
do
sleep 10
done
答案2
man ps
我在研究并添加@goldilocks 的一些代码后想到了这个。它在处理带有空格的参数方面做得很好,并且如果脚本被调用为bash scriptname
:
single_instance(){
if ps -efww | grep "$(ps -o cmd= -p $$)$" | grep -vq " $$ "; then
exit 0
fi
}
答案3
fn() { IFS='
'; set -- $(ps -o args= -C "${0##*/}")
unset IFS
[ $(($(printf $(printf %s\\n "$@" | sort | uniq -c | sort -rn)))) -gt 1 ] &&
exit 0
}
exit 0
如果当前正在运行两个或多个$0
使用相同参数调用的进程,则会出现这种情况。
答案4
使用/进程:
single_instance(){
local tl=$(cat /proc/$$/cmdline)
local l
tl=${tl##*/}
for pid in $(pidof -x "${0##*/}" -o %%PPID); do
l=$(cat /proc/$pid/cmdline)
if [ ${l##*/} = $tl ]; then
echo "already running..."
exit 0
fi
done
}
它在没有启动路径的情况下对命令行进行精确比较(就像您在脚本中所做的那样)。这些/proc/*/cmdline
值中没有任何空格,因此您可以直接比较它们。如果参数顺序发生变化,它不会注意到。