bash: मैं टूट गया [[<]]


14

मैं एक बैश स्क्रिप्ट लिख रहा था और अचानक यह व्यवहार शुरू हुआ:

[[ 1 < 2 ]]; echo $?  # outputs 0
[[ 2 < 13 ]]; echo $? # outputs 1

लेकिन -ltकाम करता है:

[[ 1 -lt 2 ]]; echo $?  # outputs 0
[[ 2 -lt 13 ]]; echo $? # outputs 0

क्या मैंने गलती से <किसी तरह अधिलेखित कर दिया था ?

यहाँ एक स्क्रिप्ट है जिसे मैंने इस व्यवहार का परीक्षण करने के लिए लिखा है:

#!/bin/bash

for a in {1..5}
do
    for b in {1..20}
    do
        [[ $a < $b ]] && echo $a $b
    done

    echo
done

यहाँ उत्पादन है:

1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20

2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 20

3 4
3 5
3 6
3 7
3 8
3 9

4 5
4 6
4 7
4 8
4 9

5 6
5 7
5 8
5 9

बदल रहा है <करने के लिए -ltस्क्रिप्ट में सामान्य उत्पादन (देता है 5 10, उदाहरण के लिए ऊपर से पता चलता है)।

रिबूट करने से कुछ भी नहीं बदला।

मेरा बैश संस्करण GNU बैश है, संस्करण 4.3.42 (1) -release (x86_64-pc-linux-gnu)। मैं उबंटू 15.10 पर हूं। मुझे नहीं पता कि अन्य जानकारी यहाँ क्या प्रासंगिक है।


16
<ऑपरेशन के साथ , आप एक स्ट्रिंग तुलना कर रहे हैं, जबकि -ltऑपरेटर संख्यात्मक तुलना है, यदि आप सूचीबद्ध किए गए परिणामों को देखते हैं, तो आपको इसका एहसास होगा। संख्यात्मक रूप से 2 10 से कम है, वर्णानुक्रम में, दूसरे तरीके से।
मेलबर्सलान

जवाबों:


51

से bashआदमी पेज।

जब [[, <और> ऑपरेटर्स के साथ प्रयोग किया जाता है तो लेक्सिकोग्राफ़िक रूप से वर्तमान लोकेल का उपयोग करते हैं।

आउटपुट से, यह डिज़ाइन के अनुसार काम करता प्रतीत होता है।


35
दूसरे शब्दों में, मान लेने से पहले मैन पेज पढ़ें कि आपको बग मिल गया है। ;)
वाइल्डकार्ड

सच। शायद मैं जिस स्क्रिप्ट पर काम कर रहा था, वह वास्तव में 'सही ढंग से' काम करना शुरू कर रही थी (जैसा कि [[$ myvar <13]] विफल रहा) जब मैंने इस व्यवहार पर ध्यान दिया। क्या अब मुझे इस सवाल पर कुछ करना चाहिए? क्या हम इस साइट पर शीर्षक को [हल] या कुछ और शामिल करने के लिए बदलते हैं? शीर्षक को कुछ और अधिक वर्णनात्मक करने के लिए वैसे भी बदला जाना चाहिए?
घोंघा-ऑन-ए-तलाश

2
नहीं, प्रश्न का शीर्षक नहीं बदलना चाहिए। इस उत्तर के आगे वाला चेक मार्क इंगित करने के लिए पर्याप्त है कि प्रश्न हल किया गया है।
सियारकोट May५

14
@Wildcard ओपी नहीं लगता है कि वे एक बग पाया। वे स्पष्ट रूप से सुझाव देते हैं कि शायद उन्होंने व्यवहार को बदलने के लिए कुछ किया है। यहाँ तक कि शीर्षक भी उतना ही मानता है!
jpmc26

5

कैसा रहेगा:

for a in {1..5}; 
do     
  for b in {1..20};     
  do         
    (( $a < $b )) && echo $a $b
  done      
  echo
done

Http://www.tldp.org/LDP/abs/html/dblparens.html के अनुसार

आज्ञा देने के समान, ((...) परमिट परमिट अंकगणितीय विस्तार और मूल्यांकन का निर्माण करता है। अपने सरलतम रूप में, एक = $ ((5 + 3) एक से 5 + 3 या 8 सेट करेगा। हालांकि, इस दोहरे-कोष्ठक निर्माण भी बैश में चर की सी-शैली हेरफेर की अनुमति देने के लिए एक तंत्र है, उदाहरण के लिए , (var ++))।


2
आप प्रश्न के बिंदु को याद कर रहे हैं - यह "मैं उन मूल्यों की तुलना कैसे कर सकता हूं?" लेकिन "यह ऐसा क्यों करता है?"
गुंटबर्ट

7
इसका उत्तर पहले ही दिया जा चुका था। लेकिन जैसा कि वह एक अंकगणितीय अभिव्यक्ति का उपयोग करना चाहता था, यह इंगित करने के लायक हो सकता है कि ऐसे निर्माण मौजूद हैं जो आपको शेल में उपयोग करने की अनुमति देते हैं।
पॉलस्मेकर

3

सबसे पहले, [[ POSIX नहीं है और इसे टाला जाना चाहिए।

दूसरे, यदि आप <एक अंकगणितीय परीक्षण के भाग के रूप में उपयोग करना चाहते हैं, तो आप ऐसा कर सकते हैं, लेकिन अलग-अलग वाक्य-विन्यास के साथ:

if [ $((2 < 13)) = 1 ]
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi

या:

if expr 2 '<' 13
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.