इको कमांड के लिए निष्पादन का पता लगाएं?


29

मैं जेनकिंस से शेल स्क्रिप्ट्स चला रहा हूं, जो शेल स्क्रिप्ट्स को शेबंग ऑप्शंस से हटाता है #!/bin/sh -ex

डमी के लिए बैश शेबंग के अनुसार ? , -x"शेल एक निष्पादन ट्रेस को प्रिंट करने का कारण बनता है", जो अधिकांश उद्देश्यों के लिए महान है - इकोस को छोड़कर:

echo "Message"

उत्पादन करता है

+ echo "Message"
Message

जो थोड़ा बेमानी है, और थोड़ा अजीब लगता है। क्या -xसक्षम छोड़ने का एक तरीका है , लेकिन केवल आउटपुट

Message

ऊपर की दो पंक्तियों के बजाय, जैसे कि एक विशेष कमांड कैरेक्टर के साथ इको कमांड को प्रीफ़िक्स करके, या आउटपुट को रीडायरेक्ट करना?

जवाबों:


20

जब आप एलिगेटर में अपनी गर्दन तक होते हैं, तो यह भूलना आसान है कि लक्ष्य दलदल को खत्म करना था।                   - लोकप्रिय कहावत

सवाल के बारे में है echo, और अभी तक जवाब के बहुमत पर ध्यान केंद्रित करने के लिए कैसे एक set +xआदेश में चुपके है । वहाँ एक बहुत सरल, अधिक प्रत्यक्ष समाधान है:

{ echo "Message"; } 2> /dev/null

(मैं स्वीकार करता हूं कि { …; } 2> /dev/null अगर मैंने इसे पहले के उत्तर में नहीं देखा था , तो शायद मैंने सोचा भी नहीं होगा।)

यह कुछ हद तक बोझिल है, लेकिन, अगर आपके पास लगातार echoकमांड का एक ब्लॉक है, तो आपको इसे हर एक पर व्यक्तिगत रूप से करने की आवश्यकता नहीं है:

{
  echo "The quick brown fox"
  echo "jumps over the lazy dog."
} 2> /dev/null

ध्यान दें कि जब आपको नई सुर्खियाँ चाहिए तो आपको अर्धविराम की आवश्यकता नहीं है।

आप गैर-मानक फ़ाइल डिस्क्रिप्टर (जैसे, 3) पर स्थायी रूप से खोलने के kenorb के विचार का उपयोग करके /dev/nullऔर फिर हर समय के 2>&3बजाय कहकर टाइपिंग का बोझ कम कर सकते हैं 2> /dev/null


इस लेखन के समय में पहले चार जवाब कुछ खास कर की आवश्यकता होती है (और, ज्यादातर मामलों, बोझिल में) हर बार जब आप एक कर echo। यदि आप वास्तव में चाहते हैं कि सभी echo कमांड निष्पादन ट्रेस को दबा दें (और आप ऐसा क्यों नहीं करेंगे?), तो आप बहुत सारे कोड को हटाए बिना, विश्व स्तर पर ऐसा कर सकते हैं। सबसे पहले, मैंने देखा कि उपनामों का पता नहीं लगाया गया है:

$ myfunc()
> {
>     date
> }
$ alias myalias="date"
$ set -x
$ date
+ date
Mon, Oct 31, 2016  0:00:00 AM           # Happy Halloween!
$ myfunc
+ myfunc                                # Note that function call is traced.
+ date
Mon, Oct 31, 2016  0:00:01 AM
$ myalias
+ date                                  # Note that it doesn’t say  + myalias
Mon, Oct 31, 2016  0:00:02 AM

