วิธีสร้างไดเรกทอรีชั่วคราว


229

ฉันใช้ในการสร้างtempfileลบออกและสร้างเป็นไดเรกทอรี:

tmpnam=`tempfile`
rm -f $tmpnam
mkdir "$tmpnam"

ปัญหาคือกระบวนการอื่นอาจได้รับชื่อเดียวกันXถ้าตั้งใจเรียกใช้ไฟล์ชั่วคราวหลังจากหนึ่งกระบวนการrm -f Xและก่อนหน้าmkdir Xนี้

คำตอบ:


341

mktemp -dใช้ มันสร้างไดเรกทอรีชั่วคราวด้วยชื่อแบบสุ่มและทำให้แน่ใจว่าไฟล์นั้นไม่มีอยู่ คุณต้องจำไว้ว่าให้ลบไดเรกทอรีหลังจากใช้งานแล้ว


25
ฉันต้องใช้mktemp -d -t <prefix>
Heath Borders

17
นี่คือ OS X vs Linux ดูคำถามนี้สำหรับรุ่นที่ใช้งานได้ทั้ง: unix.stackexchange.com/questions/30091/…
jwhitlock

2
นอกจากนี้ดูคำตอบด้านล่างโดย Ortwin เช่นกันซึ่งทำให้แน่ใจว่าการล้างข้อมูลเสร็จสิ้นเช่นกัน
Mathiasdm

5
ทำไมคุณถึงพูดว่า "คุณต้องจำไว้ว่าให้ลบไดเรกทอรีหลังจากใช้งานแล้ว" ไม่ว่าจะเป็นจุดประสงค์ของการใช้ไดเรกทอรีชั่วคราวหรือไม่
MK Safi

73

สำหรับโซลูชันที่มีประสิทธิภาพยิ่งขึ้นฉันใช้บางอย่างดังต่อไปนี้ วิธีนี้จะเป็นการลบ temp dir เสมอหลังจากสคริปต์ออก

ฟังก์ชั่นการล้างข้อมูลจะดำเนินการกับEXITสัญญาณ สิ่งนี้รับประกันว่าจะมีการเรียกใช้ฟังก์ชันการล้างข้อมูลเสมอแม้ว่าสคริปต์จะยกเลิกบางแห่ง

#!/bin/bash    

# the directory of the script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# the temp directory used, within $DIR
# omit the -p parameter to create a temporal directory in the default location
WORK_DIR=`mktemp -d -p "$DIR"`

# check if tmp dir was created
if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then
  echo "Could not create temp dir"
  exit 1
fi

# deletes the temp directory
function cleanup {      
  rm -rf "$WORK_DIR"
  echo "Deleted temp working directory $WORK_DIR"
}

# register the cleanup function to be called on the EXIT signal
trap cleanup EXIT

# implementation of script starts here
...

ไดเรกทอรีของสคริปต์ทุบตีจากที่นี่

ทุบตีกับดัก


26
ข้อควรระวัง FreeBSD! mktemp บน FreeBSD ไม่มีตัวเลือก -p และcleanupจะrm -rf ไดเรกทอรีปัจจุบันของคุณ!
madfriend

1
จุดดีอัปเดตสคริปต์เพื่อตรวจสอบว่าสามารถสร้าง temp dir ได้หรือไม่
Ortwin Angermeier

1
@madfriend จริงเหรอ? หากmktempล้มเหลวWORK_DIRจะว่างเปล่าหมายความว่าคำสั่งจะrm -rfไม่มีข้อโต้แย้ง ฉันไม่ได้ใช้ FreeBSD แต่ฉันต้องแปลกใจถ้าrm -rfเทียบกับrm -rf .
jbg

@ jbg ใช่ฉันก็ดูเหมือนจะแปลกสำหรับฉันเช่นกัน - มันไม่ควรจะเป็นปัญหาใหญ่จริงๆ ฉันอาจปรับแต่งสคริปต์เวอร์ชันเก่าของ tweaked เพื่อให้เส้นทางไปยังไดเรกทอรีชั่วคราวได้รับการคำนวณเทียบกับไดเรกทอรีปัจจุบันส่งผลให้ <s> การสูญพันธุ์ของมนุษย์ </s> กำจัดไดเรกทอรีปัจจุบัน
แฟน

