bash - lấy pid cho một tập lệnh bằng tên tập lệnh


10

Tôi có hai kịch bản:

  • running_script
  • script_one

Tôi cần phải có được PID cho / bất kỳ trường hợp nào running_scriptchạy dưới tên người dùng, và sau đó pkilldừng running_scriptquá trình con gái.

Chúng tôi mong đợi một cái gì đó như:

ps -fu will | grep running_script

để tìm running_scriptquá trình. Tuy nhiên, việc kiểm tra PID dựa vào đầu ra lệnh ps cho thấy cmd là: "bin / bash" cho running_scriptquy trình.

running_scriptchạy như một quá trình tách rời ( &toán tử) bắt đầu script_one. Tôi in các PID-s khi bắt đầu để so sánh với psđầu ra của lệnh.

running_script  &
echo $! -- $BASHPID

Trong trường hợp sử dụng thực tế, chúng tôi sẽ không có PID cho một số running_scriptquy trình đang chạy. Ngoài ra, script_onecó thể hoặc không thể là một quá trình tách rời khỏi running_scriptcha mẹ.

Đối với các mục đích của bài tập, script_onechỉ cần thực hiện các vòng lặp.

while [ true ]
do
    echo "  $0 - 35sec ..."
    sleep 35
done

Tuy nhiên đó chỉ là ví dụ. Yêu cầu là để có được PID cho cha mẹ, running_scriptquá trình.

Có một tùy chọn trên pshoặc một lệnh khác có thể cho tôi tên của tệp tập lệnh và PID không? Hoặc một phương pháp để đặt tên có thể được tìm kiếm?

Trong trường hợp sử dụng cuối cùng, có thể có một số trường hợp running_scriptvì vậy chọn chúng theo tên có vẻ là lựa chọn tốt nhất cho đến nay.

thí dụ

Tôi nghĩ rằng nó có thể giúp hiển thị những gì pslệnh hiển thị, vì hầu hết các phản hồi dường như nghĩ rằng nó sẽ hoạt động. Tôi đã chạy ví dụ này chỉ một lúc trước.

$  ./running_script &
$  echo $! - $BASHPID
9047 - 3261
$  ps -ef | grep will

  UID     PID  PPID  C STIME TTY          TIME CMD
  will   8862  2823  0 22:48 ?        00:00:01 gnome-terminal
  will   8868  8862  0 22:48 ?        00:00:00 gnome-pty-helper
  will   8869  8862  0 22:48 pts/4    00:00:00 bash
* will   9047  3261  0 22:55 pts/2    00:00:00 /bin/bash
  will   9049  9047  0 22:55 pts/2    00:00:00 /bin/bash
  will   9059  2886  0 22:56 pts/0    00:00:00 man pgrep
  will   9070  9059  0 22:56 pts/0    00:00:00 pager -s
  will  10228  9049  0 23:31 pts/2    00:00:00 sleep 35
  will  10232  8869  0 23:31 pts/4    00:00:00 ps -ef
  will  10233  8869  0 23:31 pts/4    00:00:00 grep --colour=auto william

Tôi đã đánh dấu PID # 9047, chỉ hiển thị đơn giản: - sẽ 9047 3261 0 22:55 pts / 2 00:00:00 / bin / bash

Có một cái gì đó giống như một thuộc tính " jobname " mà tôi có thể thiết lập trên linux không?


Nó sẽ là đủ để có được PID của quá trình cha mẹ script1?
terdon

Để tiết kiệm thời gian, mọi tùy chọn ps hiển thị "bash / bash", KHÔNG "running_script" khi running_scriptđược nhìn từ dòng lệnh / terminal.
sẽ

Tôi đang thử nghiệm những điều này với phiên bản v4.3.11 (1) trên linux mint 17. Yêu cầu là đối với PID của running_script. Có một lý do tuân thủ (tốt) cho yêu cầu đó xuất phát từ hệ thống phần cứng và phần mềm đang chạy.
sẽ

ps --version-> "Procps-ng phiên bản 3.3.9"
sẽ vào

Câu trả lời:


14

Thử pgrep -f running_script- tùy chọn -f sử dụng toàn bộ dòng lệnh để khớp với, không chỉ tên quy trình


Kết quả là null (hoặc không có đầu ra). Đó là trên gnu bash: v4.3.11 (1) -release
sẽ

