腳本的單一實例,但僅具有相同的參數

腳本的單一實例,但僅具有相同的參數

我這裡有一段漂亮的小程式碼,如果有另一個腳本實例正在運行,它將從腳本中退出:

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值中沒有任何空格,因此您可以直接比較它們。如果參數順序發生​​變化,它不會注意到。

相關內容