$$ หมายความว่าอะไรในเปลือกหอย?


143

ฉันเคยอ่านว่าวิธีหนึ่งในการรับชื่อไฟล์ที่ไม่ซ้ำในเชลล์สำหรับไฟล์ temp คือการใช้เครื่องหมายดอลลาร์สองครั้ง ( $$) สิ่งนี้จะสร้างตัวเลขที่แตกต่างกันเป็นครั้งคราว ... แต่ถ้าคุณเรียกมันซ้ำ ๆ มันจะส่งกลับหมายเลขเดิม (การแก้ปัญหาคือเพียงใช้เวลา)

ฉันอยากรู้ว่า$$จริง ๆ แล้วคืออะไรและทำไมมันถึงได้รับการแนะนำว่าเป็นวิธีในการสร้างชื่อไฟล์ที่ไม่เหมือนใคร

คำตอบ:


102

ใน Bash $$คือ ID กระบวนการตามที่ระบุไว้ในความคิดเห็นไม่ปลอดภัยที่จะใช้เป็นชื่อไฟล์ชั่วคราวด้วยเหตุผลหลายประการ

สำหรับชื่อไฟล์ชั่วคราวให้ใช้mktempคำสั่ง


35
สำหรับผู้ที่เพิ่งดูคำตอบยอดนิยม $$ ไม่เหมาะสำหรับแม้แต่ไฟล์เดียวหากเขียนไปยังไดเรกทอรีที่เขียนได้แบบสาธารณะ (เช่น / tmp) ง่ายต่อการทิ้งขยะ / tmp ด้วย symlink ที่จะทำให้สคริปต์ของคุณเขียนที่ไม่พึงประสงค์ mktemp ดีกว่ามาก
Chris Jester-Young

4
ใช่การใช้ $$ จะทำให้เกิดช่องโหว่ด้านความปลอดภัย อย่าทำมัน
emk

7
หรือบุคคลที่ถามคำถามควรตั้งค่าคำตอบที่ได้รับการจัดอันดับสูงกว่าด้านล่างเป็นคำตอบที่ยอมรับ ...
jtimberman

6
ฉันเพิ่ม "ดอลลาร์ดอลลาร์" สำหรับ SEO
แอนทอน

1
ถ้า $$ เพียงแค่ส่ง pid ออกมามันจะ "ไม่ปลอดภัย" ได้อย่างไร? รูโหว่ถูกสร้างขึ้นโดยอาศัยการออกแบบที่ไม่ดีไม่ใช้ PID ในชื่อไฟล์ tmp ... ถ้าคุณสนใจเกี่ยวกับความสมบูรณ์ของเอาต์พุตที่ไปยัง tmp มากบางทีคุณไม่ควรใส่มันไว้ในตอนแรกเลยล่ะ? $$ จะไม่ทำให้เกิดช่องโหว่ด้านความปลอดภัยการมองการณ์ไกลจะไม่เป็นเช่นนั้น
niken

113

$$คือ ID กระบวนการ (PID) ใน bash การใช้$$เป็นความคิดที่ไม่ดีเพราะโดยปกติแล้วจะสร้างเงื่อนไขการแข่งขันและอนุญาตให้ผู้โจมตีโจมตีเชลล์สคริปต์ของคุณ ยกตัวอย่างเช่นทุกคนที่สร้างไฟล์ชั่วคราวที่ไม่ปลอดภัยและต้องออกคำแนะนำด้านความปลอดภัย

mktempแต่การใช้งาน หน้าคน Linux สำหรับ mktempเป็นเลิศ นี่คือตัวอย่างรหัสจากมัน:

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

3
ขอบคุณ mktempตัวเลือกที่-tจะเลิกตอนนี้ (ฉันคิดว่าเนื่องจากปัญหาเกี่ยวกับถ่าน-) ใช้mktemp ${tempfoo}.XXXXXXวันนี้ ฉันมีเสรีภาพในการอัพเดทโพสต์ของคุณ
เซบาสเตียน

1
โปรดทราบว่าbacktick เลิกใช้แล้วดังนั้นควรใช้TMPFILE=$(mktemp)แทน
Michael Kopp


7

ทุกกระบวนการใน UNIX เช่นระบบปฏิบัติการจะมีตัวระบุเฉพาะ (ชั่วคราว) PID ไม่มีสองกระบวนการที่ทำงานในเวลาเดียวกันสามารถมี PID ที่เหมือนกันและ $$ อ้างถึง PID ของอินสแตนซ์ bash ที่รันสคริปต์

