ค้นหา tmp dir ที่ถูกต้องบนหลาย ๆ แพลตฟอร์ม


46

ฉันมีสคริปต์ที่ต้องการสร้างไฟล์ชั่วคราวสำหรับการทำงานและล้างข้อมูลหลังจากนั้น คำถามของฉันเกี่ยวกับการค้นหาไดเรกทอรีฐานที่เหมาะสมสำหรับไฟล์ชั่วคราว

สคริปต์ต้องทำงานกับหลายแพลตฟอร์ม: Git Bash (Windows), Solaris, Linux, OSX ในแต่ละแพลตฟอร์มไดเรกทอรีชั่วคราวที่ต้องการจะแสดงแตกต่างกัน:

  • Windows: %TMP%(และอาจเป็นไปได้%TEMP%)
  • OSX: $TMPDIR
  • Linux, UNIX: น่าจะเป็น$TMPDIRแต่ดูเหมือนว่าจะไม่มีการตั้งค่าในหลาย ๆ ระบบที่ฉันได้ลอง

ดังนั้นในสคริปต์ของฉันฉันเพิ่มแผ่นสำเร็จรูปนี้:

if test -d "$TMPDIR"; then
    :
elif test -d "$TMP"; then
    TMPDIR=$TMP
elif test -d /var/tmp; then
    TMPDIR=/var/tmp
else
    TMPDIR=/tmp
fi

ดูเหมือนว่าน่าเบื่อเกินไป มีวิธีที่ดีกว่า?


6
เพียงใช้${TMPDIR-/tmp}กับ Unix-like TMPDIRมี (โดยระบบหรือผู้ดูแลระบบหรือผู้ใช้) ที่จะบอกคุณเมื่อไม่ใช้/tmpสำหรับไฟล์ชั่วคราว
Stéphane Chazelas

คำตอบ:


72

วิธีพกพาที่ใช้จัดการไฟล์ชั่วคราวได้ง่ายmktempขึ้นเล็กน้อย มันจะสร้างไฟล์ชั่วคราวและคืนเส้นทางให้คุณ ตัวอย่างเช่น

$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P

คุณสามารถใช้มันในสคริปต์ได้อย่างง่ายดายมาก:

tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile

การอ่าน man page คุณควรจะสามารถตั้งค่าตัวเลือกได้ตามความต้องการของคุณ ตัวอย่างเช่น

  • -d สร้างไดเรกทอรีแทนไฟล์
  • -u สร้างชื่อ แต่ไม่ได้สร้างอะไรเลย

การใช้-uคุณสามารถดึงข้อมูลไดเรกทอรีชั่วคราวได้ง่าย ๆ ด้วย ...

$ tmpdir=$(dirname $(mktemp -u))

ข้อมูลเพิ่มเติมเกี่ยวกับmktempที่นี่

แก้ไขเกี่ยวกับ Mac OS X:ฉันไม่เคยใช้ระบบ Mac OSX แต่จากความคิดเห็นของ Tyilo ด้านล่างดูเหมือนว่า Mac OSX mktempต้องการให้คุณให้แม่แบบ (ซึ่งเป็นอาร์กิวเมนต์ที่เป็นตัวเลือกบน Linux) พิเศษ:

แม่แบบอาจจะเป็นชื่อไฟล์ใด ๆ ที่มีจำนวนบางส่วนของ "Xs" /tmp/temp.XXXXผนวกเข้ากับมันเช่น "Xs" ต่อท้ายจะถูกแทนที่ด้วยหมายเลขกระบวนการปัจจุบันและ / หรือการรวมตัวอักษรที่ไม่ซ้ำกัน จำนวนชื่อไฟล์ที่ไม่ซ้ำกัน mktemp สามารถส่งคืนได้ขึ้นอยู่กับจำนวนของ "Xs" ที่ระบุ หก "Xs" จะส่งผลให้ mktemp เลือก 1 จาก 56800235584 (62 ** 6) ชื่อไฟล์ที่เป็นไปได้

หน้าคนยังกล่าวว่าการดำเนินการนี้เป็นแรงบันดาลใจหน้าคน OpenBSD mktempสำหรับ ผู้ใช้ OpenBSD และ FreeBSD อาจสังเกตเห็นความแตกต่างที่คล้ายกันเช่นกัน (ดูหัวข้อประวัติ )

ทีนี้อย่างที่คุณอาจสังเกตเห็นสิ่งนี้ต้องการให้คุณระบุเส้นทางไฟล์ที่สมบูรณ์รวมถึงไดเรกทอรีชั่วคราวที่คุณกำลังมองหาในคำถามของคุณ ปัญหาเล็กน้อยนี้สามารถจัดการได้โดยใช้-tสวิตช์ ในขณะที่ตัวเลือกนี้ดูเหมือนจะต้องมีการโต้แย้ง ( prefix) มันจะปรากฏขึ้นที่mktempอาศัย$TMPDIRเมื่อจำเป็น

สรุปคุณควรจะได้รับผลลัพธ์เช่นเดียวกับการใช้ ...

$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))

