आपका कार्य क्यों नहीं हो रहा है
इसके कुछ कारण हैं:
- मुझे लगता
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
को पारित करने का कारण बनता है (और इसे संभाल सकता है)। इस तरह कम प्रक्रियाएँ बनती हैं, यह तेज़ होता है।stat
stat
stat
इस समय हमारे पास शून्य या अधिक रेखाएँ हैं। वे इस तरह दिखते हैं:
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
त्रुटि (रों) फेंक सकता है अगर किसी भी निर्देशिका (फिर से) ले जाया गया / नाम दिया जब समारोह काम करता है।