Làm thế nào để có được pid của lệnh được thực hiện cuối cùng trong shell script?


254

Tôi muốn có một kịch bản shell như thế này:

my-app &
echo $my-app-pid

Nhưng tôi không biết làm thế nào để có được pid của lệnh vừa thực hiện.

Tôi biết tôi chỉ có thể sử dụng jobs -p my-applệnh để grep pid. Nhưng nếu tôi muốn thực thi shell nhiều lần, phương thức này sẽ không hoạt động. Bởi vì jobspec là mơ hồ.

Câu trả lời:


338

PID của lệnh được thực hiện cuối cùng nằm trong $!biến shell:

my-app &
echo $!

1
Đó là in pid như ví dụ. [1] 893. Tôi chỉ muốn số.
user3153014

33
Cần lưu ý rằng điều này là viết tắt của các chương trình bắt đầu trong nền . Nếu không có quá trình nền nào được bắt đầu, tham số không được đặt.
ramrunner

5
Một giải pháp xứng đáng được đề xuất trong (một bình luận cho câu trả lời cho) Làm thế nào để có được pid của tiến trình chỉ mới bắt đầu : oh, và "oneliner": /bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &- sysfault 24 tháng 11 '10 14:28
imz - Ivan Zakharyaschev

14
@ user3153014 Chuỗi như "[2] 2625" được in bằng shell sau khi bắt đầu tác vụ nền. Điều này không liên quan đến đầu ra củaecho $!
Petr Gladkikh

Tôi thường sử dụng mã như vậy trong một tập lệnh khi tôi cần đợi cho đến khi quá trình kết thúc. my-app & myVar=$! ; fg. fgđưa quá trình lên tiền cảnh một lần nữa. Sau đó tôi có thể in echo $myVarsau và tôi khá chắc chắn rằng ứng dụng của tôi đã hoàn thành.
Vrata Blazek

66

Nhận PID:

#!/bin/bash
my-app &
echo $!

Lưu PIDtrong biến:

#!/bin/bash
my-app &
export APP_PID=$!

Lưu tất cả các trường hợp PIDtrong tệp văn bản:

#!/bin/bash
my-app &
echo $! >>/tmp/my-app.pid

Lưu đầu ra, lỗi và PIDtrong các tệp riêng biệt:

#!/bin/bash
my-app >/tmp/my-app.log 2>/tmp/my-app.error.log &
echo $! >>/tmp/my-app.pid

echo "my-app PID's: $(cat /tmp/my-app.pid)"

3
Câu hỏi không hỏi về chuyển hướng, thì câu trả lời của bạn hầu hết giống với câu hỏi được chấp nhận ngoại trừ nếu một trường hợp my-appkết thúc, và thậm chí tệ hơn nữa là PID của nó sẽ được sử dụng lại sau đó, bạn sẽ có thông tin xấu trong tệp của mình. Tôi không nghĩ câu trả lời này bổ sung nhiều giá trị cho câu trả lời được chấp nhận thực sự
Eric Renouf

@EricRenouf đăng cập nhật!
Eduardo Cuomo

một dẫn xuất khác có thể hữu ích. Điều này nhận được PID và đồng thời coi nó là một quá trình tiền cảnh (phần lớn): sleep 4 | grep INVALID & export MY_PID=$!; fg; echo $MY_PID returned with $?`
mledit

APP không phải main &là một cách để lấy PID?
MrMesees

3

Hãy thử một cái gì đó như

pidof my_app >> /tmp/my_app.pid

1
Lệnh bên ngoài và chậm, nếu hệ thống có thể cung cấp cho PID trực tiếp tại sao tìm kiếm thông qua tất cả các quy trình để tìm ra điều đó? và ngoài ra, không thể chắc chắn bạn sẽ nhận được giá trị chính xác
papo

-4

Hãy thử một cái gì đó như thế này:

 ps ef | grep "[m]y-app" | awk '{print $2}'

Đặt chữ cái đầu tiên của quy trình của bạn vào giữa để [ ]đảm bảo bạn không nhận được grepquy trình trong danh sách của mình. Nếu cần bạn cũng có thể thêm một grep vào tên người dùng của bạn.


9
Điều đó rất mong manh và không hoạt động nếu my-appđược thực thi nhiều lần - davidshen84 đặc biệt lo lắng về trường hợp đó.
Mat

2
Nếu bạn thậm chí đi theo con đường này, bạn nên sử dụng pgrepthay thế.
Willem
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.