سؤال لماذا "cat / dev / null> / var / log / messages`؟


على هذا باش البرنامج النصي المثال الصفحة يقدم المؤلف هذا النص:

# Cleanup
# Run as root, of course.

cd /var/log
cat /dev/null > messages
cat /dev/null > wtmp
echo "Log files cleaned up."

لماذا سوف cat /dev/null على أي شيء؟ لا أستطيع فهم المقصود هنا (هل هو مثل الاستخدام while TRUE; sleep 1; elihw إلى عن على {some busy program}؟). ومع ذلك ، يسميه المؤلف "لا شيء غير عادي".


75
2017-12-06 19:40


الأصل




الأجوبة:


أنت عادة cat /dev/null > [something] عندما تريد مسح محتويات الملف مع التأكد من وجود خطر عدم الانقطاع تمامًا لحالة الملف الفعلية. سيتم مسح محتويات الملف بوضوح من قبل cat /dev/null ومع ذلك ، فإن الملف نفسه - كما هو معروف ومعروف لنظام الملفات الذي يتواجد فيه - سيظل موجودًا بنفس رقم التوحيد والملكية والأذونات.

في حالة ملف السجل ، يمكن أن يكون ملف السجل نفسه "قيد الاستخدام" بواسطة عملية أخرى. هكذا تفعل - على سبيل المثال - rm /var/log/messages && touch /var/log/messages قد يؤدي إلى تعطيل العمليات الأخرى وقد يؤدي إلى اختناق العمليات. وهذا يعني عملية يتم قفلها بطريقة ما إلى رقم محدد في محل الوصول متصل بالملف /var/log/messages يمكن أن يكون الذعر فجأة ويقول "يا! ما حدث ل /var/log/messages! "حتى إذا كان الملف لا يزال موجودًا. ناهيك عن المشاكل المحتملة مع الملكية والأذونات التي يتم إعادة صياغتها بشكل غير صحيح.

بسبب عدم اليقين هذا في استخدام / حالة ملف استخدام cat /dev/null > [something] ويفضل من قبل مسؤولي النظام الذين يرغبون في مسح خارج السجل ولكن لا تريد يحتمل تتداخل مع تشغيل العمليات الموجودة بالفعل.

أيضا، في سياق الصفحة التي ترتبط بها المؤلف يقول ما يلي:

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

لذا فإن "لا شيء غير عادي" الذي يذكره المؤلف هو فيما يتعلق بالمفهوم الكامل لماهية هذا البرنامج النصي الخاص بالباش: إنه مجرد مجموعة من الأوامر البسيطة التي يمكن تشغيلها بنفس السهولة من سطر الأوامر ولكن يتم وضعها في ملف نصي إلى تجنب إعادة كتابتها مرارًا وتكرارًا.


39
2017-12-06 19:50



jlliagre الشيء الوحيد الذي "يبقى على قيد الحياة" هو سياق السؤال الذي يركز على سبب قيام المؤلف الأصلي بذلك. إذا كنت متلهفًا لتبديد "الأسطورة" ، فيرجى نشر إجابة توفر سياقًا لأسلوب ترميز المؤلف الأصلي بالإضافة إلى منظور حول سبب اعتقادك أنه يمكن الاستعاضة عنه بأساليب أخرى. - JakeGould
jlliagre لا تعالج إجابة سايروس السؤال الجوهري عن سبب استخدام المؤلف الأصلي لتلك الطريقة أو المنطق الكامن وراءها. البرنامج التعليمي المذكور قديم جدًا ومقبول بشكل معقول. هذا ليس خطأ ولا يديم "أسطورة حضرية" مفترضة. بدلا من ذلك هو الطريقة التي يرمز بها شخص واحد مقابل الطريقة التي يرمز بها شخص آخر. بهذه البساطة. إنها مشكلة نمط ليس لها أي تأثير سلبي على الموثوقية أو الأداء. - JakeGould
truncate -s 0 من شأنه أن يفعل الشيء نفسه وأن يكون أقل اصطلاحيًا. ومع ذلك ، فإن مبرمجي القذائف عبارة عن مجموعة متحفظة وقد يواجه أحدهم أنظمة قديمة بما فيه الكفاية أو أحمق تكفي لعدم وجود هذا الأمر. - Schwern
skift cat /dev/null > /foo/bar يقطع الملف echo "" > /foo/bar باقتطاعها ثم كتابة حرف newline واحد. - David
ميزة أخرى لهذه الطريقة على rm & touch هي الحفاظ على الملكية والأذونات. - jjmontes


لماذا تقوم بالقط / dev / null على أي شيء؟

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

