वास्तव में "/ बिन / [] कैसे काम करता है?


50

मुझे हमेशा आश्चर्य होता है कि फ़ोल्डर /binमें कोई [प्रोग्राम है।

यह क्या कहा जाता है जब हम की तरह कुछ कर रहे हैं: if [ something ]?

[प्रोग्राम को स्पष्ट रूप से एक शेल में कॉल करके, यह इसके लिए पूछता है ], और जब मैं क्लोजिंग ब्रैकेट प्रदान करता हूं, तो ऐसा लगता है कि मैं कोष्ठक के बीच जो भी सम्मिलित करता हूं, वह कुछ भी नहीं करता है।

कहने की जरूरत नहीं है, एक कार्यक्रम के बारे में मदद पाने का सामान्य तरीका काम नहीं करता है, न man [ही [ --helpकाम करता है।


11
@IporSircer [को संदर्भित करता है test, हालांकि आदेश, नहीं expr, तो यह होना चाहिएman test
सर्गी Kolodyazhnyy

8
man '['मेरे लिए ठीक काम करता है - या तो आप उद्धरण देना भूल गए [या आपके पास "काम" की एक अलग परिभाषा है।
टोबी स्पाइट

3
कुछ चेतावनियाँ: [इसके तर्कों का मूल्यांकन करती है, इसलिए आपको इन सभी के बीच रिक्त स्थान रखने की आवश्यकता है। [ a=b ]एक तुलना नहीं है: यह हमेशा सच होगा (यह एक एकल स्ट्रिंग है: "ए = बी", जो हमेशा सच का मूल्यांकन किया जाता है ) और आपको तर्क की संख्या 4 तक सीमित करनी चाहिए (भले ही हालिया कार्यान्वयन अधिक की अनुमति देगा .. 4 तक सीमित करने से यह अधिक पोर्टेबल हो जाता है। उदाहरण के लिए: [ "a" = "b" ]पहले से ही 4 तर्क हैं: "a" "=" "b" और परीक्षण arg का गैर-आवश्यक अंत: "]")। यदि आपको और अधिक की आवश्यकता है: उदाहरण के लिए श्रृंखला परीक्षण:if [ "$Var_a" = "foo" ] && [ "$Var_b" = "bar" ] ; then : do something ; fi
ओलिवियर दुलैक

1
@OlivierDulac !अपने आप से (unescaped और unquoted) प्रतिस्थापित नहीं किया जाएगा, और इससे भी बेहतर होगा if ! [ ...। सभी बैश विस्तार जो उपयोग करते !हैं उनमें कम से कम अन्य चरित्र शामिल हैं
मुरु

3
आपको यह भी ध्यान देना चाहिए कि (और संभवतः अन्य गोले के रूप में अच्छी तरह से) [में एक -बिल्टिन भी है bash, और इसका उपयोग इसके बजाय किया जा सकता है /bin/[। इसके अलावा वहाँ test-and, जो कई प्रणालियों पर एक प्रतीकात्मक लिंक है /bin/[(या इसके विपरीत) - लेकिन दूसरों पर एक अलग आदेश है।
बारोप कोपरुड

जवाबों:


63

[आदेश की नौकरी परीक्षण भाव मूल्यांकन करना है। यह 0 एग्जिट स्टेटस (जिसका अर्थ सत्य है ) के साथ लौटता है जब अभिव्यक्ति सही और कुछ और (जिसका अर्थ होता है झूठ ) से सुलझती है।

ऐसा नहीं है कि यह कुछ नहीं करता है, यह सिर्फ इतना है कि इसका परिणाम इसकी निकास स्थिति में पाया जाना है। एक शेल में, आप $?बॉर्न जैसे गोले के लिए या $statusअधिकांश अन्य गोले (मछली / आरसी / एससी / एससीएस / टीसीएच ...) के लिए अंतिम कमांड के बाहर निकलने की स्थिति के बारे में पता लगा सकते हैं ।

$ [ a = a ]
$ echo "$?"
0
$ [ a = b ]
$ echo "$?"
1

अन्य भाषाओं में perl, जैसे बाहर निकलने की स्थिति उदाहरण के लिए वापसी मूल्य में दी गई है system():

$ perl -le 'print system("[", "a", "=", "a", "]")'
0

ध्यान दें कि सभी आधुनिक बॉर्न जैसे गोले (और fish) में एक अंतर्निहित [कमांड होती है। में एक /binआम तौर पर केवल निष्पादित किया जाएगा जब आप एक अन्य सुरक्षा का उपयोग करें या आप की तरह बातें करते हैं जब env [ foo = bar ]या find . -exec [ -f {} ] \; -printया कि perlउपरोक्त आदेश ...

[आदेश भी से जाना जाता है testनाम। जब इसे बुलाया जाता है test, तो इसे एक समापन ]तर्क की आवश्यकता नहीं होती है ।

हालांकि आपके सिस्टम के लिए एक आदमी पृष्ठ नहीं हो सकता है [, लेकिन संभवतः इसके लिए एक है test। लेकिन फिर, ध्यान दें कि यह दस्तावेज /bin/[या /bin/testकार्यान्वयन होगा। [आपके शेल में बिलिन के बारे में जानने के लिए , आपको इसके बजाय अपने शेल के लिए दस्तावेज़ पढ़ना चाहिए।

उस उपयोगिता के इतिहास और [[...]]ksh परीक्षण की अभिव्यक्ति के साथ अंतर के बारे में अधिक जानकारी के लिए , आप यहाँ इस अन्य प्रश्नोत्तर पर एक नज़र रखना चाहते हैं


अच्छा है, हमेशा की तरह। आप उन टिप्पणियों में जोड़ना चाह सकते हैं जो मैंने @Bregalad प्रश्न के नीचे जोड़ी थीं? या शायद कुछ अतिरिक्त? इस तरह से उत्तर "पूरी तरह से कैसे काम करता है" पर और भी अधिक पूरा हो जाएगा (मैं ध्यान देता हूं कि आपने पहले से ही "] के बारे में अधिक तीखी जानकारी दी थी" ^ ^ की तुलना में)
ओलिवियर दुलक

"सभी बॉर्न-जैसे गोले (और मछली) में एक अंतर्निहित [कमांड" है जो 21 वीं शताब्दी में व्यवहार में सच है, लेकिन मुझे पूरा यकीन है कि मैंने बिना शेल का उपयोग किया है [। मुझे याद नहीं है कि यह एक बॉर्न संस्करण या राख का एक प्राचीन संस्करण था।
गिल्स एसओ- बुराई को रोकना '

@ गिल्स बोर्न शेल ने यूनिक्स सिस्टम III के साथ [और दोनों बिल्डरों को लागू किया test। इससे पहले, कोई भी नहीं था [और testकेवल एक बाहरी बाइनरी कमांड था।
जुल्गीरे

@ गिल्स, मूल राख में टेस्ट बिल्डिन (एक्सपीआर के साथ विलय) था, लेकिन वैकल्पिक रूप सेIn-ulm.de/~mascheck/various/ash के अनुसार , BSDs के पास लगभग 2000 तक टेस्ट बिल्ड नहीं था। मैंने "आधुनिक" जोड़ा है।
स्टीफन चेज़लस

दुनिया में आप क्यों करना चाहेंगे find . -exec [ f {} ] \; -print? कमांड find . -type f -printएक ही काम इतनी अधिक कुशलता से करेगा ...
यह मेरा असली नाम नहीं है

41

मुझे हमेशा आश्चर्य होता है कि फ़ोल्डर /binमें कोई [प्रोग्राम है।

आप हैरान होने के लिए सही हैं। यह एक दुर्लभ पोसिक्स कमांड में से एक है, जिसमें नल उपयोगिता ( :) है, जो कि कमांड फाइल की अनुमति नहीं देता है वर्णों के कन्वेंशन (पोर्टेबल फ़ाइल नाम वर्ण सेट) की अनुमति देता है।

है क्या कहा जाता है जब हम की तरह कुछ कर रहे हैं: if [ something ]?

ठीक है, लेकिन यह ifभी बिना इस्तेमाल किया जा सकता है।

[प्रोग्राम को स्पष्ट रूप से एक शेल में कॉल करके, यह इसके लिए पूछता है ], और जब मैं क्लोजिंग ब्रैकेट प्रदान करता हूं, तो ऐसा लगता है कि मैं कोष्ठक के बीच जो भी सम्मिलित करता हूं, वह कुछ भी नहीं करता है।

यह कुछ भी दिखाई नहीं देता है, लेकिन यह वास्तव में बहुत ही काम करता है जब इसके साथ प्रयोग किया जाता है if, यानी यह बाहर निकलने की स्थिति को 0 (सही) या कुछ और (गलत) के आधार पर सेट करता है जो आप कोष्ठक के अंदर डालते हैं। यह (एक कारण के लिए) testकमांड के समान व्यवहार है ; एकमात्र अंतर यह है कि यह अंत के लिए दिखता है ]man testविवरण के लिए देखें।

कहने की जरूरत नहीं है, एक कार्यक्रम के बारे में मदद पाने का सामान्य तरीका काम नहीं करता है, न man [ही [ --helpकाम करता है।

जो आपके ऑपरेटिंग सिस्टम पर निर्भर करता है। man [निश्चित रूप से मुख्यधारा गन्नू / लिनक्स वितरण के एक जोड़े पर मेरे लिए काम करता है, लेकिन यह सोलारिस पर नहीं है।

[ --helpकार्यान्वयन के आधार पर काम कर सकता है या नहीं, क्योंकि यह सिंटैक्स को तोड़ रहा है, समाप्त होने को याद नहीं कर रहा है ]। इसके अलावा, के लिए POSIX मानक test/ [आदेश स्पष्ट सहित सभी विकल्प, बाहर नियम --विकल्प समाप्ति इसलिए दोनों [ --help ]और test --helpवापस जाने के लिए की जरूरत है trueऔर डिजाइन द्वारा चुप रहने की। ध्यान दें कि क्या आप कोष्ठक के अंदर या के बाद डाल [कि (जैसे विकल्पों की तरह लग रही है और -f file, -n string, और पसंद) नहीं हैं विकल्प लेकिन ऑपरेंड

सभी आधुनिक बॉर्न शैली खोल दुभाषिए (जैसे bash, ksh, dashऔर zshकुछ नाम हैं) को लागू test/ [उपयोगिता आंतरिक रूप अंतर्निहित इसलिए जब आप उन्हें इस्तेमाल, सही मार्गदर्शन पेज उल्लेख करने के लिए खोल में से एक, नहीं हो सकता है के लिए testएक।

यूनिक्स सिस्टम III (1981) से पहले, बॉर्न शेल ने testउपयोगिता को बेसिन के रूप में लागू नहीं किया था, इसलिए केवल बाहरी बाइनरी कमांड कार्यान्वयन उपलब्ध था। [यूनिक्स सिस्टम III तक कोई कमांड (आंतरिक या बिलिन) तब तक नहीं था, उदाहरण के लिए यूनिक्स संस्करण 7 के तहत आपको टाइप करना था:

if test something ; then

के बजाय:

if [ something ] ; then

"आदमी [निश्चित रूप से मुख्यधारा गन्नू / लिनक्स वितरण पर मेरे लिए काम करता है" हम्म .. सेंटोस (माना जाता है कि अभी भी 6.8) स्पष्ट रूप से पर्याप्त मुख्यधारा नहीं है :) man testकाम करता है, लेकिन man [ दूसरी तरफ मेरे साइबर पर्यावरण के बारे में नहीं जानता है man [!
एडम

1
@ अदम हां, आप सही हैं, मैंने जितना सोचा था उससे अधिक हाल का है, हालांकि मैंने सभी मुख्यधारा लिनक्स डिस्ट्रोस को नहीं लिखा है , बस यह मेरे लिए काम किया है (यानी जिन लोगों पर मैंने परीक्षण किया था)। वह है ओएल 7.2 (आरएचईएल 7.2) क्लोन और मिंट 17.1 (उबंटू 14.04)।
जल्लियरे

man [Manjaro (आर्क लिनक्स आधारित) पर काम नहीं कर रहा है। एक वैध आह्वान के रूप में testसूचियों के लिए मैनुअल [ --helpजिसे मदद दिखानी चाहिए, लेकिन दिलचस्प रूप से यह नहीं है, और इसके बजाय एक लापता के बारे में शिकायत करता है ], उसी के साथ --version। जोड़ने से ]कुछ नहीं होता है, इसलिए इसके अलावा अन्य सहायता प्राप्त करना असंभव लगता है man test
डार्कहॉग 22

@ डारखॉग आप /usr/bin/[ --helpया कोशिश कर सकते हैं /bin/[ --help
जुल्गीरे

1
@jlliagre आप पूरी तरह से सही हैं, मैं बिलिन का उपयोग कर रहा था। env [ --helpके रूप में अच्छी तरह से /usr/bin/[ --helpपूरी तरह से ठीक काम (हालांकि मैं बोली /usr/bin/[या zsh शिकायत की जरूरत है )।
डार्कहॉग

10

[वास्तव में अधिक सामान्यतः testकमांड के रूप में जाना जाता है । इस कमांड का विशिष्ट उपयोग केवल भावों का मूल्यांकन करने और उनकी स्थिति को वापस करने के लिए है - सही या गलत। यह अक्सर if-then-else-fiबयानों में उपयोग किया जाता है , हालांकि इसे ifकथनों &&या ||ऑपरेटरों के माध्यम से सशर्त रूप से अन्य कमांड चलाने के लिए बयानों के बाहर इस्तेमाल किया जा सकता है , जैसे।

$ [ -e /etc/passwd  ] && echo "File exists"
File exists

$ test -e /etc/passwd && echo "File exists"
File exists

अधिक विशेष रूप से, मूल्यांकन को बाहर निकलने की स्थिति के माध्यम से अन्य आदेशों के लिए सूचित किया जाता है। कुछ कार्यक्रम विभिन्न प्रकार की घटनाओं को इंगित करने के लिए आउटपुट एक्जिट स्थिति का चयन कर सकते हैं - कार्यक्रम सफलतापूर्वक पूरा करना, निष्पादन के दौरान होने वाली विशेष प्रकार की त्रुटि या वाक्यविन्यास त्रुटियां। testआदेश के मामले में , 0सत्य के संकेत हैं, और 1झूठे का प्रतीक है। जैसा कि स्टीफ़न ने कहा, वाक्यविन्यास त्रुटियों से बाहर निकलने की स्थिति उत्पन्न होती है 2

इसका स्थान आपके सिस्टम पर निर्भर करता है, और यह भी बताता है कि आपने मैन पेज क्यों नहीं देखा जब आपने किया था man [। उदाहरण के लिए, FreeBSD पर यह जारी है /bin। लिनक्स पर (या मेरे विशेष मामले में, Ubuntu 16.04) यह अंदर है /usr/bin/। यदि आप लिनक्स सिस्टम पर करते हैं man [या करते हैं man test, तो आपको वही दस्तावेज खुले दिखाई देंगे। यह भी ध्यान रखना महत्वपूर्ण है कि आपके शेल का अपना कार्यान्वयन हो सकता है test

यह भी ध्यान दिया जाना चाहिए कि इस कमांड में मुद्दे हैं , जिसे कोर्न शेल के कार्यान्वयन (आमतौर पर डबल वर्ग कोष्ठक के साथ "सशर्त अभिव्यक्ति" संदर्भ के रूप में जाना जाता है [[ "$USER" = "root" ]]) हल करने के लिए चाहते हैं। यह सुविधा भी इस तरह के रूप में अन्य के गोले द्वारा इस्तेमाल किया bashऔर zsh


/usr/bin/अमेज़न लिनक्स के लिए भी।
फ्रेंकलिन्सिजो

@ स्टीफनचैलेजस धन्यवाद। उत्तर तदनुसार संपादित किया गया
सर्जियो कोलोडियाज़नी

3

न तो man [है और न ही [ --helpकाम करता है

कुछ डिस्ट्रोस (उदाहरण के लिए उबंटू) पर, man [एक सिमलिंक का अनुसरण करता है test(1)। दूसरों पर (जैसे आर्क), यह मामला नहीं है। (लेकिन testमैन पेज दस्तावेज़ का उपयोग भी करता है [)


type -a [ आपको दिखाता है कि शेल शेल और निष्पादन योग्य दोनों हैं।

$ type -a [
[ is a shell builtin
[ is /usr/bin/[

बैश-बिलिन [ --helpकेवल एक त्रुटि संदेश प्रिंट करता है। (लेकिन चूंकि यह एक बिलिन है, आप help [बैश मैन पेज / डॉक्स पर उपयोग कर सकते हैं या देख सकते हैं )।

/usr/bin/[ --help पूर्ण सहायता आउटपुट (GNU Coreutils संस्करण के लिए) प्रिंट करता है, जो इसके साथ शुरू होता है:

$ /usr/bin/[ --help
Usage: test EXPRESSION
  or:  test
  or:  [ EXPRESSION ]
  or:  [ ]
  or:  [ OPTION
Exit with the status determined by EXPRESSION.

      --help     display this help and exit
      --version  output version information and exit

और फिर वर्णन के लिए अनुमत सिंटैक्स का वर्णन करता है।

यह एक और तरीका है कि आप कि बाहर मिल सकता है [और testबराबर हैं।


BTW, यदि आप बैश के लिए प्रोग्रामिंग कर रहे हैं (या अंतःक्रियात्मक रूप से एक लाइनर लिख रहे हैं), मैं [[इसके बजाय की सिफारिश करेंगे [। यह कई मायनों में बेहतर है, सर्ग के जवाब में लिंक देखें।


2

[यदि कमांड को एग्जिट-स्टेटस जीरो रिटर्न मिलता है, तो उसके तर्कों में निहित अभिव्यक्ति को सही और गैर-शून्य एग्जिट-स्टेटस माना जाता है, यदि एक्सप्रेशन को उसके तर्कों में निहित माना जाता है, तो उसे गलत माना जाता है। यह त्रुटि संदेश के साथ भी विफल हो जाता है यदि इसका अंतिम तर्क नहीं है ](यह विशुद्ध रूप से सौंदर्य कारणों से किया जाता है)।

उदाहरण के लिए:

[ hello ]
echo "Exit-status of [ hello ] is:" $?
[ abc = abc ]
echo "Exit-status of [ abc = abc ] is:" $?
[ ]
echo "Exit-status of [ ] is:" $?
[ abc = def ]
echo "Exit-status of [ abc = def ] is:" $?

... उत्पादन होगा:

[हेल्लो] की एक्जिट-स्थिति: 0       - क्योंकि गैर-रिक्त स्ट्रिंग को सही माना जाता है 
[एबीसी = एबीसी] की एग्जिट-स्थिति: 0   - क्योंकि 'एबीसी' वास्तव में 'एबीसी' की ' 
एग्जिट-स्टेटस ' के समान है। : 1             - क्योंकि खाली स्ट्रिंग को गलत माना जाता है 
, [abc = def] की Exit-status है: 1   - क्योंकि 'abc' वास्तव में 'def' से भिन्न होती है

हालांकि, बैश और कई अन्य गोले वास्तव में इन मामलों में आम तौर पर आह्वान /bin/[(या /usr/bin/[) नहीं करते हैं , लेकिन बिल्ट-इन कमांड को इसके बजाय बिल्कुल उसी व्यवहार के साथ कहते हैं (प्रदर्शन कारणों से पूरी तरह से)। आह्वान करने के लिए /bin/[(शेल निर्मित बिल्ट-इन सरोगेट नहीं) आपको या तो इसके पथ को स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है (उदाहरण के लिए /bin/[ hello ]; आपको ]dirname के साथ उपसर्ग करने की आवश्यकता नहीं है , हालांकि ,), या शेल को अंतर्निर्मित सरोगेट का उपयोग न करने के लिए कॉन्फ़िगर करने के लिए (उदाहरण के लिए) enable -n [बाश में)।

पुनश्च: जैसा कि अन्य उत्तरों में कहा गया था, [से संबंधित है test। लेकिन test, इसके विपरीत [, ]इसके अंतिम तर्क के रूप में आवश्यकता नहीं है (और यह बिल्कुल भी उम्मीद नहीं करता है, तर्कों के ]लिए अतिरिक्त जोड़ने से testयह त्रुटि संदेश के साथ विफल हो सकता है या गलत परिणाम वापस कर सकता है)और एक ही फाइल को हल कर सकते हैं (उदाहरण के लिए एक है सांकेतिक रूप से लिंक , इस मामले में व्यवहार मोड़ शायद द्वारा कार्यान्वित किया जाता वर्तमान में कथित आदेश का विश्लेषण करने के भीतर / ही कोड) या अलग फ़ाइलों के लिए। के लिए , खोल भी आम तौर पर invokes बनाया-में किराए की, जब तक पथ स्पष्ट रूप से निर्दिष्ट किया जाता है ( ) या इसे कॉन्फ़िगर किया गया है ऐसा करने के लिए नहीं (/bin/test/bin/[test[test/bin/testenable -n test)।

PPS: इसके विपरीत testऔर [, आधुनिक ifकभी एक वास्तविक फ़ाइल नहीं है। यह शेल (उदा। बैश) सिंटैक्स का हिस्सा है: if commandA; then commandB; fi(सेमीकॉलन के बजाय नईलाइनों का उपयोग किया जा सकता है) commandBयदि और-और-केवल- commandAशून्य स्थिति के साथ बाहर निकलने पर निष्पादित होने का कारण बनता है । यह पूरी तरह से व्यवहार पर फिट बैठता है , testया [उन्हें जैसे if [ "$a" = foo ]; then …; fi (या if test "$a" = foo; then …; fi- बस कम पठनीय) को संयोजित करने की अनुमति देता है । हालांकि, आधुनिक स्क्रिप्ट अक्सर या के [[बजाय का उपयोग करते हैं , जो (के रूप में ) कभी भी एक वास्तविक फ़ाइल नहीं होती है, लेकिन हमेशा शेल सिंटैक्स का एक हिस्सा होता है।test[if

PPPS: जैसा कि man- manआपके फ़ाइल-सिस्टम में हर कमांड पर एक लेख होने की कभी उम्मीद नहीं की जाती है। कुछ (यहां तक कि 'असली', फ़ाइल-आधारित) आदेशों पर जानकारी, गायब हो सकता है कुछ खोल बनाया-इन शायद वर्तमान न केवल विशिष्ट खोल करने के लिए समर्पित एक लेख के भीतर (जो जगह है जहाँ आप सबसे निश्चित रूप से के बारे में जानकारी मिल जाएगा है पर जानकारी test, [, if, [[)। फिर भी, कई वितरणों के लिए स्पष्ट- manसार हैं testऔर [। (के बारे में --help, यह testस्पष्ट कारण के साथ मान्यता प्राप्त नहीं है : इसे चुपचाप मामलों को संभालने की आवश्यकता है a=--help; test "$a", जैसे कुछ वितरण पर [ --help(बंद किए बिना ]) अभी भी मदद दिखाता है, कुछ पर यह नहीं करता है।)


3
ध्यान दें कि ifयूनिक्स V6 तक का कमांड था। यूनिक्स V7 (1979) बॉर्न शेल (इसके if-then-else-fiनिर्माण के साथ ) और नई testकमांड के साथ आया था ।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.