(ध्यान दें कि निम्न स्क्रिप्ट स्निपेट काम करता है यदि शेबंग है #!/bin/sh, भले ही /bin/shबैश करने के लिए एक लिंक है। लेकिन, यदि शेबंग है #!/bin/bash, तो आपको shopt -s expand_aliasesस्क्रिप्ट में काम करने के लिए उपनाम प्राप्त करने के लिए एक कमांड जोड़ने की आवश्यकता है ।)

तो, मेरी पहली चाल के लिए:

alias echo='{ set +x; } 2> /dev/null; builtin echo'

अब, जब हम कहते हैं echo "Message", हम उपनाम कह रहे हैं, जिसका पता नहीं चलता है। उपनाम ट्रेस विकल्प को बंद कर देता है, जबकि setकमांड से ट्रेस संदेश को दबा देता है (पहले उपयोगकर्ता 505071535 के उत्तर में तकनीक को प्रस्तुत करता है), और फिर वास्तविक echoकमांड निष्पादित करता है । इससे हमें प्रत्येक echo कमांड पर कोड को संपादित करने की आवश्यकता के बिना उपयोगकर्ता के 505071535 के उत्तर के समान प्रभाव मिलता है । हालाँकि, यह ट्रेस ट्रेस मोड बंद हो गया। हम set -xउपनाम (या कम से कम आसानी से नहीं) में नहीं डाल सकते क्योंकि एक उपनाम केवल एक स्ट्रिंग को एक शब्द के लिए प्रतिस्थापित करने की अनुमति देता है; अलियास स्ट्रिंग के किसी भी भाग को तर्कों (जैसे, ) के बाद कमांड में इंजेक्ट नहीं किया जा सकता है "Message"। इसलिए, उदाहरण के लिए, यदि स्क्रिप्ट में है

date
echo "The quick brown fox"
echo "jumps over the lazy dog."
date

आउटपुट होगा

+ date
Mon, Oct 31, 2016  0:00:03 AM
The quick brown fox
jumps over the lazy dog.
Mon, Oct 31, 2016  0:00:04 AM           # Note that it doesn’t say  + date

इसलिए आपको संदेश प्रदर्शित करने के बाद भी ट्रेस विकल्प को फिर से चालू करने की आवश्यकता है - लेकिन लगातार कमांड के प्रत्येक ब्लॉक के बाद केवल एक बार echo:

date
echo "The quick brown fox"
echo "jumps over the lazy dog."
set -x
date


यह अच्छा होगा यदि हम set -xएक के बाद स्वचालित बना सकते हैं echo- और हम थोड़ा अधिक प्रवंचना के साथ कर सकते हैं। लेकिन इससे पहले कि मैं इसे प्रस्तुत करूं, इस पर विचार करें। ओपी उन स्क्रिप्ट्स से शुरू कर रहा है जो एक #!/bin/sh -exशेबंग का उपयोग करती हैं । स्पष्ट रूप से उपयोगकर्ता xशेलबैंग से निकाल सकता है और एक स्क्रिप्ट है जो सामान्य रूप से काम करता है, निष्पादन अनुरेखण के बिना। यह अच्छा होगा यदि हम एक समाधान विकसित कर सकें जो उस संपत्ति को बरकरार रखे। यहां पहले कुछ उत्तर उस संपत्ति को विफल कर देते हैं क्योंकि वे echoबयानों के बाद "पीछे" ट्रेसिंग करते हैं, बिना शर्त, बिना इस बात के कि क्या यह पहले से ही था।  यह उत्तर स्पष्ट रूप से उस मुद्दे को पहचानने में विफल रहता है, क्योंकि यह प्रतिस्थापित करता है echoट्रेस आउटपुट के साथ आउटपुट; इसलिए, यदि ट्रेसिंग बंद हो जाती है तो सभी संदेश गायब हो जाते हैं। मैं अब एक समाधान पेश करूंगा जो एक echoबयान के बाद सशर्त रूप से पीछे मुड़ जाता है - केवल अगर यह पहले से ही था। इसे ऐसे समाधान में अपग्रेड करना जो बिना शर्त के "बैक" को ट्रेस करता है, तुच्छ है और इसे अभ्यास के रूप में छोड़ दिया जाता है।

alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
echo_and_restore() {
        builtin echo "$*"
        case "$save_flags" in
         (*x*)  set -x
        esac
}

$-विकल्प सूची है; सेट किए गए सभी विकल्पों के अनुरूप अक्षरों का एक संयोजन। उदाहरण के लिए, यदि विकल्प eऔर xविकल्प निर्धारित किए जाते हैं, तो $-उन अक्षरों का एक जोड़ होगा जो शामिल हैं eऔर x। मेरा नया उपनाम (ऊपर) $-ट्रेसिंग बंद करने से पहले का मूल्य बचाता है। फिर, ट्रेसिंग बंद होने के साथ, यह एक शेल फ़ंक्शन में नियंत्रण को फेंकता है। यह फ़ंक्शन वास्तविक करता है echo और फिर यह देखने के लिए जांचता है कि क्या xविकल्प चालू किया गया था जब उपनाम उतारा गया था। यदि विकल्प चालू था, तो फ़ंक्शन इसे वापस चालू करता है; यदि यह बंद था, तो फ़ंक्शन इसे बंद कर देता है।

आप shoptस्क्रिप्ट की शुरुआत में उपरोक्त सात लाइनें (आठ, यदि आप शामिल हैं ) सम्मिलित कर सकते हैं और बाकी को अकेले छोड़ सकते हैं।

यह आपको अनुमति देगा

  1. निम्नलिखित शेबंग लाइनों में से किसी का उपयोग करने के लिए:
    #! / बिन / श-ष
    #! / बिन / श-ई
    #! / बिन / श- x
    या सिर्फ सादा
    #! / Bin / श
    और यह उम्मीद के मुताबिक काम करना चाहिए।
  2. कोड की तरह है
    (shebang) 
    कमांड 1
     कमांड 2
     कमांड 3
    सेट -x
    कमांड 4
     कमांड 5
     कमांड 6
    सेट + एक्स
    कमांड 7
     कमांड 8
     कमांड 9
    तथा
    • कमांड 4, 5, और 6 का पता लगाया जाएगा - जब तक कि उनमें से कोई एक नहीं है echo, जिस स्थिति में इसे निष्पादित किया जाएगा, लेकिन पता नहीं लगाया जाएगा। (लेकिन भले ही कमांड 5 एक है echo, कमांड 6 अभी भी पता लगाया जाएगा।)
    • 7, 8, और 9 कमांड का पता नहीं लगाया जाएगा। भले ही कमांड 8 एक है echo, कमांड 9 अभी भी पता नहीं लगाया जाएगा।
    • कमांड 1, 2, और 3 का पता लगाया जाएगा (जैसे 4, 5 और 6) या नहीं (जैसे 7, 8, और 9) इस बात पर निर्भर करता है कि शेबंग शामिल है या नहीं x

PS मुझे पता चला है कि, मेरे सिस्टम पर, मैं builtinअपने मध्य उत्तर में कीवर्ड को छोड़ सकता हूं (वह जो केवल एक उपनाम है echo)। यह आश्चर्य की बात नहीं है; बाश (1) कहता है कि, उर्फ ​​विस्तार के दौरान,…

... एक शब्द जो उपनाम के समान है, दूसरी बार विस्तारित नहीं किया जाता है। इसका मतलब यह है कि उदाहरण के lsलिए ls -F, अन्य व्यक्ति उर्फ ​​हो सकता है , और बैश रिप्लेसमेंट टेक्स्ट को पुनरावृत्ति करने की कोशिश नहीं करता है।

बहुत आश्चर्य की बात नहीं, अंतिम उत्तर (जिसके साथ echo_and_restore) विफल रहता है यदि builtinकीवर्ड 1 छोड़ दिया गया है । लेकिन, अगर मैं हटाता हूं builtinऔर ऑर्डर को स्विच करता हूं तो यह अजीब तरह से काम करता है :

echo_and_restore() {
        echo "$*"
        case "$save_flags" in
         (*x*)  set -x
        esac
}
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'

__________
1  यह अपरिभाषित व्यवहार को जन्म देता है। मैंने देखा है

  • एक अनन्त लूप (शायद अनबिके पुनरावृत्ति के कारण),
  • एक /dev/null: Bad addressत्रुटि संदेश, और
  • एक कोर डंप।

2
मैंने एलियास के साथ कुछ अद्भुत जादू के गुर देखे हैं, इसलिए मुझे पता है कि मेरा ज्ञान अधूरा है। अगर कोई किसी echo +x; echo "$*"; echo -xअन्य के बराबर करने का तरीका पेश कर सकता है , तो मैं इसे देखना चाहूंगा।
जी-मैन का कहना है कि 'मोनिका'

11

मुझे InformIT पर एक आंशिक समाधान मिला :

#!/bin/bash -ex
set +x; 
echo "shell tracing is disabled here"; set -x;
echo "but is enabled here"

आउटपुट

set +x; 
shell tracing is disabled here 
+ echo "but is enabled here"
but is enabled here

दुर्भाग्य से, यह अभी भी गूँजती है set +x, लेकिन कम से कम इसके बाद शांत है। इसलिए यह समस्या का कम से कम एक आंशिक समाधान है।

लेकिन क्या ऐसा करने का एक बेहतर तरीका है? :)