هناك بديل زائف كثيرًا ما يتم العثور عليه هو إزالة الملف ثم إنشائه مرة أخرى:

rm file
touch file

أو ما شابه:

mv file file.old
gzip file.old
touch file

المشكلة هي أن هذه الطرق لا تمنع حفظ الملف القديم من خلال أي عمليات تتضمن الملف المحذوف مفتوحًا عند وقت الحذف. السبب وراء أنظمة ملفات Unix ، عندما تقوم بحذف ملف ، فإنك تقوم فقط بإلغاء ربط اسمها (المسار) من محتواه (inode). يتم الاحتفاظ inode طالما أن هناك عمليات فتح للقراءة أو الكتابة.

هذا يؤدي إلى العديد من التأثيرات السلبية: يتم فقدان السجلات المكتوبة بعد حذف الملف لعدم وجود طريقة مباشرة / محمولة لفتح ملف محذوف. طالما كانت عملية الكتابة إلى الملف المحذوف ، ما زال محتواها يستخدم مساحة على نظام الملفات. هذا يعني أنه إذا قمت بإزالة / إنشاء الملف لأنه كان يملأ القرص ، يظل القرص ممتلئًا. إحدى الطرق لإصلاح هذه المشكلة الأخيرة هي إعادة تشغيل عمليات التسجيل ولكن قد لا ترغب في القيام بذلك للخدمات الهامة والسجلات الوسيطة ستفقد نهائياً. هناك أيضًا آثار جانبية نظرًا لأن الملف الذي تنشئه قد لا يكون لديه نفس الأذونات والمالك والمجموعة أكثر من الإصدار الأصلي. هذا على سبيل المثال يمكن أن يمنع محلل سجل لقراءة الملف الذي تم إنشاؤه حديثا ، أو ما هو أسوأ ، منع عملية التسجيل لكتابة سجلات خاصة بها.

الطريقة الأولى ، cat /dev/null > file تحقيق الهدف بشكل صحيح ومع ذلك ، على الرغم من الأسطورة الحضرية عنيد ، لها cat /dev/null جزء لا شيء على الاطلاق مفيد. فهو يفتح ملفًا زائفًا فارغًا حسب التصميم ، ويفشل في قراءة أي شيء منه ، وفي النهاية يخرج فقط. إن استخدام هذا الأمر هو إذن ضياع ضربات المفاتيح والبايتات ومكالمات النظام ودورات وحدة المعالجة المركزية ويمكن استبدالها دون أي تغيير وظيفي من خلال أمر لا أوب أسرع. : أو حتى ، مع معظم القذائف ، من دون أي قيادة على الإطلاق.

اسمحوا لي أن أجرب استعارة لشرح كيف عديمة الفائدة cat /dev/null هو. لنفترض أن هدفك هو إفراغ زجاج.

  • عليك أولا إزالة أي سائل منه. هذا يكفي وهو على وجه التحديد ما (> file) في ضوء حقيقة أن عمليات إعادة التوجيه تتم معالجتها دائمًا أولاً.

  • ثم ، اخترت زجاجة فارغة (/dev/null) وسكبها في الزجاج الفارغ (cat). هذه هي الخطوة التي لا طائل منها ...

إذا قرأت المستند المرتبط حتى النهاية ، قد تلاحظ التعليقات في هذا السطر من الإصدار المحسن للبرنامج النصي:

    cat / dev / null> wtmp # ':> wtmp' و '> wtmp' لها نفس التأثير.

لديهم بالفعل. مؤسف جدا cat /dev/null تم الاحتفاظ بها في القانون.

وهذا يعني أن التعليمة البرمجية التالية ستعمل مع كل الأصداف الشائعة (كلاهما csh و sh أسرة):

cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."

وهذا سيعمل مع جميع القذائف باستخدام بنية Bourne ، مثل ash، bash، ksh، zsh ويحب:

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."

لاحظ مع ذلك ، مع قذائف بوريكس بوسيكس القديمة ، أي من هذه الأوامر ، بما في ذلك cat /dev/null لن يتم اقتطاع ملف إذا تمت كتابته بعد ذلك بواسطة نص برنامج shell الذي لا يزال قيد التشغيل. بدلاً من ملف بايت صفر ، من شأنه أن يكون ملف متفرق مع حجمها دون تغيير. نفس الشيء سيحدث إذا كان الملف مكتوبًا بعملية تسعى إلى الموقع الذي يعتقد أنه موجود حاليًا قبل الكتابة.

