किसी फ़ाइल पर लिखने के लिए गैर-इनवेसिव परीक्षण कैसे करें?


20

एक शेल स्क्रिप्ट में, मैं वास्तव में फ़ाइल को संशोधित करने का प्रयास किए बिना किसी फ़ाइल तक पहुंच लिखने के लिए आसानी से और गैर-इनवेसिव परीक्षण कैसे कर सकता हूं ?

मैं के आउटपुट को पार्स कर सकता था stat, लेकिन यह वास्तव में जटिल लगता है, और शायद भंगुर है, हालांकि मुझे यकीन नहीं है कि कितना स्टैड आउटपुट पूरे कार्यान्वयन और समय में भिन्न होता है।

मैं फ़ाइल के अंत में संलग्न हो सकता हूं और देख सकता हूं कि क्या यह सफल होता है, लेकिन यह संभावित रूप से खतरनाक है, दो कारणों से मैं इसके बारे में सोच सकता हूं:

  1. मुझे अब इसके अतिरिक्त को हटाना होगा, और यदि कोई अन्य प्रक्रिया फ़ाइल को लिखती है, तो यह तुरंत गैर-तुच्छ हो जाती है क्योंकि मेरी रेखा अब अंतिम नहीं है।
  2. फ़ाइल को पढ़ने की किसी भी प्रक्रिया में उस फ़ाइल की सामग्री पर मनमानी आवश्यकताएं हो सकती हैं, और हो सकता है कि मैंने उस एप्लिकेशन को तोड़ दिया हो।

जवाबों:


29

बस यूटिलिटी के wध्वज का उपयोग करें test:

[ -w /path/to/file ] && echo "writeable" || echo "write permission denied"

ध्यान दें कि यदि आप बाद में फ़ाइल में लिखने जा रहे हैं, तो यह अभी भी संभव है कि आप इसे लिखने में सक्षम नहीं होंगे। फ़ाइल स्थानांतरित हो सकती है, अनुमतियाँ बदल सकती हैं, आदि। यह भी हो सकता है कि -wलिखने की अनुमति का पता लगाता है, लेकिन कुछ अन्य कारक हस्तक्षेप करते हैं ताकि फ़ाइल को लिखने योग्य न बनाया जा सके


1
बेशक! मुझे परीक्षण के मैन पेज की जांच करने के लिए सोचना चाहिए था। धन्यवाद।
user50849

