क्या सिंटेक्स समान नहीं है?


22

स्क्रिप्टिंग करते समय, मैं आमतौर पर अपने सिंटैक्स को निम्नलिखित सिंटैक्स के साथ लिखता हूं क्योंकि मेरे लिए यह समझना आसान है कि आगे जो आता है वह सच नहीं है।

if [ ! "$1" = "$2" ]; then

दूसरों का कहना है कि नीचे का रास्ता बेहतर है

if [ "$1" != "$2" ]; then

बात यह है कि जब मैं पूछता हूं कि कोई मतभेद क्यों है और क्या है तो किसी के पास कोई जवाब नहीं है।

तो, क्या दोनों सिंटैक्स के बीच कोई अंतर है? क्या उनमें से एक दूसरे की तुलना में अधिक सुरक्षित है? या यह सिर्फ वरीयता / आदत की बात है?


9
पहले मामले में आप ऑपरेटरों भेद करने के लिए प्राथमिकता जानने की जरूरत !(x==y)से (!x)==y
जिमीज

@ जिमीज का मतलब यह है कि जब एक तार की तुलना करते हैं if [ ! "$string" = "one" ]तो यह अनुवाद करता है कि क्या $stringबराबरी का मूल्य नहीं है one। और यह if [ "$string" != "one"]अनुवाद करता है कि क्या इसका मूल्य $stringनहीं के बराबर है one?
जिम्मी_ए

5
@Jimmy_A मेरा मतलब है कि आपको यह जानना होगा कि यह "अनुवाद" कैसे है। साथ में ऑपरेटरों को इकट्ठा करना ( !=वाक्य रचना) अधिक स्पष्ट है।
जिमीज

प्रिय करीबी मतदाताओं, स्टीफन के जवाब से पता चलता है कि व्यवहार में एक भौतिक अंतर है, सही जवाब किसी भी तरह से राय-आधारित नहीं है।
केविन

जवाबों:


35

कॉस्मेटिक / वरीयता के तर्कों के अलावा, एक कारण यह भी हो सकता है कि अधिक क्रियान्वयन ऐसे हों जहां [ ! "$a" = "$b" ]कोने के मामलों में असफलता हो [ "$a" != "$b" ]

यदि कार्यान्वयन POSIX एल्गोरिथ्म का पालन करते हैं , तो दोनों मामले सुरक्षित होने चाहिए , लेकिन आज भी (2018 की शुरुआत में लेखन के रूप में), अभी भी ऐसे कार्यान्वयन हैं जो विफल हो जाते हैं। उदाहरण के लिए, इसके साथ a='(' b=')':

$ (a='(' b=')'; busybox test "$a" != "$b"; echo "$?")
0
$ (a='(' b=')'; busybox test ! "$a" = "$b"; echo "$?")
1

dash0.5.9 से पहले के संस्करणों के साथ , shउदाहरण के लिए Ubuntu 16.04 पर 0.5.8 जैसा पाया गया :

$ a='(' b=')' dash -c '[ "$a" != "$b" ]; echo "$?"'
0
$ a='(' b=')' dash -c '[ ! "$a" = "$b" ]; echo "$?"'
1