2

इस तरह से set +xआउटपुट से छुटकारा पाने के अपने खुद के समाधान में सुधार होता है:

#!/bin/bash -ex
{ set +x; } 2>/dev/null
echo "shell tracing is disabled here"; set -x;
echo "but is enabled here"

2

set +xकोष्ठक के अंदर रखो , तो यह केवल स्थानीय दायरे के लिए लागू होगा।

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

#!/bin/bash -x
exec 3<> /dev/null
(echo foo1 $(set +x)) 2>&3
($(set +x) echo foo2) 2>&3
( set +x; echo foo3 ) 2>&3
true

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

$ ./foo.sh 
+ exec
foo1
foo2
foo3
+ true

अगर मैं गलत हूं तो मुझे सुधारें, लेकिन मुझे नहीं लगता कि set +xसब-इनशेल के अंदर (या सब-से-सब का उपयोग करके) कुछ भी उपयोगी है। आप इसे हटा सकते हैं और समान परिणाम प्राप्त कर सकते हैं। यह / / dev / null को पुनर्निर्देशित करने का स्टैडर है जो अस्थायी रूप से "ट्रेसिंग" को अक्षम करने का काम कर रहा है ... ऐसा लगता है echo foo1 2>/dev/null, आदि, बस उतना ही प्रभावी होगा, और अधिक पठनीय होगा।
टायलर रिक

