बैश सिंटैक्स त्रुटि जब "और" एक खाली "तब" खंड का अनुसरण करता है


36

निम्नलिखित स्क्रिप्ट निष्पादित क्यों नहीं करती है, लेकिन एक सिंटैक्स त्रुटि दें else:

LOGS3_DIR=~/logs
if [ -d "$LOGS3_DIR" ]; then
 cd
 cd "$LOGS3_DIR"
 echo "$LOGS3_DIR"
 for filename in `find "." -mtime 1 -type f`
  do
  if lsof "$filename" > /dev/null
  then
    # file is open
  else
    echo "deleting $filename"
    rm "$filename"
  fi
 done
fi

जवाबों:


23

के आउटपुट पर कमांड प्रतिस्थापन का उपयोग न करेंfind । यहाँ, सब कुछ के साथ किया जा सकता है find:

find . -mtime 1 -type f ! -exec lsof -t {} \; -exec rm -f {} \; > /dev/null

कुछ findकार्यान्वयन के साथ (FreeBSD findजिसमें यह कहां से और GNU आता है find) शामिल हैं, आप -deleteइसके बजाय उपयोग कर सकते हैं -exec rm...

कारण आपको कोई त्रुटि हो रही है वहाँ के बीच कोई आदेश है कि है thenऔर elseऔर कुछ गोले (बॉर्न शैल जहां कि वाक्य रचना से आता है के साथ शुरू) कम से कम एक की आवश्यकता होती है (और एक टिप्पणी एक आदेश नहीं है)। ध्यान दें कि यह पूरी तरह से मनमाना है और कोई कारण नहीं है कि वे गोले ऐसा क्यों करेंगे। yashऔर zshवह सीमा नहीं है ( if false; then else echo x; fiऔर यहां तक ​​कि if false; then else fiउनके साथ ठीक काम भी करते हैं)।

जैसा कि अन्य लोगों ने कहा है, आप कीवर्ड के साथ :(या for nothing in; do nothing; done) की तरह एक नूप कमांड का उपयोग कर सकते हैं या !कीवर्ड के साथ तर्क को उल्टा कर सकते हैं (POSIX गोले में उपलब्ध है, लेकिन बॉर्न शेल नहीं है (आप पाएंगे कि इसके लिए उपयोग :करना उस शेल में आम था)। mkshऔर yashसमर्थन करने के लिए होता है if false; then () else echo x; fi(मैं इस पर भरोसा नहीं करेगा क्योंकि भविष्य के संस्करणों में बदल सकता है)।

एक और दृष्टिकोण इसके साथ है:

lsof... || {
  cmd1
  cmd2
}

हालांकि एक अंतर समग्र बाहर निकलें स्थिति जो होगा इस बात का है lsofकि अगर lsofविफल रहता है।


17
हालांकि यह एक बहुत बेहतर तरीका है जो @Novice उपयोगकर्ता प्रयास कर रहा है, यह प्रश्न का उत्तर नहीं देता है।
SeeJayBee

जबकि -execअक्सर उपयोगी होता है, जैसा कि होता है xargs, कभी-कभी शेल लूप की आवश्यकता होती है। जिस स्थिति में एक while read nameलूप पसंदीदा विकल्प है (जीएनयू के साथ टकराव में, आप दोनों के लिए -0 विकल्प का उपयोग कर सकते हैं; पोर्टेबली आपको न्यूलाइन पर छोड़ देना होगा)।
जन हुदेक

@ जानहुडेक, वहाँ तरीके हैं। -print0है -exec printf '%s\0' {} +(लेकिन portably आप अगर तुम पर विचार करना चाहते सिवाय इसके कि उत्पादन के साथ सौदा नहीं कर सकते हैं perl), और साथ find .//.और कुछ पोस्ट-प्रोसेसिंग, आप के लिए नई-पंक्तियों बच सकते हैं xargs। ध्यान दें कि यह एक नहीं है while read, यह है while IFS= read -r
स्टीफन चेज़लस

@ क्रिस, मैंने वास्तविक सवाल का जवाब जोड़ दिया है क्योंकि जवाब समाप्त होने के बाद स्वीकार किया जा रहा है।
स्टीफन चेज़लस 12

91

ऐसा लगता है कि यदि आप फ़ाइल खोलना चाहते हैं तो आप एक नो-ऑप करना चाहते हैं, इसलिए आपको एक जोड़ना चाहिए :, जो एक शून्य कमांड है bash:

if lsof "$filename" > /dev/null; then
  # file is open
  :
else
  printf 'deleting %s\n' "$filename"
  rm -- "$filename"
fi

यदि आप उपयोग नहीं करते हैं :, bashतो आप कोड को पार्स नहीं कर सकते हैं, और जैसे त्रुटि दिखाएंगे bash: syntax error near unexpected token 'else'


कभी भी नया नहीं है :और यह बैश-बिल्डिंस में सूचीबद्ध पहला कमांड है।
14

26

एक अन्य विकल्प: अपने तर्क को उल्टा करें।

if ! lsof "$filename" >/dev/null;then
    echo "deleting $filename"
    rm "$filename"
fi

17

टी एल; डॉ

कोई अन्य उत्तर वास्तव में आपके मूल प्रश्न को संबोधित नहीं करता है कि कमांड एक सिंटैक्स त्रुटि क्यों देता है। इस बीच एक लापता आदेश के कारण होता है तो और किसी और

एक मिसिंग कमांड

आपका मूल कोड इस तरह दिखता है:

if lsof "$filename" > /dev/null
then
  # file is open
else
  echo "deleting $filename"
  rm "$filename"
fi

समस्या यह है कि आपके पास तब और किसी के बीच एक टिप्पणी है , लेकिन टिप्पणी को एक आदेश के रूप में नहीं माना जाता है। संक्षेप में, आप अपनी समस्या (संरचनात्मक रूप से बोलना) को इस प्रकार से लिख सकते हैं:

$ if true; then else echo; fi
bash: syntax error near unexpected token `else'

बॉर्न बिलिन के साथ अपने सिंटैक्स को ठीक करें

इससे पहले कि वास्तविक आदेशों रखकर इस समस्या को ठीक कर सकते हैं और कुछ है, लेकिन अपने आप में एक टिप्पणी नहीं करेंगे। अगर-तब अनुभाग खाली नहीं हो सकता; यदि आप एक प्लेसहोल्डर चाहते हैं, तो आप कोलन बिलिन का उपयोग कर सकते हैं । उदाहरण के लिए:

$ if true; then :; else echo; fi

बस तब के: बीच अनुभाग में रखने और अन्यथा आप अनुभव कर रहे वाक्यविन्यास त्रुटि को ठीक कर देंगे।


1
Gnouc का उत्तर, जो सबसे अधिक उत्कीर्ण है, पहले से ही मूल प्रश्न को स्वीकार कर रहा है।
जॉलीग्रे

सिंटैक्स त्रुटि को संबोधित करने के लिए केवल उत्तर। एफडब्ल्यूआईडब्ल्यू, आप एक पंक्ति की शुरुआत में एकमात्र अर्ध-बृहदान्त्र के साथ एक समान त्रुटि को पुन: उत्पन्न कर सकते हैं। यह एक मजबूत संकेत देगा। $ ; -bash: syntax error near unexpected token ';'
मैथ्यू हैनिगन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.