1
Thêm -l( --list-name) vào pgrep để đặt tên cho các quá trình đó. Ví dụ, để chạy script claws2postgres.sh, pgrep -l -f claws2postgrestrả về 23538 claws2postgres..
Victoria Stuart

4

ps -o pid,args -C bash | awk '/running_script/ { print $1 }'

Điều này sử dụng psđể lấy pid và lập luận cho tất cả các quy trình bash, sau đó sử dụng awk để in pid (trường 1) của quy trình khớp.

BTW, ps -o pid,args -C bashcung cấp cho bạn pid và tên của tệp tập lệnh mà bạn đã yêu cầu - tên của tập lệnh nằm trong đối số của bashlệnh.

Nếu bạn sẽ sử dụng pschứ không phải pgrepít nhất là sử dụng toàn bộ khả năng của nó chứ không phải là ps ... | grep -v grep | grep | awkcấu trúc cực kỳ xấu xí . Cái cuối cùng grepthậm chí không cần thiết vì awkcó thể thực hiện khớp mẫu. Trên thực tế, cả hai greps đều không cần thiết vì awk có thể làm tất cả:ps ax | awk '! /awk/ && /myprocessname/ { print $1}'


Kết quả là null (hoặc không có đầu ra), gnu bash: v4.3.11 (1) -release. Đầu ra của lệnh ps là: 9047 / bin / bash 9049 / bin / bash, 8869 bash. Tôi cho rằng PID 8869 là quy trình bash cha (mẹ của tất cả). Có thể có một kết quả khác nếu running_scriptlệnh được chạy từ một tập lệnh hoặc một cái gì đó (??) chứ không phải từ thiết bị đầu cuối (shell).
sẽ vào

Phiên bản psnào bạn đang chạy? Hãy thử ps --version. Cả hai ps -efps -o argsđược cho là hiển thị dòng lệnh đầy đủ, bao gồm cả các đối số. Và bạn có bất kỳ Biến môi trường nào được đề cập ở gần cuối man pstập không?
cas

Tôi đặt phiên bản trong câu hỏi: "Procps-ng phiên bản 3.3.9". Màn hình hệ thống đúc cho thấy thông tin tương tự. Nó có thể sử dụng ps (dù sao đi nữa). Tuy nhiên, thiết bị giả quá trình chỉ hiển thị bash / bash - Điều này khiến tôi tin rằng đó là bash thiết lập thông tin lệnh.
sẽ

vâng, bạn đúng. bashthay đổi đối số của nó trong ps. Tôi sẽ cố gắng tìm hiểu xem có cách nào psđể thể hiện những lý lẽ thực sự không. Trong thời gian chờ đợi, bạn có thể thử một cái gì đó như thế này nếu bạn đang chạy trên linuxps h -o pid -C bash | xargs -IXX grep -sEl 'running_script' /proc/XX/cmdline | sed -re 's:/proc/([^/]*)/.*:\1:'
cas

FYI, bashchỉ thay đổi tên của nó trong psnếu bạn chạy tập lệnh như bash scriptname.sh. Nếu bạn chạy nó như chỉ ./scriptname.sh(hoặc /path/to/scriptname.sh) thì tên thật của kịch bản sẽ xuất hiện trongps
cas

1
ps - ef | grep -v grep | grep <script_name> | awk '{print $2}'

Lệnh trên sẽ cung cấp cho PID cho script_name. Ngoài ra, bạn có thể có tập lệnh viết một tập tin tạm thời với PID đang chạy.

Thêm một dòng bên trong tập lệnh: echo $$>/tmp/script_pid.tmp


0
#!/bin/bash

# pidofargs.sh
# get process id by first argument of a process
# using `ps -eo pid,args` and `read -a`

# sample use: pidofargs.sh python /usr/bin/youtube-dl

search_grep="$1" # first filter
search_arg1="$2" # second filter

# first filter
ps -eo pid,args | grep "$search_grep" | while read pid args
do
  read -a arg < <(echo "$args")

  # pid    = process id
  # arg[0] = executable file of process
  # arg[1] = first argument of process

  # second filter
  if [[ "${arg[1]}" == "$search_arg1" ]]
  then
    # success
    echo $pid
    break
  fi

done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.