आपकी स्क्रिप्ट में अनुरेखण होने से प्रदर्शन प्रभावित हो सकता है। जब आप कुछ अन्य त्रुटियों की अपेक्षा करते हैं, तो दूसरा और NULL को पुनर्निर्देशित करना समान नहीं हो सकता है।
केनोरब

अगर मैं गलत हूं तो मुझे सुधारें, लेकिन आपके उदाहरण में आपके पास पहले से ही आपकी स्क्रिप्ट में सक्षम (साथ bash -x) है और आप पहले से ही &2अशक्त करने के लिए पुनर्निर्देशित कर रहे हैं (चूंकि &3अशक्त करने के लिए पुनर्निर्देशित किया गया था), इसलिए मुझे यकीन नहीं है कि यह टिप्पणी कैसे प्रासंगिक है। हो सकता है कि हमें एक बेहतर उदाहरण की आवश्यकता है जो आपकी बात को स्पष्ट करता है, लेकिन दिए गए उदाहरण में, यह अभी भी ऐसा लगता है कि बिना किसी लाभ को खोए इसे सरल बनाया जा सकता है।
टायलर रिक

1

मुझे जी-मैन द्वारा व्यापक और अच्छी तरह से समझाया गया उत्तर पसंद है , और इसे अब तक का सबसे अच्छा माना जाता है। यह स्क्रिप्ट के संदर्भ के बारे में परवाह करता है, और जब वे आवश्यक नहीं हैं, तो कॉन्फ़िगरेशन को मजबूर नहीं करता है। इसलिए, यदि आप इस उत्तर को पढ़ रहे हैं तो पहले आगे बढ़ें और जाँचें कि एक, सारी योग्यता है।

