आपका कार्य क्यों नहीं हो रहा है
इसके कुछ कारण हैं:
- मुझे लगता
echoहै कि सिंटैक्स या तो परीक्षण के लिए उपयोग की जाने वाली एक कलाकृति है। यह कोई मतलब नहीं है अगर आप चाहते हैं कि फ़ंक्शन आपके द्वारा वर्णित है।
- अपरकेस
HEAD। लिनक्स में यह होना चाहिए head। मैं अन्य ओएस-एस जहां चला सकते हैं के बारे में यकीन नहीं है bashऔर head। HEADउनमें से कुछ में काम कर सकते हैं या नहीं, लेकिन headहर जगह काम करना चाहिए।
- पार्सिंग
lsकी सिफारिश नहीं की जाती है। इसके बारे में एक लेख है । आपके मामले में मुख्य बिंदु यह होगा कि lsविशेष या अनपेक्षित वर्णों सहित नामों को विश्वसनीय रूप से प्रिंट नहीं किया जा सकता है ।
- केवल निर्देशिकाओं का परीक्षण करने के लिए कोई तर्क नहीं है, हो सकता है
cdकि जब कोई निर्देशिका न हो तो आप किसी फ़ाइल के लिए प्रयास कर सकते हैं ।
- वर्तमान कार्य निर्देशिका खाली होने पर स्थिति को संभालने के लिए कोई तर्क नहीं है।
इन सभी मुद्दों को इस पार्सिंग lsबात को छोड़कर बहस की जा सकती है । यह एक डिजाइन दोष है। अगर आपको लगता है कि lsसीमाएं आपको नहीं काटेंगी तो आप इस दूसरे जवाब से समाधान के साथ जा सकते हैं ।
कुछ परीक्षण करने के लिए आप एक परेशान करने वाली निर्देशिका बना सकते हैं mkdir "$(echo -ne "foo\nbar")"; ls-जल्दी समाधान संभवत: विफल हो जाएगा अगर यह निर्देशिका को cdrcकरना चाहिए cd। परेशान निर्देशिका को हटाने के लिए rmdir "$(echo -ne "foo\nbar")"।
मैं एक सुरक्षित फ़ंक्शन बनाने में कामयाब रहा।
उपाय
function cdrc { cd "$(find -maxdepth 1 -mindepth 1 -type d -exec stat --printf "%Y %n\0" {} + | sort -znr | head -zn 1 | cut -f 2- -d " ")" ;}
व्याख्या
अपने कार्य को समझाने के लिए मैं इसे और स्पष्ट रूप से लिखूंगा। \एक पंक्ति के बहुत अंत में ध्यान दें bashकि कमांड अगली पंक्ति में जारी है; इसलिए नीचे दिए गए मेरे कोड को वन-लाइनर के रूप में माना जाता है, इसे पूरी तरह से इंटरैक्टिव के रूप में चिपकाया जा सकता है bash।
function cdrc { \
cd "$( \
find -maxdepth 1 -mindepth 1 -type d -exec \
stat --printf "%Y %n\0" {} + |
sort -znr |
head -zn 1 |
cut -f 2- -d " " \
)" \
;}
प्रक्रिया निम्नलिखित है:
- सबसे पहले
findचलाया जाता है। यह उपनिर्देशिका ( -maxdepth 1) में नहीं उतरता है , यह वर्तमान निर्देशिका या तो नहीं पाता है ( -mindepth 1)। यह केवल निर्देशिका पाता है ( -type d)। तब statकमांड चलाया जाता है (धन्यवाद -exec):
statअंतिम डेटा संशोधन का समय ( %Y, समय , सेकंड के बाद से युग), एकल स्थान और नाम ( %n)। --printfविकल्प के कारण यह न्यूलाइन वर्ण को नहीं जोड़ता है, लेकिन \0एक अशक्त चरित्र के रूप में व्याख्या करता है जिसे हर पंक्ति के अंत में जोड़ा जाना चाहिए।
{}find -execवाक्य रचना का एक हिस्सा है । findनिष्पादन के दौरान इसे निर्देशिका नाम से बदल दिया जाता है ताकि statपता चल सके कि इसका लक्ष्य क्या है।
+find -execसिंटैक्स का एक हिस्सा भी है । यह एकल के लिए कई नामों findको पारित करने का कारण बनता है (और इसे संभाल सकता है)। इस तरह कम प्रक्रियाएँ बनती हैं, यह तेज़ होता है।statstatstat
इस समय हमारे पास शून्य या अधिक रेखाएँ हैं। वे इस तरह दिखते हैं:
1493488341 directory name
1497365306 troublesome?directory name
लेकिन वे अशक्त हैं, इसलिए यहां तक कि अगर परेशान पात्रों के नाम हैं, तो उन्हें ठीक से संभाला जाएगा। पहले कॉलम में प्रमुख स्थानों के बिना mtimes हैं (मैंने statसुनिश्चित करने के लिए विभिन्न लंबाई की संख्याओं के साथ व्यवहार की जांच की ), फिर पहला स्थान निर्देशिका नाम से माइम को अलग करता है।
- इस आउटपुट को संसाधित किया जाता है:
sortसंख्यात्मक मान के अनुसार लाइनों को सॉर्ट करें ( -n), रिवर्स ऑर्डर ( -r) का उपयोग करता है और अशक्त-समाप्त स्ट्रिंग्स ( -z) के साथ काम करता है । इस तरह जिस निर्देशिका की हमें आवश्यकता है वह अब पहली पंक्ति में है।
- फिर
headकेवल पहली पंक्ति को छोड़ देता है ( -n 1); इसे अशक्त-समाप्त स्ट्रिंग्स ( -z) के साथ काम करना भी बताया जाता है ।
cutलाइन को काटता है, अंतरिक्ष को सीमांकक ( -d " ") के रूप में मानता है और दूसरे क्षेत्र को छोड़ता है और वह सब कुछ जो निम्नानुसार है ( -f 2-), यानी पहली जगह के बाद सब कुछ। यह अशक्त-समाप्त स्ट्रिंग्स ( -z) के साथ काम करता है । अंतिम आउटपुट वांछित निर्देशिका नाम है।
यदि वर्तमान कार्यशील निर्देशिका में कोई निर्देशिका नहीं है, तो आउटपुट रिक्त होगा।
$(…)अंदर है कि सब कुछ के उत्पादन से बदल दिया है। इस समय हम या तो cd "some directory name"या cd ""। पूर्व कमांड आप क्या चाहते हैं; बाद वाला (जब कोई निर्देशिका नहीं है) कुछ नहीं करता है।
यदि निर्देशिका को माना जाता है तो फ़ंक्शन विफल हो जाएगा cd(पुनः) findइसे ढूंढने के बाद स्थानांतरित / नाम बदला गया है। इसके अलावा statत्रुटि (रों) फेंक सकता है अगर किसी भी निर्देशिका (फिर से) ले जाया गया / नाम दिया जब समारोह काम करता है।