2008-09-16 53 views
109

Tôi đã từng đọc một cách để có được một tên tệp duy nhất trong một trình bao cho các tệp tạm thời là sử dụng một dấu đô la đôi ($$). Điều này tạo ra một số thay đổi theo thời gian ... nhưng nếu bạn gọi nó lặp đi lặp lại, nó sẽ trả về cùng một số. (Giải pháp là chỉ sử dụng thời gian.)

Tôi tò mò muốn biết những gì $$ thực sự là, và tại sao nó sẽ được đề xuất như một cách để tạo ra tên tập tin duy nhất.

Trả lời

69

Trong Bash $$ là ID tiến trình, như được lưu ý trong các nhận xét, không an toàn để sử dụng làm tên tệp tạm thời vì nhiều lý do.

Đối với tên tệp tạm thời, hãy sử dụng lệnh mktemp.

+33

Đối với những người chỉ cần nhìn vào các câu trả lời trên, $$ là không tốt cho ngay cả một tập tin duy nhất nếu viết vào một thư mục công khai-ghi (ví dụ:/tmp). Thật dễ dàng để xả rác/tmp với các liên kết tượng trưng sẽ khiến kịch bản của bạn viết ở đâu đó không mong muốn. mktemp tốt hơn nhiều. –

+4

Vâng, sử dụng $$ sẽ gây ra lỗ hổng bảo mật khó chịu. Đừng làm thế. – emk

+2

ai đó có đủ đại diện cần chỉnh sửa câu trả lời ... – dwestbrook

14

$$ là id của quy trình hiện tại.

2

$$ là pid của quá trình shell hiện tại. Đó không phải là cách hay để tạo tên tệp duy nhất.

1

Đó là ID tiến trình của quy trình bash. Không có quá trình đồng thời nào sẽ có cùng một PID.

6

Mọi quá trình trong hệ điều hành giống UNIX đều có một mã định danh duy nhất (tạm thời), PID. Không có hai quá trình chạy cùng một lúc có thể có cùng một PID và $$ đề cập đến PID của cá thể bash đang chạy tập lệnh.

Điều này rất nhiều không một idenifier duy nhất theo nghĩa là nó sẽ không bao giờ được tái sử dụng (thực sự, PID được tái sử dụng liên tục). Những gì nó cung cấp cho bạn là một số như vậy, nếu một người khác chạy tập lệnh của bạn, họ sẽ nhận được một số nhận dạng khác trong khi máy của bạn vẫn đang chạy. Một khi máy của bạn chết, PID có thể được tái chế và người khác có thể chạy tập lệnh của bạn, lấy cùng một PID, và vì vậy có cùng tên tệp.

Như vậy, thật sự rất vui khi nói "$$ cung cấp tên tệp sao cho nếu ai đó chạy tập lệnh tương tự huýt sáo ví dụ của tôi vẫn chạy, họ sẽ có tên khác".

1

$$ là id quá trình của hệ vỏ mà tập lệnh của bạn đang chạy. Để biết thêm chi tiết, xem trang hướng dẫn sử dụng sh hoặc bash. Bạn có thể tìm thấy trang người dùng bằng cách sử dụng dòng lệnh "man sh" hoặc bằng cách tìm kiếm trên web cho "shell manpage"

4

$$ là PID của bạn. Nó không thực sự tạo ra một tên tập tin duy nhất, trừ khi bạn cẩn thận và không ai khác làm chính xác theo cùng một cách.

Điển hình bạn muốn tạo ra một cái gì đó giống như/tmp/myprogramname $$

Có thật nhiều cách để phá vỡ này, và nếu bạn đang viết đến các địa điểm folks khác có thể viết thư cho nó không quá khó khăn trên nhiều Các hệ điều hành để dự đoán PID nào bạn sẽ có và xoay quanh - tưởng tượng bạn đang chạy dưới dạng root và tôi tạo/tmp/yourprogname13395 như một liên kết tượng trưng trỏ tới/etc/passwd - và bạn viết vào đó.

Đây là điều không tốt khi thực hiện trong tập lệnh trình bao. Nếu bạn định sử dụng một tệp tạm thời cho một thứ gì đó, bạn nên sử dụng một ngôn ngữ tốt hơn và ít nhất cũng sẽ cho phép bạn thêm cờ "độc quyền" để mở (tạo) tệp. Sau đó, bạn có thể chắc chắn rằng bạn không phải là một thứ gì đó khác.

1

$$ là pid (id tiến trình) của trình thông dịch shell chạy tập lệnh của bạn. Nó khác nhau cho mỗi tiến trình đang chạy trên một hệ thống tại thời điểm này, nhưng theo thời gian các pid kết thúc tốt đẹp xung quanh, và sau khi bạn thoát ra sẽ có một quá trình với cùng một pid cuối cùng.Miễn là bạn đang chạy, pid là duy nhất cho bạn.

Từ định nghĩa trên, rõ ràng là dù bạn sử dụng $$ bao nhiêu lần trong tập lệnh, nó cũng sẽ trả về cùng một số.

Bạn có thể sử dụng, ví dụ: /tmp/myscript.scratch.$$ làm tệp tạm thời của bạn cho những thứ không cần phải cực kỳ đáng tin cậy hoặc an toàn. Đó là một thực hành tốt để xóa các tập tin tạm thời như vậy ở phần cuối của kịch bản của bạn, sử dụng, ví dụ, bẫy lệnh:

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT 
91

$$ là quá trình ID (PID) trong bash. Sử dụng $$ là một ý tưởng tồi, bởi vì nó thường sẽ tạo ra một điều kiện chủng tộc, và cho phép shell-script của bạn bị lật đổ bởi kẻ tấn công. Xem, ví dụ: tất cả these people đã tạo các tệp tạm thời không an toàn và phải đưa ra các khuyến cáo về bảo mật.

Thay vào đó, hãy sử dụng mktemp. Các Linux man page for mktemp là tuyệt vời. Dưới đây là một số mã mẫu từ nó:

tempfoo=`basename $0` 
TMPFILE=`mktemp -t ${tempfoo}` || exit 1 
echo "program output" >> $TMPFILE 
+3

Cảm ơn bạn. Tùy chọn 'mktemp'' -t' hiện không còn được dùng nữa (tôi nghĩ vì các vấn đề với char '-'). ** Sử dụng 'mktemp $ {tempfoo} .XXXXXX' những ngày này **. Tôi tự do cập nhật bài đăng của bạn. – Sebastian

+0

Cũng xin lưu ý rằng [backtick không được chấp nhận] (http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html#tag_23_02_06_03), vì vậy hãy sử dụng 'TMPFILE = $ (mktemp)' thay thế. –

1

Cho tôi câu trả lời thứ hai của emk - không sử dụng $$ tự nó là một thứ "độc đáo". Đối với các tập tin, sử dụng mktemp. Đối với các ID khác trong cùng một tập lệnh bash, hãy sử dụng "$$$ (ngày +% s% N)" cho hợp lý cơ hội tốt về tính duy nhất.

-k 
0

Ngoài ra, bạn có thể lấy tên người dùng đăng nhập thông qua lệnh này. Ví dụ.

echo $(</proc/$$/login id). After that, you need to use getent command.