Tại sao $$ trả lại id giống như quy trình cha?


159

Tôi có vấn đề với Bash, và tôi không biết tại sao.
Dưới vỏ, tôi nhập:

echo $$    ## print 2433
(echo $$)  ## also print 2433
(./getpid) ## print 2602

"getpid" là một chương trình C để có được pid hiện tại, như:

   int main() {
    printf("%d", (int)getpid());
    return 0;
   }

Điều làm tôi bối rối là:

  1. Tôi nghĩ "(lệnh)" là một quá trình phụ (tôi có đúng không?) Và tôi nghĩ rằng pid của nó phải khác với pid cha của nó, nhưng chúng giống nhau, tại sao ...
  2. Khi tôi sử dụng chương trình của mình để hiển thị pid giữa dấu ngoặc đơn, pid mà nó hiển thị là khác nhau, phải không?
  3. là '$$' một cái gì đó giống như vĩ mô?

Bạn có thể giúp tôi được không?


8
Lưu ý rằng getpidsẽ hiển thị ID tiến trình khác nhau ngay cả khi nó không chạy trong một lớp con.
chepner

1
@Marian echo $$ $BASHPID ; ( echo $$ $BASHPID )chứng minh rằng nó làm. Dấu ngoặc tròn tạo ra một khung con. Các câu lệnh có thể thay đổi các giá trị biến và vỏ cha mẹ không được nhìn thấy các thay đổi đó. Điều này được thực hiện như là một fork()hoạt động.
Ben

Câu trả lời:


222

$$được định nghĩa để trả về ID tiến trình của cha mẹ trong một lớp con; từ trang người đàn ông trong "Thông số đặc biệt":

$ Mở rộng tới ID tiến trình của trình bao. Trong một lớp con (), nó mở rộng tới ID tiến trình của lớp vỏ hiện tại, chứ không phải lớp con.

Trong bash4, bạn có thể lấy ID tiến trình của trẻ BASHPID.

~ $ echo $$
17601
~ $ ( echo $$; echo $BASHPID )
17601
17634

16
"cha mẹ" là một chút sai lệch (ít nhất là với tôi), nó thực sự là vỏ "cấp cao nhất". Ví dụ: echo $$; (echo $$; (echo $$))lặp lại cùng một tiếng vang ba lần
Martin Bouladour

1
Đúng; Tôi nên nói rằng giá trị được kế thừa từ shell cha (kế thừa giá trị của từ cha mẹ, v.v.). Shell cấp cao nhất thiết lập nó ban đầu, thay vì kế thừa từ tiến trình cha (không phải shell) của nó.
chepner

$ Expands to the process ID of the shellnó có tho không echo $chỉ lặp lại nghĩa đen $.
Alexander Mills

@AlexanderMills Vâng, vâng; $một mình không phải là một mở rộng tham số. Trang man đang đề cập đến tên của tham số đặc biệt, đó là $; nó không tuyên bố rằng $một mình mở rộng.
chepner

Ok tôi thực sự không biết điều đó có nghĩa là gì, nhưng echo $BASHPIDhoạt động trong bash 4 và 5 (nhưng không phải là phiên bản 3.2.57 trên MacOS)
Alexander Mills

81

Bạn có thể sử dụng một trong những điều sau đây.

  • $! là PID của quá trình nền cuối cùng.
  • kill -0 $PID kiểm tra xem nó vẫn chạy.
  • $$ là PID của shell hiện tại.

2
Không phải viên đạn thứ hai là kill -0 $!nếu chúng ta đang nói về các quá trình nền? PIDkhông được đặt thành bất cứ điều gì theo mặc định.
Isaac Freeman

26
  1. Dấu ngoặc đơn gọi một nhánh con trong Bash . Vì nó chỉ là một lớp con nên nó có thể có cùng một PID - phụ thuộc vào việc thực hiện.
  2. Chương trình C mà bạn gọi là một quy trình riêng biệt, có quy trình riêng biệt của riêng nó - không thành vấn đề nếu nó nằm trong một mạng con hay không.
  3. $$là một bí danh trong Bash cho tập lệnh hiện tại PID . Xem sự khác biệt giữa $$$BASHPIDở đây , và ngay bên trên rằng biến bổ sung $BASH_SUBSHELLcó chứa mức lồng nhau.

4

Hãy thử getppid()nếu bạn muốn chương trình C của bạn in PID của shell.


2

Nếu bạn hỏi làm thế nào để có được PID của một lệnh đã biết thì nó sẽ giống như thế này:

Nếu bạn đã ban hành lệnh bên dưới # Lệnh đã ban hành là ***

dd if = / dev / đĩax của = / dev / disky


Sau đó, bạn sẽ sử dụng:

PIDs=$(ps | grep dd | grep if | cut -b 1-5)

Điều xảy ra ở đây là nó đưa tất cả các ký tự duy nhất cần thiết vào một trường và trường đó có thể được lặp lại bằng cách sử dụng

tiếng vang $ PID


1

Đây là một cách đơn nhất để có được pid chính xác

pid=$(cut -d' ' -f4 < /proc/self/stat)

cùng làm việc tốt cho phụ

SUB(){
    pid=$(cut -d' ' -f4 < /proc/self/stat)
    echo "$$ != $pid"
}

echo "pid = $$"

(SUB)

kiểm tra đầu ra

pid = 8099
8099 != 8100

Ý tưởng hay, nhưng sẽ không giúp bạn có được cái nĩa của cái vỏ mà nó đã chạy để nắm bắt đầu ra của vết cắt? Nếu tôi chạy nó hai lần, một lần với echo $ (...) và một lần không có, thì tôi nhận được các câu trả lời khác nhau.
Martin Dorey
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.