(0.5.9 में तय किया गया, https://www.mail-archive.com/dash@vger.kernel.org/msg00911.html देखें )

उन कार्यान्वयन का इलाज [ ! "(" = ")" ]के रूप में [ ! "(" "text" ")" ]वह यह है कि [ ! "text" ](परीक्षण है कि क्या "पाठ" अशक्त स्ट्रिंग है) POSIX जनादेश इसे होने की जबकि [ ! "x" = "y" ](परीक्षण "x" और समानता के लिए "Y")। वे कार्यान्वयन विफल हो जाते हैं क्योंकि वे उस मामले में गलत परीक्षण करते हैं।

ध्यान दें कि अभी एक और रूप है:

! [ "$a" = "$b" ]

उस व्यक्ति को POSIX शेल की आवश्यकता होती है (पुराने बॉर्न शेल के साथ काम नहीं करेगा)।

ध्यान दें कि कई कार्यान्वयनों के साथ [ "$a" = "$b" ](और [ "$a" != "$b" ]) के साथ समस्याएं थीं और अभी भी सोलारिस 10 (एक बॉर्न शेल, पोसिक्स शेल के अंदर ) पर [बिल्टिन की तरह है । इसलिए आप चीजों को देखते हैं:/bin/sh/usr/xpg4/bin/sh

[ "x$a" != "x$b" ]

पुराने सिस्टम में पोर्टेबल होने की कोशिश करने वाली स्क्रिप्ट में।


तो दूसरे शब्दों में, दोनों वाक्यविन्यास समान हैं, चाहे कोई भी मतभेद क्यों न हो, लेकिन ! "$a" = "b"आपको यह बताने की आवश्यकता है कि तुलना को निर्दिष्ट करने के लिए आप इसे कैसे लिखते हैं। आपके उदाहरण से मैं समझता हूं कि दूसरा कमांड रिटर्न not zeroजो लाभकारी या परेशान करने वाला हो सकता है। यदि वे मेल नहीं खाते हैं, या बाहर निकलना चाहते हैं, तो यह फायदेमंद हो सकता है यदि आप यह देखना चाहते हैं कि क्या तुलना दुर्घटनाग्रस्त हो गई है
जिम्मी_ए

2
@Jimmy_A, नहीं, उन क्रियान्वयनों में [ ! "$a" = "$b" ]जब असफलता होती $aहै (और होती $bहै ), तो यह दावा करता है कि वे समान हैं जब वे नहीं होते हैं, तो वे (समान स्ट्रिंग नहीं होते हैं ), लेकिन [उस मामले में गलत परीक्षण करते हैं।
स्टीफन चेज़लस

आह, मुझे लगता है कि मैं समझ गया। पहले और तीसरे का मतलब यह है कि अगर हालत सही है, तो दूसरी और चौथी स्थिति की जाँच करें। इस प्रकार, बाहर निकलने की स्थिति कोड अलग है। इसका मूल रूप से कहना, 1 और 4 चर अलग-अलग हैं और 2 और 3 समान नहीं हैं।
जिम्मी_ए

3
@ जिम्मी_ए, नहीं। तुम पूरी तरह से चूक गए हो। यदि इन कार्यान्वयनों ने POSIX का अनुसरण किया, तो सभी स्थिति कोड 0.
वाइल्डकार्ड

यह सुनिश्चित करने के लिए कि मुझे समझ में आता है: [ ! "$a" = "$b" ]बुग्याल खोल कार्यान्वयन में कभी-कभी इसे गलत तरीके से नियंत्रित किया जाता है (जो मुझे लगता है कि उत्तर के पहले वाक्य को कम या ज्यादा बहाल करना है)।
माइकल बूर

8

x != yक्योंकि वाक्य रचना के लिए बेहतर है ! x == yत्रुटियों की संभावना है - जो अलग भाषा से भाषा को ऑपरेटरों पूर्वता के ज्ञान की आवश्यकता। वाक्य रचना ! x == yके रूप में व्याख्या की जा सकती !(x == y)है या (!x) == yकी प्राथमिकता के आधार पर, !बनाम =


उदाहरण के लिए, तुलनात्मक / रिलेशनल ऑपरेटर से पहलेc++ नकारात्मकता ! आती है == , इसलिए निम्न कोड:

#include<iostream>

using namespace std;

int main()
{
  int x=1, y=2;
  if(     x  != y   ) cout<<"true"<<endl; else cout<<"false"<<endl;
  if(  !  x  == y   ) cout<<"true"<<endl; else cout<<"false"<<endl;
  if(  !( x  == y ) ) cout<<"true"<<endl; else cout<<"false"<<endl;
  if(   (!x) == y   ) cout<<"true"<<endl; else cout<<"false"<<endl;
}

रिटर्न

true
false
true
false

इसी तरह के व्यवहार को कई अन्य भाषाओं में देखा जा सकता है, जैसे awk- यूनिक्स दुनिया में अक्सर इस्तेमाल किया जाने वाला उपकरण।


दूसरी ओर, एक साथ संचालकों को इकट्ठा करने से x != yएक अच्छी तरह से स्थापित पैटर्न के रूप में कोई भ्रम नहीं होता है। इसके अलावा, तकनीकी रूप से बोलना !=बहुत अक्सर दो नहीं है, लेकिन सिर्फ एक ऑपरेटर है, इसलिए अलग तुलना और फिर नकार की तुलना में मूल्यांकन करने के लिए थोड़ा तेज होना चाहिए। इसलिए, हालांकि दोनों वाक्यविन्यास बाश में काम करते हैं मैं पालन करने की सिफारिश करूंगा x != yक्योंकि यह कोड को पढ़ने और बनाए रखने में आसान है जो कुछ मानक तर्क का पालन करता है।


4

इस तरह की बात बहुत राय-आधारित है, क्योंकि "उत्तर" बहुत दृढ़ता से निर्भर करता है जिस तरह से किसी व्यक्ति का मस्तिष्क तार हो जाता है। हालांकि यह सच है कि शब्दार्थ, NOT ( A == B )समान है (A != B ), एक व्यक्ति के लिए स्पष्ट हो सकता है और दूसरे से दूसरे में। यह संदर्भ-निर्भर भी है। उदाहरण के लिए, यदि मेरे पास एक ध्वज सेट है, तो अर्थ एक वाक्य विन्यास के साथ दूसरे पर अधिक स्पष्ट हो सकता है:

if NOT ( fileHandleStatus == FS_OPEN )

विरोध के रूप में

if ( fileHandleStatus != FS_OPEN )

और यहां तक कि if ( FS_OPEN != fileHandleStatus )गलती से टाइपिंग में आसानी के परिणाम स्वरूप =के बजाय ==भाषाओं जहां पूर्व काम किया और बाद में समानता परीक्षण (सी) की तरह है में ...
derobert
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.