हालांकि, उस जवाब में एक महत्वपूर्ण टुकड़ा गायब है: प्रस्तावित विधि एक विशिष्ट उपयोग के मामले में काम नहीं करेगी, अर्थात रिपोर्टिंग त्रुटियां:

COMMAND || echo "Command failed!"

अलियास का निर्माण कैसे किया जाता है, इस कारण इसका विस्तार होगा

COMMAND || { save_flags="$-"; set +x; } 2>/dev/null; echo_and_restore "Command failed!"

और आपने यह अनुमान लगाया, हमेशा बिना शर्त के, echo_and_restoreनिष्पादित किया जाता है । यह देखते हुए कि भाग नहीं चला, इसका मतलब है कि उस फ़ंक्शन की सामग्री मुद्रित हो जाएगी, भी।set +x

पिछले बदलने ;के लिए &&, क्योंकि या तो बैश में काम करेगा नहीं,, ||और &&कर रहे हैं बाएं साहचर्य

मुझे एक संशोधन मिला जो इस उपयोग के मामले में काम करता है:

echo_and_restore() {
    echo "$(cat -)"
    case "$save_flags" in
        (*x*) set -x
    esac
}
alias echo='({ save_flags="$-"; set +x; } 2>/dev/null; echo_and_restore) <<<'

यह एक subshell (का उपयोग करता है (...)सभी आदेशों समूह के क्रम में भाग), और उसके बाद के माध्यम से इनपुट स्ट्रिंग से गुजरता stdin एक के रूप में यहाँ स्ट्रिंग ( <<<बात) जो तब से छपा है cat --वैकल्पिक है, लेकिन आप जानते हैं, " स्पष्ट अंतर्निहित से बेहतर है ।"

आप cat -सीधे इको के बिना भी उपयोग कर सकते हैं , लेकिन मुझे यह पसंद है क्योंकि यह मुझे आउटपुट में किसी अन्य तार को जोड़ने की अनुमति देता है। उदाहरण के लिए, मैं इसका उपयोग इस तरह करता हूं:

BASENAME="$(basename "$0")"  # Complete file name
...
echo "[${BASENAME}] $(cat -)"

और अब यह खूबसूरती से काम करता है:

false || echo "Command failed"
> [test.sh] Command failed

0

निष्पादन का पता लगाने के लिए जाता है stderr, इसे इस तरह से फ़िल्टर करें:

./script.sh 2> >(grep -v "^+ echo " >&2)

कुछ स्पष्टीकरण, कदम से कदम:

  • stderr पुनर्निर्देशित है ... - 2>
  • ... एक आदेश के लिए। ->(…)
  • grep आदेश है ...
  • ... जो लाइन की शुरुआत की आवश्यकता है ... ^
  • … इसके बाद + echo
  • ... तो grepमैच का विरोध ...-v
  • ... और वह सभी लाइनों को छोड़ देता है जो आप नहीं चाहते हैं।
  • परिणाम आम तौर पर जाना होगा stdout; हम इसे उस स्थान पर पुनः निर्देशित करते हैं stderrजहां यह है। ->&2

समस्या है (मुझे लगता है) यह समाधान धाराओं को वंशानुक्रमित कर सकता है। फ़िल्टरिंग की वजह से stderrथोड़ी देर हो सकती है stdout(जहां echoआउटपुट डिफ़ॉल्ट रूप से होता है)। इसे ठीक करने के लिए आप पहले उन धाराओं में शामिल हो सकते हैं यदि आपको उन दोनों में बुरा न लगे stdout:

./script.sh > >(grep -v "^+ echo ") 2>&1

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