ข้อเสนอแนะใด ๆ จากผู้ใช้ Mac OS X จะได้รับการชื่นชมอย่างมากเนื่องจากฉันไม่สามารถทดสอบวิธีนี้ได้ด้วยตนเอง


OP ระบุถึงปัญหานี้ในความคิดเห็นที่ถูกลบทันที ฉันเกรงว่าฉันไม่สามารถให้คำตอบสำหรับระบบที่ต้องการgitbashได้รับส่วนต่อประสานเชลล์ดังนั้น "เล็กน้อย" ของฉัน ที่จริงผมจะไม่สามารถบอกได้ว่าไฟล์ temp จะถูกเก็บไว้บนระบบ Windows ...
จอห์นสมิ ธ WH

1
เหมือนกันว่า c:\User\Name\..............\stuffบางบ้า และอาจมี 100 ของพวกเขา ยังคงบาง distros /varลินุกซ์กำลังใกล้เข้ามาในระดับเดียวกันของความบ้าใน ผมก็แค่อยากรู้. มันทำให้ฉันรู้สึกแปลก ๆ ที่จะใส่มันทั้งหมด - ในประสบการณ์ของฉันความหงุดหงิดแบบพกพามากและความสะดวกสบายน้อยลง คำตอบที่ดีมากอยู่แล้ว
mikeserv

1
หนึ่งปีที่ผ่านมาฉันเขียนสคริปต์ Bash เพื่อจัดการไฟล์ Windows Restore Point ที่ทำงานบน Win2K ผ่านไปยัง WinXP (รุ่นที่ใหม่กว่าจะจัดการกับสิ่งต่าง ๆ ได้) สคริปต์ของฉันใช้WINDOWS/TempหรือWindows/Tempเป็นไดเรกทอรีเริ่มต้นสำหรับไฟล์ชั่วคราว ไดเรกทอรีนั้นยังมีอยู่ในเครื่อง Windows 7 แต่สคริปต์ของฉันอนุญาตให้ผู้ใช้สามารถจัดหา temp dir อื่นบนบรรทัดคำสั่ง
PM 2Ring

นี้จะไม่ทำงานบน OS X, mktempที่คุณมีในการจัดหาแม่แบบ
Tyilo

1
ตั้งแต่ El Capitan mktempเพียงใช้งานได้: simple mktempส่งคืนไฟล์และmktemp -dส่งคืนไดเร็กทอรี ไม่จำเป็นต้องมีเทมเพลต คู่มือจะไม่ปรับปรุงแม้ว่า
แฟรงคลินหยู

9

หากคุณกำลังมองหาสิ่งเดียวกันในบรรทัดที่น้อยลง ...

for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
    test -d "$TMPDIR" && break
done

คุณสามารถเขียนสิ่งนี้ได้ในที่เดียว


คุณควรทดสอบด้วยว่ามันเขียนได้หรือไม่
frostschutz

@janos: และหากทั้งหมดอื่นล้มเหลวขอให้ผู้ใช้ระบุเส้นทางสำหรับไฟล์ temp หรืออนุญาตให้พวกเขาระบุหนึ่งในบรรทัดคำสั่ง
PM 2Ring

6

คุณอาจจะ:

: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit

เชลล์ควรหาไดเร็กทอรีที่สามารถเรียกทำงานได้ในหนึ่งใน 4 ทางเลือกหรือออกด้วยข้อผิดพลาดที่มีความหมาย ยัง POSIX กำหนด$TMPDIRตัวแปร(สำหรับระบบ XCU) :

TMPDIR ตัวแปรนี้จะแสดงถึงชื่อพา ธ ของไดเรกทอรีที่มีให้สำหรับโปรแกรมที่ต้องการสถานที่ในการสร้างไฟล์ชั่วคราว

นอกจากนี้ยังต้องใช้/tmpเส้นทาง


1
นี่เป็นคำตอบเดียวที่ถูกต้องที่นี่ IMO Dunno กำลังนั่งลงที่ส่วนล่างโดยไม่ลงคะแนนเลย ...
Graeme

2
@ Graeme: อาจเป็นเพราะมันอ่านไม่ได้อย่างเต็มที่?
ssc

ฉันลงคะแนนแล้ว แต่ถอนกลับ - ใช่คำตอบนี้เป็นระเบียบดูเหมือนว่าจะเป็นเพลงที่มีประโยชน์ แต่ก็ไม่ชัดเจนว่าโค้ด snippit พยายามทำอะไร - บรรทัดแรกคือความคิดเห็นและที่สอง หนึ่งคือข้อผิดพลาด (ในทุบตีแล้ว) สามารถใช้งานได้
Don Hatch

โอ้ฉันเข้าใจแล้วรุ่นแรกของคำตอบนั้นชัดเจนขึ้น (ยังคงมีข้อผิดพลาดในบรรทัดที่ 2 หากคุณพยายามเรียกใช้) แม้ว่า ... และจากนั้นชุดการแก้ไขหลายชุดจึงทำการทิ้งตัวอย่างโค้ดเพื่อให้มันไร้สาระ สามารถใช้อีกหนึ่งหรือสอง :-)
Don Hatch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.