นี่ไม่ใช่ตัวบ่งชี้เฉพาะในแง่ที่ว่ามันจะไม่ถูกนำมาใช้ซ้ำ (จริง ๆ แล้ว PID จะถูกนำมาใช้ซ้ำอย่างต่อเนื่อง) สิ่งที่ทำให้คุณมีจำนวนนั้นถ้าบุคคลอื่นเรียกใช้สคริปต์ของคุณพวกเขาจะได้รับตัวระบุที่แตกต่างกันในขณะที่คุณยังคงทำงานอยู่ เมื่อคุณตาย PID อาจถูกรีไซเคิลและบางคนอาจเรียกใช้สคริปต์ของคุณรับ PID ที่เหมือนกันและรับชื่อไฟล์เดียวกัน

เช่นนี้มันมีเหตุผลจริงๆที่จะพูดว่า "$$ ให้ชื่อไฟล์เช่นว่าถ้ามีคนอื่นที่ทำงานสคริปต์เดียวกันที่อินสแตนซ์ของฉันยังคงทำงานอยู่พวกเขาจะได้รับชื่ออื่น"


5

$$ เป็น PID ของคุณ มันไม่ได้สร้างชื่อไฟล์ที่เป็นเอกลักษณ์จริง ๆ เว้นแต่คุณจะระมัดระวังและไม่มีใครทำแบบเดียวกัน

โดยทั่วไปแล้วคุณจะสร้างบางสิ่งเช่น / tmp / myprogramname $$

มีหลายวิธีที่จะทำลายสิ่งนี้และถ้าคุณเขียนไปยังสถานที่ที่คนอื่นสามารถเขียนถึงมันก็ไม่ยากเกินไปในระบบปฏิบัติการหลายระบบในการทำนายว่า PID ใดที่คุณจะมีและหมุนไปรอบ ๆ เป็นรากและฉันสร้าง / tmp / yourprogname13395 เป็น symlink ชี้ไปที่ / etc / passwd - และคุณเขียนมัน

นี่เป็นสิ่งที่ไม่ดีที่จะทำในเชลล์สคริปต์ หากคุณกำลังจะใช้ไฟล์ชั่วคราวสำหรับบางสิ่งคุณควรใช้ภาษาที่ดีกว่าซึ่งอย่างน้อยที่สุดจะช่วยให้คุณเพิ่มการตั้งค่าสถานะ "เอกสิทธิ์" เพื่อเปิด (สร้าง) ไฟล์ จากนั้นคุณสามารถมั่นใจได้ว่าคุณจะไม่ปิดบังสิ่งอื่น


3

$$ เป็น pid ของกระบวนการเชลล์ปัจจุบัน มันไม่ใช่วิธีที่ดีในการสร้างชื่อไฟล์ที่ไม่เหมือนใคร


3

$$ คือ pid (id กระบวนการ) ของตัวแปลเชลล์ที่รันสคริปต์ของคุณ มันแตกต่างกันไปสำหรับแต่ละกระบวนการที่ทำงานบนระบบในขณะนี้ แต่เมื่อเวลาผ่านไป pid จะวนไปมาและหลังจากที่คุณออกไปแล้วจะมีอีกกระบวนการหนึ่งที่มี pid เดียวกันในที่สุดตราบใดที่คุณกำลังทำงาน pid นั้นก็ไม่เหมือนใคร

จากคำนิยามข้างต้นควรเห็นได้ชัดว่าไม่ว่าคุณจะใช้ $$ ในสคริปต์กี่ครั้งก็จะส่งกลับหมายเลขเดิม

คุณสามารถใช้เช่น /tmp/myscript.scratch.$$ เป็นไฟล์ temp ของคุณสำหรับสิ่งที่ไม่น่าเชื่อถือหรือปลอดภัยอย่างยิ่ง เป็นวิธีที่ดีที่จะลบไฟล์ temp ดังกล่าวในตอนท้ายของสคริปต์โดยใช้คำสั่ง trap:

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

2

เป็นรหัสกระบวนการของกระบวนการทุบตี ไม่มีกระบวนการที่เกิดขึ้นพร้อมกันจะมี PID เดียวกัน


2

$$ เป็นรหัสกระบวนการของเชลล์ที่สคริปต์ของคุณกำลังทำงาน สำหรับรายละเอียดเพิ่มเติมโปรดดูหน้า man สำหรับ sh หรือ bash สามารถพบ man page ได้โดยใช้บรรทัดคำสั่ง "man sh" หรือโดยการค้นหาเว็บเพื่อหา "shell manpage"


2

ให้ฉันคำตอบที่สองของ emk - อย่าใช้ $$ ด้วยตัวเองเป็นอะไรที่ "ไม่เหมือนใคร" สำหรับไฟล์ใช้ mktemp สำหรับรหัสอื่น ๆ ที่อยู่ในสคริปต์ทุบตีเดียวกันใช้ "$$$ วันที่ (+% s% N)" สำหรับเหตุผลที่โอกาสที่ดีของความเป็นเอกลักษณ์

 -k

0

นอกจากนี้คุณสามารถคว้าชื่อผู้ใช้เข้าสู่ระบบผ่านคำสั่งนี้ เช่น.

echo $(</proc/$$/login id). After that, you need to use getent command.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.