1
@qweilun यह एक शेल बिल्डिन है, लेकिन आप इसके माध्यम से मैन पेज को प्रदर्शित कर सकते हैं man testयाman [
अराजकता

5
@ आचोस यह शेल शेल और बाहरी निष्पादन योग्य दोनों है - कोशिश करेंtype -a
वोल्कर सिएगल

1
प्रति स्रोतtest का उपयोग करता है euidaccessजो बस अनुमति बिट्स की जाँच करता है । क्या अन्य कारक (जैसे SELinux) नहीं हैं जो लिखने की पहुँच को रोक सकते हैं?
zamnuts

2
@ ब्रोसलो, &&और ||समान मिसाल है। उनका मूल्यांकन बाएं से दाएं किया जाता है।
वाइल्डकार्ड

11

एक और तरीका:

if >> /path/to/file
then
    echo "writeable"
else
    echo "write permission denied"
fi

यह है कि अगर सफल होता है, जोड़कर के लिए फ़ाइल को खोलने का प्रयास करेंगे, और, चलाने के लिए कोई आदेश (यानी, एक अशक्त आदेश चला फाइल करने के लिए उत्पादन के साथ)। 

अगर यह मौजूद नहीं था तो एक खाली फ़ाइल बनाएं।

कमांड का -wऑपरेटर testबस एक काम कर सकता है stat और फिर यह पता लगाने की कोशिश कर सकता है कि ऐसा लगता है कि आपके पास पहुंच होनी चाहिए। मेरा विकल्प (ऊपर) testकुछ विशेष परिस्थितियों में दृष्टिकोण से अधिक विश्वसनीय है , क्योंकि यह शेल के बजाय कर्नेल द्वारा किए जाने वाले एक्सेस चेक को बाध्य करता है। उदाहरण के लिए,

  • यदि फ़ाइल एक गैर-यूनिक्स फ़ाइल सिस्टम पर है - विशेष रूप से यदि यह एक गैर-यूनिक्स फ़ाइल सर्वर से दूरस्थ रूप से मुहिम की जाती है - क्योंकि statएक मोड मान वापस आ सकता है जो भ्रामक है।
  • यदि फ़ाइल किसी फ़ाइल सिस्टम पर है जो केवल पढ़ने के लिए मुहिम की जाती है।
  • यदि फ़ाइल में ACL है, और यह मोड ऐसा दिखता है जैसे आपके पास पहुंच होनी चाहिए, लेकिन ACL इससे इनकार करता है, या इसके विपरीत।
  • अगर कुछ सुरक्षा ढांचे (AppArmor, SELinux,…) फ़ाइल तक पहुंच से इनकार करते हैं।

3
मैंने बस (डेबियन पर) इसका परीक्षण किया। न तो समय में कोई फेरबदल किया गया, और यही वह तरीका है जो किसी भी यूनिक्स पर काम करना चाहिए। एक्सेस समय को केवल तभी अपडेट किया जाना चाहिए जब आप फ़ाइल से पढ़ते हैं, संशोधित समय केवल तभी अपडेट किया जाना चाहिए जब आप फ़ाइल पर लिखते हैं। यह कोड न तो। @ शंख: क्या आपके पास अपने बयान के लिए एक संदर्भ है? क्या आपमें से किसी ने इसे आजमाया है?
जी-मैन का कहना है कि 'मोनिका'

2
PS @muru: मैंने बस touchएक ऐसी फ़ाइल की कोशिश की, जिसके स्वामित्व में मैं था लेकिन उसके पास लिखने की पहुँच नहीं थी, और यह सफल रहा। मुझे लगता है कि यह chmodफ़ाइल है और chmodयह वापस आ गया है। तो touchसवाल के जवाब के रूप में बिल्कुल बेकार प्रतीत होता है।
जी-मैन का कहना है कि 'मोनिका'

2
@ जी-मैन आह, यह दिलचस्प है। IIRC के vimपास केवल-पढ़ने वाली फ़ाइलों पर लिखने के लिए बाध्य होने पर अनुमतियों को बदलने का व्यवहार है। मैं के साथ की जाँच strace, touchके openसाथ विफल रहता है EACCES, लेकिन बाद में कॉल करने के लिए utimensatसफल होता है, जिसके कारण मुझे लगता है कि touchसफलतापूर्वक पूरे रास्ते पर।
मुरु

2
@ मुरु: जाँच के लिए धन्यवाद। utimensat(2)कहते हैं, " अनुमतियाँ आवश्यकताएँ: 1. लेखन पहुँच (या) 2. कॉलर की प्रभावी उपयोगकर्ता आईडी को फ़ाइल के स्वामी से मेल खाना चाहिए, ..."
G-Man Says 'Reinstate Monica'

3
Champignac के लिए अन्य समस्याएं जैसे: >> fileपोर्टेबल नहीं है (उदाहरण के लिए, NULLCMD को zsh में चलाता है), true >> fileइसके बजाय उपयोग करें । और अगर फ़ाइल एक नामित पाइप है, तो इसका बुरा दुष्प्रभाव है।
स्टीफन चेज़लस

3

G- आदमी सही है: हमेशा सच [ -w ]नहीं बताएगा गैर-मौजूदा फ़ाइल और शेल से अनुमति अस्वीकृत संदेश का सामना करने के लिए :

( [ -e /path/to/file ] && >> /path/to/file ) 2> /dev/null && 
  echo writable || 
  echo not writable

अद्यतन : भयावह लगता है, है ना? यह ठीक है। हम्म ... इसे कैसे वाक्यांशित किया जाए ... इसका उपयोग न करें, जब तक कि आप पूरी तरह से नहीं जानते कि आप उन परिस्थितियों में हैं जब यह अपेक्षित रूप से काम करने का अनुरोध करता है। स्टीफन की टिप्पणी देखें।

फिर क्या निष्कर्ष निकालना है? भले ही [ -w ]वह सच न बताए, यह एक ऐसा आदेश है जो काम करने का इरादा है। यदि यह नहीं होता है, तो ठीक है, हम इसे दोष देंगे, बग रिपोर्ट लिखें, और यह भविष्य में काम करेगा। उन परिस्थितियों की बेहतर जांच करें जिनके तहत यह काम करता है और उपयोग करता है [ -w ]; विशेष मामलों के लिए विशेष कोड लिखें। Workarounds की अपनी शर्तें हैं।

[ -w /path/to/file ]

सबसे अच्छी प्राथमिकता है


3
यदि फ़ाइल एक नामांकित पाइप है, तो यदि कोई रीड नहीं है, तो यह लटका हुआ होगा, और यहां तक ​​कि अगर एक रीडर में बुरा साइड इफेक्ट होगा। test -wअधिकांश कार्यान्वयन में access(2)अनुमतियों का परीक्षण करने के लिए पर्याप्त होना चाहिए।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.