حذار أيضًا من أن بعض الحلول البديلة التي تقترح غالبًا لاقتطاع ملف بها عيوب.

  • كل من التالية فقط لا تفعل المهمة. الملف الناتج ليس فارغًا ولكنه يحتوي على سطر فارغ. هذا من شأنه كسر ملفات السجل مثل wtmp التي تخزن سجلات عرض ثابتة.

    echo > file
    echo "" > file
    
  • المقبل على أساس BSD sh الخيار غير محمول ، لا تحدد POSIX أي خيارات مسموح بها للصدى ، لذلك قد ينتهي بك الأمر إلى ملف يحتوي على خط به "-n":

    echo -n > file
    
  • هذا واحد غير محمول إما عن طريق استخدام نظام V sh تسلسل الهروب. تقوم بعض الأصداف بإنشاء ملف يحتوي على خط به "\c":

    echo "\c" > file
    
  • يستخدم ذلك أحد الأوامر المصممة للقيام بهذه المهمة. القضية تستخدم truncate غير محمولة لأن هذا الأمر ، غير المحدد بواسطة POSIX ، قد يكون مفقودًا من نظام Unix / Linux.

    truncate -s 0
    

وأخيرًا ، إليك بعض البدائل المحمولة وستنفذ المهمة بشكل صحيح:

  • صراحة طباعة سلسلة فارغة إلى الملف:

    printf "" > file
    
  • باستخدام true الأمر الذي يعادل بشكل صارم واحد لا : وإن كان أكثر قابلية للقراءة:

    true > file
    

121
2017-12-06 21:24



JonathanLeffler وأعتقد أنه جزء من كل الحالي csh عمليات التنفيذ على الرغم من أنها ليست موثقة بالضرورة. من سولاريس csh  صفحة دليل : Null command. This command is interpreted, but performs no action.. لم أجد أي ذكر للنفس في أي منهما tcsh صفحة دليل أو BSD الأصلي csh ولكن ربما نجح هذا النحو. - jlliagre
سبب واحد للكتابة cat /dev/null هو جعل نواياك صريحة. - Davidmh
Davidmh من شأنه أن يكون معقولا ولكن تصريحك لا يقاوم عمليات التحقق من الحقيقة. لقد لاحظت هذه العبارة الصرفية لربما بضعة عقود. عندما أتيحت لي الفرصة لأطلب من المؤلف المنطق وراء ذلك ، وأنا دائما حصلت على نظريات غير سليمة حول استخدام /dev/null كونها طريقة فعالة لحقن صفر بايت ، على أي حال أكثر موثوقية من استخدام : أو لا شيء. في هذه الصفحة بالذات ، كانت إجابة سايروس التي كانت مقتضبة ولكن مباشرة إلى النقطة خالية من الأصوات بينما كان جيك جورد هو الذي كان يتحدى الحقيقة cat /dev/null كان لا شيء (انظر تعليقاتنا) بالفعل أربعة أصوات على الأقل. - jlliagre
jlliagre معرفتي للقذيفة أساسية جدا ، لذلك ربما لا أكون أفضل هدف للسكان. ولكن عارية > أو : غير واضح. أوافق على أنه من العار أن تكون الأساطير قد انتشرت بسبب استخدامها. - Davidmh
Davidmh إذا كنت تريد حقا شيء واضح قبل إعادة التوجيه ، أود أن أوصي به printf "" > file وهو محمول على حد سواء (POSIX) وخفيف الوزن كما يتم تنفيذه في كثير من الأحيان كمبنى shell. - jlliagre


إنها طريقة معقدة لإحضار الملف إلى الحجم صفر.

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."

6
2017-12-06 19:44



لن تعمل هذه البنية في كل صدفة. - reinierpost
صيح. يتم وضع علامة على السؤال فقط مع "باش". - Cyrus
reinierpost وسوف تعمل في جميع قذائف على غرار بورن ، أليس كذلك؟ دعونا لا تقلق csh. - Barmar
: > messagesيعمل أيضا. : أو true هي الخيارات الأكثر وضوحًا للأوامر التي لا تطبع أي شيء وترجع إلى true. - Peter Cordes


لاقتطاع ملف مفتوح. هذا ما يعادل ، وأكثر قابلية للفهم:

echo -n > /var/log/messages

(تمت إضافة -n لتجنب السطر الجديد)


-3
2017-12-07 18:29



هذا هو في الواقع أكثر مفهومة ولكن للأسف لا يعادل. حتى انه كسر وظائف مثل في wtmp قضية. انظر إجابتي المحدثة. - jlliagre
الصدى على تجنب الخط الجديد. - bbaassssiiee
سيكون بالفعل إذا كنت متأكدا من استخدامها bash، -n لا يضمن العمل في جميع قذائف Bourne. - jlliagre