1
เพื่อให้ดีขึ้นคุณสามารถหลีกเลี่ยงไดเรกทอรีว่างหรืออย่างน้อยก็มีปัญหาภายในไดเรกทอรีโดยใช้วิธีแก้ปัญหาที่คุณทำ: 1. TMPWORKDIR=$(basename 'mktemp -d -p /tmp/git/')และ 2 rmdir /tmp/git/"${TMPWORKDIR}". หากตัวแปรว่างเปล่าในตอนนี้คุณจะยังคงถอยกลับไป/tmp/git/ยังระบบทั้งหมดไม่ได้ ลองพิจารณาสิ่งนี้ในคำตอบและฉันก็ยินดีเห็นด้วย ;)
Dr Beco

64

หนึ่งซับที่ชื่นชอบสำหรับสิ่งนี้คือ

cd $(mktemp -d)

10
และrm $(pwd)? : P
Arran Cudbard-Bell

19
มีประโยชน์เช่นกัน: pushd $(mktemp -d)...popd
Ponkadoodle

4
@ ArranCudbard-Bell ควรเป็นrm -r $(pwd)
piggybox

31
@piggybox ตรงไปตรงมาผมจะมากrm -r $(pwd)ระมัดระวังในการใช้ พิจารณาความเป็นไปได้ที่การสร้างไดเรกทอรีชั่วคราวล้มเหลวไม่ว่าด้วยเหตุผลใดก็ตาม (อาจเป็นระบบไฟล์ / tmp เต็มหรือถูกอ่านซ้ำเนื่องจากข้อผิดพลาด?); จากนั้นcd $(mktemp -d)จะประเมินcdว่าการเปลี่ยนแปลงใดในไดเรกทอรีภายในบ้านของผู้ใช้ซึ่งจะถูกลบในภายหลัง
จูลส์

1
มันอาจปลอดภัยด้วยif pushd $(mktemp -d || echo BADMPDIR); then ........ ; rm -r $(pwd); popd; fi
AndreyS Scherbakov

9

ตัวอย่างต่อไปนี้ได้อย่างปลอดภัยจะสร้างไดเรกทอรีชั่วคราว ( -d) TMPDIRและจัดเก็บชื่อของมันเข้าไปใน (ตัวอย่างการใช้TMPDIRตัวแปรจะแสดงในภายหลังในรหัสที่ใช้สำหรับการจัดเก็บไฟล์ต้นฉบับที่อาจมีการแก้ไข)

trapบรรทัดแรกเรียกใช้งานexit 1คำสั่งเมื่อได้รับสัญญาณใด ๆ ที่ระบุ trapบรรทัดที่สองจะลบ (ล้างข้อมูล) $TMPDIRออกจากโปรแกรม (ทั้งปกติและผิดปกติ) เราเริ่มต้นกับดักเหล่านี้หลังจากที่เราตรวจสอบว่าmkdir -dประสบความสำเร็จในการหลีกเลี่ยงการดำเนินการกับดักทางออกโดยไม่ตั้งใจ$TMPDIRในสถานะที่ไม่รู้จัก

#!/bin/bash

# Create a temporary directory and store its name in a variable ...
TMPDIR=$(mktemp -d)

# Bail out if the temp directory wasn't created successfully.
if [ ! -e $TMPDIR ]; then
    >&2 echo "Failed to create temp directory"
    exit 1
fi

# Make sure it gets removed even if the script exits abnormally.
trap "exit 1"           HUP INT PIPE QUIT TERM
trap 'rm -rf "$TMPDIR"' EXIT

# Example use of TMPDIR:
for f in *.csv; do
    cp "$f" "$TMPDIR"
    # remove duplicate lines but keep order
    perl -ne 'print if ++$k{$_}==1' "$TMPDIR/$f" > "$f"
done

1
แม้ว่านี่จะเป็นวิธีแก้ปัญหาที่น่าสนใจสำหรับการจัดการข้อผิดพลาด แต่การอธิบายข้อดีและข้อบกพร่องที่เป็นไปได้อีกเล็กน้อย
เมอร์ฟี

1. ) -dตรวจสอบไดเรกทอรี 2. ) การสิ้นสุดเป็นสัญญาณเริ่มต้นสำหรับสัญญาณเหล่านั้นแล้ว
ceving
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.