कोड इस तरह दिखता है:

#!/bin/bash -x

{
 # original script here
 # …
} 2> >(grep -v "^+ echo " >&2)

इसे बिना किसी चाल के चलाएं:

./script.sh

फिर से, > >(grep -v "^+ echo ") 2>&1स्ट्रीम में शामिल होने की लागत पर सिंक्रनाइज़ेशन बनाए रखने के लिए उपयोग करें।


एक और दृष्टिकोण। आपको "थोड़ा बेमानी" और अजीब दिखने वाला आउटपुट मिलता है क्योंकि आपका टर्मिनल मिक्स है stdoutऔरstderr । ये दोनों धाराएँ एक कारण से अलग-अलग जानवर हैं। जाँच करें कि क्या विश्लेषण stderrकेवल आपकी आवश्यकताओं के अनुरूप है; त्याग करें stdout:

./script.sh > /dev/null

यदि आपके पास अपनी स्क्रिप्ट में एक echoमुद्रण डिबग / त्रुटि संदेश है stderrतो आप ऊपर वर्णित तरीके से अतिरेक से छुटकारा पा सकते हैं। पूर्ण आदेश:

./script.sh > /dev/null 2> >(grep -v "^+ echo " >&2)

इस समय हम stderrकेवल साथ काम कर रहे हैं , इसलिए वंशानुक्रम में कोई चिंता नहीं है। दुर्भाग्यवश इस तरह से आपको (यदि कोई हो) echoउस प्रिंट का कोई निशान और आउटपुट दिखाई नहीं देगा stdout। हम पुनर्निर्देशन ( >&2) का पता लगाने के लिए हमारे फ़िल्टर को फिर से बनाने की कोशिश कर सकते हैं, लेकिन यदि आप देखते हैं echo foobar >&2, echo >&2 foobarऔर echo "foobar >&2"तब आप शायद सहमत होंगे कि चीजें जटिल हो जाती हैं।

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


निष्पादन के निशान को छोड़ने के बजाय echoहम इसके उत्पादन को छोड़ सकते हैं - और निशान को छोड़कर किसी भी आउटपुट को। केवल निष्पादन के निशान का विश्लेषण करने के लिए, प्रयास करें:

./script.sh > /dev/null 2> >(grep "^+ " >&2)

सरल? नहीं। अगर echo "+ rm -rf --no-preserve-root /" >&2स्क्रिप्ट में है तो क्या होगा । किसी को दिल का दौरा पड़ सकता है।


और अंत में…

सौभाग्य से BASH_XTRACEFDपर्यावरण चर है। से man bash:

BASH_XTRACEFD
यदि एक मान्य फ़ाइल डिस्क्रिप्टर के संगत पूर्णांक पर सेट किया गया है, तो बैश set -xउस फ़ाइल डिस्क्रिप्टर के लिए सक्षम होने पर उत्पन्न ट्रेस आउटपुट लिखेगा ।

हम इसे इस तरह से उपयोग कर सकते हैं:

(exec 3>trace.txt; BASH_XTRACEFD=3 ./script.sh)
less trace.txt

ध्यान दें कि पहली पंक्ति एक उपधारा को जन्म देती है। इस तरह फाइल डिस्क्रिप्टर वैध नहीं रहेगा और न ही मौजूदा शेल में बाद में वेरिएबल असाइन किया जाएगा।

आपके लिए धन्यवाद BASH_XTRACEFDइकोस और किसी भी अन्य आउटपुट से मुक्त निशान का विश्लेषण कर सकते हैं, जो कुछ भी वे हो सकते हैं। यह वही नहीं है जो आप चाहते थे, लेकिन मेरा विश्लेषण मुझे लगता है कि यह (सामान्य रूप से) सही तरीका है।

बेशक आप किसी अन्य विधि का उपयोग कर सकते हैं, खासकर जब आपको विश्लेषण करने की आवश्यकता होती है stdoutऔर / या stderrअपने निशान के साथ। आपको बस याद रखने की ज़रूरत है कि कुछ सीमाएँ और नुकसान हैं। मैंने उन्हें (कुछ) दिखाने की कोशिश की।


