إزالة الملفات المؤقتة التي تم إنشاؤها عند خروج bash غير المتوقع

StackOverflow https://stackoverflow.com/questions/687014

  •  22-08-2019
  •  | 
  •  

سؤال

أقوم بإنشاء ملفات مؤقتة من برنامج نصي bash.أقوم بحذفها في نهاية المعالجة، ولكن نظرًا لأن البرنامج النصي يعمل لفترة طويلة، إذا قمت بإيقافه أو ببساطة الضغط على CTRL-C أثناء التشغيل، فلن يتم حذف الملفات المؤقتة.
هل هناك طريقة يمكنني من خلالها التقاط تلك الأحداث وتنظيف الملفات قبل انتهاء التنفيذ؟

أيضًا، هل هناك نوع من أفضل الممارسات لتسمية تلك الملفات المؤقتة وموقعها؟
لست متأكدًا حاليًا بين استخدام:

TMP1=`mktemp -p /tmp`
TMP2=`mktemp -p /tmp`
...

و

TMP1=/tmp/`basename $0`1.$$
TMP2=/tmp/`basename $0`2.$$
...

أو ربما هناك بعض الحلول الأفضل؟

هل كانت مفيدة؟

المحلول

هل يمكن تحديد " فخ " لتنفيذ على خروج أو على ضبط ج للتنظيف.

trap "{ rm -f $LOCKFILE; }" EXIT

وبدلا من ذلك، واحدة من بلدي المفضلة ليونكس المذهبين هو فتح الملف، ثم قم بحذفه في حين لا يزال لديك فتحه. يبقى الملف على نظام الملفات ويمكنك القراءة والكتابة، ولكن بمجرد أن يخرج البرنامج، ملف يذهب بعيدا. لست متأكدا كيف كنت تفعل ذلك في باش، وإن كان.

وراجع للشغل: وسيطة واحدة سأعطيك لصالح mktemp بدلا من استخدام الحل الخاص بك: إذا يتوقع المستخدم البرنامج الخاص بك هو الذهاب لإنشاء الملفات المؤقتة ضخمة، وقال انه قد يريد وضع TMPDIR إلى مكان أكبر، مثل / فار / تمة . يعترف mktemp ذلك، لديك حل باليد تدحرجت (الخيار الثاني) لا. أنا كثيرا ما تستخدم TMPDIR=/var/tmp gvim -d foo bar، على سبيل المثال.

نصائح أخرى

وأنا عادة إنشاء الدليل الذي وضع كل ما عندي من الملفات المؤقتة، وبعدها مباشرة، إنشاء معالج EXIT لتنظيف هذا الدليل عند إنهاء البرنامج النصي.

MYTMPDIR=$(mktemp -d)
trap "rm -rf $MYTMPDIR" EXIT

إذا كنت وضعت جميع الملفات المؤقتة تحت $MYTMPDIR، ثم أنها سوف تكون جميع حذفها عند إنهاء البرنامج النصي في معظم الحالات. قتل عملية مع SIGKILL (قتل -9) يقتل عملية على الفور على الرغم من ذلك لن يتم تشغيل معالج EXIT الخاصة بك في هذه الحالة.

وتحتاج إلى استخدام الأمر فخ للتعامل مع الخروج من البرنامج النصي أو إشارات مثل CTRL-C. انظر ويكي ل جريج للحصول على مزيد من التفاصيل.

لtempfiles، وذلك باستخدام basename $0 هو فكرة جيدة، فضلا عن توفير القالب الذي يوفر مساحة للملفات المؤقتة بما فيه الكفاية:

tempfile() {
    tempprefix=$(basename "$0")
    mktemp /tmp/${tempprefix}.XXXXXX
}

TMP1=$(tempfile)
TMP2=$(tempfile)

trap 'rm -f $TMP1 $TMP2' EXIT

وفقط نأخذ في الاعتبار أن يختار الجواب bashism، وهو ما يعني حل ك

trap "{ rm -f $LOCKFILE }" EXIT

وسيعمل فقط في سحق (لن قبض على Ctrl + ج إذا قذيفة dash أو sh الكلاسيكية)، ولكن إذا كنت تريد التوافق فإنك لا تزال بحاجة إلى تعداد كافة الإشارات التي تريد الفخ.

وكما نضع في اعتبارنا أنه عندما يخرج النصي في فخ لإشارة "0" (الملقب EXIT) يتم تنفيذ دائما مما أدى إلى إعدام مزدوج القيادة trap.

وهذا هو سبب لعدم كومة جميع الإشارات في سطر واحد إذا كان هناك إشارة EXIT.

لفهم أفضل وننظر التالية السيناريو الذي سيعمل عبر الأنظمة المختلفة دون تغييرات:

#!/bin/sh

on_exit() {
  echo 'Cleaning up...(remove tmp files, etc)'
}

on_preExit() {
  echo
  echo 'Exiting...' # Runs just before actual exit,
                    # shell will execute EXIT(0) after finishing this function
                    # that we hook also in on_exit function
  exit 2
}


trap on_exit EXIT                           # EXIT = 0
trap on_preExit HUP INT QUIT TERM STOP PWR  # 1 2 3 15 30


sleep 3 # some actual code...

exit 

وهذا الحل سوف اعطيكم المزيد من السيطرة حيث يمكنك تشغيل بعض التعليمات البرمجية على حدوث إشارة الفعلية قبل الخروج النهائي (وظيفة preExit)، وإذا كانت هناك حاجة يمكنك تشغيل بعض التعليمات البرمجية في إشارة EXIT الفعلية (المرحلة النهائية من الخروج)

البديل المتمثل في استخدام اسم ملف يمكن التنبؤ به مع $$ يمثل ثغرة أمنية كبيرة ويجب ألا تفكر أبدًا في استخدامه.حتى لو كان مجرد برنامج نصي شخصي بسيط على جهاز الكمبيوتر الشخصي الخاص بك.إنها عادة سيئة للغاية لا يجب أن تكتسبها. BugTraq مليء بحوادث "الملف المؤقت غير الآمن".يرى هنا, هنا و هنا لمزيد من المعلومات حول الجانب الأمني ​​للملفات المؤقتة.

كنت أفكر في البداية في اقتباس تخصيصات TMP1 وTMP2 غير الآمنة، ولكن بعد التفكير مرة أخرى، من المحتمل أن يكون ذلك لا تكون فكرة جيدة.

وانا افضل استخدام tempfile التي بإنشاء ملف في / تمة بطريقة آمنة ولم يكن لديك ما يدعو للقلق حول تسمية لها:

tmp=$(tempfile -s "your_sufix")
trap "rm -f '$tmp'" exit

وليس لديك لعناء إزالة هذه الملفات TMP تم إنشاؤها بواسطة mktemp. سيتم حذف أي حال في وقت لاحق.

استخدم mktemp إذا استطعت كما أنها تولد ملفات أكثر فريدة من نوعها ثم '$$' البادئة. ويبدو وسيلة أكثر عبر منصة لإنشاء الملفات المؤقتة ثم صراحة وضعها في / تمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top