Find the PID(s) of running processes and store as an array

前端 未结 4 1451
被撕碎了的回忆
被撕碎了的回忆 2021-01-12 03:01

I\'m trying to write a bash script to find the PID of a running process then issue a kill command. I have it partially working, but the issue I face is that there may be mor

相关标签:
4条回答
  • 2021-01-12 03:14

    Don't know why you would ever grep for a process to kill, unless you didn't know the command name. Most modern versions of ps have the flags

        -C cmdlist
              Select by command name.  This selects the processes whose executable name is given in cmdlist.
    

    and

       -o format
              User-defined format.  format is a single argument in the form of
              a blank-separated or comma-separated list, which offers a way to
              specify individual output columns.  The recognized keywords are
              described in the STANDARD FORMAT SPECIFIERS section below.
              Headers may be renamed (ps -o pid,ruser=RealUser -o
              comm=Command) as desired.  If all column headers are empty (ps
              -o pid= -o comm=) then the header line will not be output.
              Column width will increase as needed for wide headers; this may
              be used to widen up columns such as WCHAN (ps -o pid,wchan=WIDE-
              WCHAN-COLUMN -o comm).  Explicit width control (ps opid,
              wchan:42,cmd) is offered too.  The behavior of ps -o pid=X,
              comm=Y varies with personality; output may be one column named
              "X,comm=Y" or two columns named "X" and "Y".  Use multiple -o
              options when in doubt.  Use the PS_FORMAT environment variable
              to specify a default as desired; DefSysV and DefBSD are macros
              that may be used to choose the default UNIX or BSD columns.
    

    So you can just do

    ps -o pid= -C commandName 
    

    Will return the pid of all processes named exactly commandName and is cleaner and faster. Or kill a loop

    while read -r pid; do 
      kill "$pid" 
    done < <(ps -o pid= -C commandName)
    

    But really, you should always just be able to do

    > pkill commandName 
    
    0 讨论(0)
  • 2021-01-12 03:23

    You don't need to use an array if you're going to immediately iterate over the results and perform an action:

    for pid in $(ps -fe | grep '[p]rocess' | grep -v grep | awk '{print $2}'); do
        kill "$pid"
    done
    

    Notice we have to exclude grep's pid from the list of processes to kill. Or we could just use pgrep(1):

    for pid in $(pgrep '[p]rocess'); do
        kill "$pid"
    done
    

    If you actually needed to store the pids in an array, pgrep is how you would do it:

    pids=( $(pgrep '[p]rocess') )
    

    Back to killing process. We can still do better. If we're just using pgrep to get a list of processes to kill them, why not go straight for pgrep's sister program: pkill(1)?

    pkill '[p]rocess'
    

    As it turns out, no need for bash scripting at all.

    0 讨论(0)
  • 2021-01-12 03:34

    Your script seems fine, if you want to have each pid list on a new like then replace:

    echo $pid
    #kill $pid
    

    with

    echo "$pid"
    #kill "$pid"
    
    0 讨论(0)
  • 2021-01-12 03:38

    Here's a little one liner that might help

    for pid in `ps -ef | grep your_search_term | awk '{print $2}'` ; do kill $pid ; done
    

    Just replace your_search_term with the process name you want to kill.

    You could also make it into a script and swap your_search_term for $1

    EDIT: I suppose I should explain how this works.

    The back ticks `` collects the output from the expression inside it. In this case it will return a list of pids for a process name.

    Using a for loop we can iterate through each pid and kill the process.

    EDIT2: replaced kill -9 with kill

    0 讨论(0)
提交回复
热议问题