0

मेकफाइल में आप @प्रतीक का उपयोग कर सकते हैं ।

उदाहरण उपयोग: @echo 'message'

से इस जीएनयू डॉक:

जब कोई रेखा '@' से शुरू होती है, तो उस रेखा की गूंज दब जाती है। शेल में जाने से पहले '@' को छोड़ दिया जाता है। आमतौर पर आप इसे एक कमांड के लिए उपयोग करेंगे जिसका एकमात्र प्रभाव कुछ प्रिंट करना है, जैसे कि मेकओवर के माध्यम से प्रगति को इंगित करने के लिए एक इको कमांड।


नमस्ते, आप जिस संदर्भ का उल्लेख कर रहे हैं वह ग्नू मेक के लिए है, शेल के लिए नहीं। क्या आपको यकीन है कि यह काम करता है? मुझे त्रुटि मिलती है ./test.sh: line 1: @echo: command not found, लेकिन मैं बैश का उपयोग कर रहा हूं।

वाह, माफ करना, मैंने सवाल को पूरी तरह से गलत बताया। हां, @केवल तभी काम करता है जब आप मेकफाइल्स में गूंज रहे हों।
डेरेक

@ डेरेक ने आपके मूल उत्तर को संपादित किया ताकि अब यह स्पष्ट रूप से कहा जाए कि समाधान केवल मेकफाइल्स के लिए सीमित है। मैं वास्तव में इस एक की तलाश में था, इसलिए मैं चाहता था कि आपकी टिप्पणी नकारात्मक प्रतिष्ठा न हो। उम्मीद है, लोग इसे मददगार भी पाएंगे।
शकरॉन

-1

29 अक्टूबर 2016 को प्रति मॉडरेटर सुझावों को संपादित किया गया कि मूल में यह समझने के लिए पर्याप्त जानकारी नहीं थी कि क्या हो रहा है।

यह "ट्रिक" टर्मिनल पर संदेश आउटपुट की सिर्फ एक लाइन का उत्पादन करता है जब xtrace सक्रिय होता है:

मूल प्रश्न यह है कि क्या x -x को सक्षम करने का एक तरीका है, लेकिन केवल दो पंक्तियों के बजाय आउटपुट संदेश । यह प्रश्न से सटीक उद्धरण है।

मैं इस सवाल को समझता हूं कि "सेट -x को कैसे सक्षम किया जाए और संदेश के लिए एक ही लाइन का निर्माण कैसे किया जाए"?

  • वैश्विक अर्थों में, यह प्रश्न मूल रूप से सौंदर्यशास्त्र के बारे में है - प्रश्नकर्ता , वस्तुतः सक्रिय होने के दौरान उत्पादित दो वस्तुतः डुप्लिकेट लाइनों के बजाय एक पंक्ति का उत्पादन करना चाहता है।

इसलिए सारांश में, ओपी की आवश्यकता है:

  1. करवाने के लिए सेट -x प्रभाव में
  2. एक संदेश, मानव पठनीय का निर्माण करें
  3. संदेश आउटपुट की केवल एक पंक्ति का उत्पादन करें।

ओपी को इको कमांड का उपयोग करने की आवश्यकता नहीं है । उन्होंने इसे संदेश उत्पादन के एक उदाहरण के रूप में उद्धृत किया, उदाहरण के लिए जो लैटिन उदाहरण ग्रामिया, या "उदाहरण के लिए" का उपयोग करता है।

"बॉक्स के बाहर" सोचकर और संदेशों का उत्पादन करने के लिए प्रतिध्वनि के उपयोग को त्यागते हुए , मैं ध्यान देता हूं कि एक असाइनमेंट स्टेटमेंट सभी आवश्यकताओं को पूरा कर सकता है।

