शेल स्क्रिप्ट में कोई फाइल मौजूद है या नहीं, इसकी जांच कैसे करें


175

मैं एक शेल स्क्रिप्ट लिखना चाहता हूं, जो यह निश्चित करती है कि कोई निश्चित फ़ाइल archived_sensor_data.jsonमौजूद है, मौजूद है या नहीं, और यदि उसे हटा दिया गया है। Http://www.cyberciti.biz/tips/find-out-if-file-exists-with-conditional-expressions.html के बाद , मैंने निम्नलिखित प्रयास किए हैं:

[-e archived_sensor_data.json] && rm archived_sensor_data.json

हालाँकि, यह एक त्रुटि फेंकता है

[-e: command not found

जब मैं कमांड test_controllerका उपयोग करके परिणामी स्क्रिप्ट को चलाने का प्रयास करता हूं ./test_controller। कोड में क्या गलत है?



2
आपको स्क्वायर ब्रैकेट खोलने के बीच एक या एक से अधिक व्हाट्सएप सेट करना होगा "[" और विकल्प "-e" उसी के रूप में फिल्नाम और क्लोजिंग स्क्वायर ब्रैकेट के बीच "]"
कॉन्स्टेंटिन यानिव

जवाबों:


350

आपको ब्रैकेट के बीच एक आवश्यक स्थान याद आ रहा है और -e:

#!/bin/bash
if [ -e x.txt ]
then
    echo "ok"
else
    echo "nok"
fi

12
मैंने अंत में दो रिक्त स्थान जोड़े, एक उद्घाटन वर्ग कोष्ठक के बाद और एक समापन से पहले [ -e archived_sensor_data.json ] && rm archived_sensor_data.json। स्क्रिप्ट अब काम करने लगती है।
कर्ट पीक

3
यह if [ -e "$1" ](फ़ाइल नाम इनपुट तर्क) का उपयोग करके भी काम करता है ।
एडवर्ड

2
यहां मुख्य अंतर यह है कि आप "शेल" स्क्रिप्टिंग के बजाय "बैश" स्क्रिप्टिंग का उपयोग कर रहे हैं। ध्यान दें कि आपने जो पहली पंक्ति जोड़ी है, वह #! / बिन / बैश थी, इसलिए आप मशीन को श के बजाय "बैश" का उपयोग करने के लिए कह रहे हैं। क्योंकि श उस तर्क "-ई" को नहीं पहचानता है
निक क्यूवास

29

यहाँ एक वैकल्पिक विधि का उपयोग किया गया है ls:

(ls x.txt && echo yes) || echo no

आपकी ओर से कोई उत्पादन को छिपाना चाहते हैं lsतो आप केवल हाँ या नहीं देखते हैं, रीडायरेक्ट stdoutऔर stderrकरने के लिए /dev/null:

(ls x.txt >> /dev/null 2>&1 && echo yes) || echo no

1
इस कोड का अर्थ है: "यदि lsसफल है, तो ऐसी फाइल है, अन्यथा, कोई नहीं है"। यदि lsविफल, इसका मतलब यह नहीं है कि फ़ाइल गायब है। यह कुछ और त्रुटि हो सकती है। उदाहरण के लिए, रूट के स्वामित्व वाली निर्देशिका में फ़ाइल बनाएं और lsनियमित उपयोगकर्ता के तहत करने का प्रयास करें। इसके साथ विफल हो जाएगा Permission denied, जो बराबर नहीं है कि फ़ाइल मौजूद नहीं है।
Tigran

9

मेरे समाधान की सिफारिश की पृष्ठभूमि एक ऐसे मित्र की कहानी है, जिसने अपनी पहली नौकरी के दूसरे सप्ताह में, आधे बिल्ड-सर्वर को साफ कर दिया था। इसलिए मूल कार्य यह पता लगाना है कि क्या कोई फ़ाइल मौजूद है, और यदि ऐसा है, तो इसे हटा दें। लेकिन इस नदी पर कुछ विश्वासघाती रैपिड हैं:

  • सब कुछ एक फाइल है।

  • लिपियों में वास्तविक शक्ति तभी होती है जब वे सामान्य कार्यों को हल करते हैं

  • सामान्य होने के लिए, हम चर का उपयोग करते हैं

  • हम अक्सर मैनुअल हस्तक्षेप से बचने के लिए स्क्रिप्ट में -f बल का उपयोग करते हैं

  • और यह भी सुनिश्चित करने के लिए कि हम समय पर फैशन का निर्माण करें, नकल करें और नष्ट करें।

इस परिदृश्य पर विचार करें:

हमारे पास वह फ़ाइल है जिसे हम हटाना चाहते हैं: filesexists.json

यह फ़ाइल नाम एक चर में संग्रहीत किया जाता है

<host>:~/Documents/thisfolderexists filevariable="filesexists.json"

हम चीजों को वास्तव में लचीला बनाने के लिए एक पथ चर भी करते हैं

<host>:~/Documents/thisfolderexists pathtofile=".."

<host>:~/Documents/thisfolderexists ls $pathtofile

filesexists.json  history20170728  SE-Data-API.pem  thisfolderexists

तो आइए देखें कि -eक्या करना चाहिए। क्या फाइलें मौजूद हैं?

<host>:~/Documents/thisfolderexists [ -e $pathtofile/$filevariable ]; echo $?

0

ऐसा होता है। जादू।

हालाँकि, क्या होगा यदि फ़ाइल चर गलती से नफ़िन के लिए मूल्यांकन किया गया है '

<host>:~/Documents/thisfolderexists filevariable=""

<host>:~/Documents/thisfolderexists [ -e $pathtofile/$filevariable ]; echo $?

0

क्या? यह एक त्रुटि के साथ लौटने वाला है ... और यह कहानी की शुरुआत है कि कैसे दुर्घटना से पूरा फ़ोल्डर हटा दिया गया

एक विकल्प विशेष रूप से परीक्षण के लिए हो सकता है जिसे हम 'फ़ाइल' समझते हैं

<host>:~/Documents/thisfolderexists filevariable="filesexists.json"

<host>:~/Documents/thisfolderexists test -f $pathtofile/$filevariable; echo $?

0

तो फ़ाइल मौजूद है ...

<host>:~/Documents/thisfolderexists filevariable=""

<host>:~/Documents/thisfolderexists test -f $pathtofile/$filevariable; echo $?

1

तो यह एक फ़ाइल नहीं है और शायद, हम उस पूरी निर्देशिका को हटाना नहीं चाहते हैं

man test कहने के लिए निम्नलिखित है:

-b FILE

       FILE exists and is block special

-c FILE

       FILE exists and is character special

-d FILE

       FILE exists and is a directory

-e FILE

       FILE exists

-f FILE

       FILE exists and is a regular file

...

-h FILE

       FILE exists and is a symbolic link (same as -L)

4

आंतरिक रूप से, rm कमांड को फ़ाइल अस्तित्व के लिए वैसे भी परीक्षण करना चाहिए,
इसलिए दूसरा परीक्षण क्यों जोड़ें? बस जारी करो

rm filename

और यह उसके बाद चला जाएगा, चाहे वह वहां था या नहीं।
Rm -f का उपयोग करें यदि आप गैर-मौजूद फ़ाइलों के बारे में कोई संदेश नहीं चाहते हैं।

यदि आपको कुछ कार्रवाई करने की आवश्यकता है यदि फ़ाइल मौजूद नहीं है, तो आपको स्वयं के लिए परीक्षण करना होगा। आपके उदाहरण कोड के आधार पर, इस उदाहरण में ऐसा नहीं है।


1
यह वास्तव में rm कमांड के लिए काफी मान्य उत्तर है। अन्य आदेशों के लिए मैं -e के साथ परीक्षण करने का सुझाव देता हूं।
वॉरहेंसन

सिवाय इसके कि यह सवाल क्या नहीं है।
क्रेयॉन्स

1
यह बहुत अधिक है कि प्रश्न क्या पूछता है, यदि आप "और ... (यदि ऐसा है) ... सहित पूरे प्रश्न को पढ़ते हैं " भाग हटाता है।
TG

1

यदि आप एक NFS का उपयोग कर रहे हैं, तो "परीक्षण" एक बेहतर उपाय है, क्योंकि यदि आप अपना NFS काम कर रहे हैं, तो आप इसमें एक टाइमआउट जोड़ सकते हैं:

time timeout 3 test -f 
/nfs/my_nfs_is_currently_down
real    0m3.004s <<== timeout is taken into account
user    0m0.001s
sys     0m0.004s
echo $?
124   <= 124 means the timeout has been reached

एक "[-E my_file]" निर्माण तब तक जम जाएगा जब तक कि एनएफएस फिर से कार्य नहीं करता:

if [ -e /nfs/my_nfs_is_currently_down ]; then echo "ok" else echo "ko" ; fi

<no answer from the system, my session is "frozen">

testऔर [पर्यायवाची हैं। आप timeoutके [रूप में अच्छी तरह से उपयोग कर सकते हैं , और testअगर एनएफएस लटका भी जमा देता है।
कि अन्य लड़के
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.