एक निष्क्रिय चर के लिए एक पाठ स्ट्रिंग (संदेश युक्त) का असाइनमेंट करें।

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

echo="====================== Divider line ================="

टर्मिनल पर आप जो देखेंगे वह केवल 1 लाइन है:

++ echo='====================== Divider line ================='

दो नहीं, ओपी नापसंद:

+ echo '====================== Divider line ================='
====================== Divider line =================

यहाँ नमूना स्क्रिप्ट प्रदर्शित करने के लिए है। ध्यान दें कि एक चर में चर प्रतिस्थापन ($ HOME निर्देशिका नाम अंत से 4 लाइनें) काम करता है, इसलिए आप इस विधि का उपयोग करके चर का पता लगा सकते हैं।

#!/bin/bash -exu
#
#  Example Script showing how, with trace active, messages can be produced
#  without producing two virtually duplicate line on the terminal as echo does.
#
dummy="====================== Entering Test Script ================="
if [[ $PWD == $HOME ]];  then
  dummy="*** "
  dummy="*** Working in home directory!"
  dummy="*** "
  ls -la *.c || :
else
  dummy="---- C Files in current directory"
  ls -la *.c || :
  dummy="----. C Files in Home directory "$HOME
  ls -la  $HOME/*.c || :
fi

और यहाँ इसे रूट में चलाने से आउटपुट है, फिर होम डायरेक्टरी।

$ cd /&&DemoScript
+ dummy='====================== Entering Test Script ================='
+ [[ / == /g/GNU-GCC/home/user ]]
+ dummy='---- C Files in current directory'
+ ls -la '*.c'
ls: *.c: No such file or directory
+ :
+ dummy='----. C Files in Home directory /g/GNU-GCC/home/user'
+ ls -la /g/GNU-GCC/home/user/HelloWorld.c /g/GNU-GCC/home/user/hw.c
-rw-r--r-- 1 user Administrators 73 Oct 10 22:21 /g/GNU-GCC/home/user/HelloWorld.c
-rw-r--r-- 1 user Administrators 73 Oct 10 22:21 /g/GNU-GCC/home/user/hw.c
+ dummy=---------------------------------

$ cd ~&&DemoScript
+ dummy='====================== Entering Test Script ================='
+ [[ /g/GNU-GCC/home/user == /g/GNU-GCC/home/user ]]
+ dummy='*** '
+ dummy='*** Working in home directory!'
+ dummy='*** '
+ ls -la HelloWorld.c hw.c
-rw-r--r-- 1 user Administrators 73 Oct 10 22:21 HelloWorld.c
-rw-r--r-- 1 user Administrators 73 Oct 10 22:21 hw.c
+ dummy=---------------------------------

1
ध्यान दें, यहां तक ​​कि आपके हटाए गए उत्तर का संपादित संस्करण (जो यह एक प्रतिलिपि है), फिर भी सवाल का जवाब नहीं देता है, क्योंकि उत्तर केवल संबंधित ईको कमांड के बिना संदेश को आउटपुट नहीं करता है, जो कि ओपी ने पूछा था।
DavidPostill


@ डेविड मैंने मेटा फोरम में टिप्पणियों के अनुसार स्पष्टीकरण को बढ़ा दिया है।
HiTechHiTouch

@ डेविड फिर मैं आपको ओपी को बहुत ध्यान से पढ़ने के लिए प्रोत्साहित करता हूं, लैटिन ".eg" पर ध्यान देना। पोस्टर को इको कमांड का उपयोग करने की आवश्यकता नहीं है। ओपी समस्या को हल करने के लिए संभावित तरीकों के उदाहरण (पुनर्निर्देशन के साथ) के रूप में केवल प्रतिध्वनि का संदर्भ देता है। पता चला कि आपको या तो ज़रूरत नहीं है,
हाईटेक हाईट

और अगर ओपी कुछ करना चाहता है तो क्या होगा echo "Here are the files in this directory:" *?
जी-मैन का कहना है कि 'मोनिका'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.