ইকো কমান্ডের জন্য এক্সিকিউশন ট্রেস দমন করবেন?


29

আমি জেনকিন্স থেকে শেল স্ক্রিপ্টগুলি চালাচ্ছি, যা শ্যাবাং অপশনগুলির সাথে শেল স্ক্রিপ্টগুলি বন্ধ করে দেয় #!/bin/sh -ex

ডামিদের জন্য বাশ শেবাং অনুসারে ? ,, -x"শেলটি একটি এক্সিকিউশন ট্রেস মুদ্রণ করে তোলে", যা বেশিরভাগ উদ্দেশ্যে দুর্দান্ত - ইকোস ব্যতীত:

echo "Message"

আউটপুট উত্পাদন করে

+ echo "Message"
Message

যা কিছুটা অপ্রয়োজনীয় এবং কিছুটা অদ্ভুত লাগছে। -xসক্ষম করার ছেড়ে যাওয়ার কোনও উপায় আছে তবে কেবল আউটপুট

Message

উপরের দুটি রেখার পরিবর্তে, যেমন একটি বিশেষ কমান্ড অক্ষরের সাথে ইকো কমান্ডের উপসর্গ রেখে, বা আউটপুট পুনঃনির্দেশিত করে?

উত্তর:


20

আপনি যখন অ্যালিগিটারগুলিতে আপনার ঘাড়ে পৌঁছান, তখন ভুলে যাওয়া সহজ যে গোলটি সোয়াম্পটি নিকাশ করা ছিল।                   - জনপ্রিয় উক্তি

প্রশ্নটি সম্পর্কে echo, এবং এখনও অবধি বেশিরভাগ উত্তর কীভাবে কোনও set +xকমান্ডকে ছিনতাই করতে হবে সেদিকে মনোনিবেশ করেছে a এর একটি আরও সহজ, আরও প্রত্যক্ষ সমাধান রয়েছে:

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

(আমি স্বীকার করি যে আমি { …; } 2> /dev/null যদি পূর্বের উত্তরগুলিতে না দেখি তবে আমি এটি সম্পর্কে ভাবতে পারি না))

এটি কিছুটা কষ্টকর, তবে, যদি আপনার ক্রমাগত echoকমান্ডগুলির একটি ব্লক থাকে, তবে আপনাকে পৃথকভাবে প্রতিটিটির জন্য এটি করার প্রয়োজন হবে না:

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

মনে রাখবেন যে আপনার যখন নিউলাইনগুলি থাকে তখন আপনাকে সেমিকোলনগুলির প্রয়োজন হয় না।

আপনি কোনও/dev/null মানের-অ-স্ট্যান্ডার্ড ফাইল বর্ণনাকারীর (যেমন, 3) স্থায়ীভাবে খোলার কেনোরব ধারণাটি ব্যবহার করে টাইপিং বোঝা হ্রাস করতে পারেন এবং তারপরে সর্বকালের 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 লেখা পেতে কমান্ড।)

সুতরাং, আমার প্রথম কৌশলটির জন্য:

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

এখন, যখন আমরা বলি echo "Message", আমরা উপনামটি কল করছি, যা সনাক্ত করা যায় না। setকমান্ডটি থেকে ট্রেস বার্তাটি দমন করার সময় (নাম 50501515 এর উত্তরে প্রথমে উপস্থাপিত কৌশলটি ব্যবহার করা হয়েছে ), এবং তারপরে প্রকৃত echoকমান্ডটি কার্যকর করে তার নামটি ট্রেস বিকল্পটি বন্ধ করে দেয় । এটি আমাদের প্রতিটি echo কমান্ডে কোড সম্পাদনা করার প্রয়োজন ছাড়াই ব্যবহারকারীর 5071535 এর উত্তরের মতো একটি প্রভাব পেতে দেয় । তবে, এই পাতাগুলি ট্রেস মোডটি বন্ধ করে দিয়েছে। আমরা একটি 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পারি - এবং আমরা আরও কিছু চালাকি করে with তবে আমি এটি উপস্থাপন করার আগে এটি বিবেচনা করুন। #!/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. নিম্নলিখিত শেবাং লাইন ব্যবহার করতে:
    #! / বিন / এস-এক্স
    #! / বিন / শি -e
    #! / বিন / শ এক্স
    বা ঠিক সরল
    #! / বিন / SH
    এবং এটি প্রত্যাশা অনুযায়ী কাজ করা উচিত।
  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

পিএস আমি আবিষ্কার করেছি যে, আমার সিস্টেমে, আমি builtinআমার মধ্যম উত্তরে কীওয়ার্ডটি রেখে দিতে পারি (যার জন্য এটি কেবলমাত্র একটি উপনাম echo)। এটি আশ্চর্যজনক নয়; বাশ (1) বলেছেন যে, ওরফে সম্প্রসারণের সময়,…

… এমন একটি শব্দ যা একটি উপনামের সমান যা প্রসারিত হচ্ছে তা দ্বিতীয় বার প্রসারিত হয় না। এর অর্থ এই যে এক ওরফে পারে lsথেকে ls -F, উদাহরণস্বরূপ, এবং ব্যাশ যাও recursively প্রতিস্থাপন পাঠ্য প্রসারিত করতে চেষ্টা করে না।

না খুব আশ্চর্যজনক, গত উত্তর (সঙ্গে এক 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

আমি ইনফর্মিট এ একটি আংশিক সমাধান পেয়েছি :

#!/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 / নাল" তে পুনঃনির্দেশক স্ট্যান্ডার যা সাময়িকভাবে "অক্ষম" ট্রেসিংয়ের কাজ করছে ... মনে হয় echo foo1 2>/dev/null, ইত্যাদি, ঠিক তত কার্যকর এবং আরও পঠনযোগ্য হবে।
টাইলার রিক

আপনার স্ক্রিপ্টে ট্রেসিং করা কার্য সম্পাদনকে প্রভাবিত করতে পারে। দ্বিতীয়ত & 2 টি NUL এ পুনঃনির্দেশ একইরকম হতে পারে না, যখন আপনি অন্য কিছু ত্রুটি আশা করেন।
কেনারব

আমি ভুল হলে আমাকে সংশোধন করুন, তবে আপনার উদাহরণে আপনি ইতিমধ্যে আপনার স্ক্রিপ্টটিতে ট্রেসিং সক্ষম করেছেন (সহ 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'

থেকে এই গনুহ ডক:

যখন একটি লাইন '@' দিয়ে শুরু হয়, তখন সেই লাইনের প্রতিধ্বনি দমন করা হয়। শেলটিতে লাইনটি পাস করার আগে '@' বাতিল করা হবে। সাধারণত আপনি এটি একটি কমান্ডের জন্য ব্যবহার করবেন যার একমাত্র প্রভাব কিছু মুদ্রণ করা যেমন মেকফাইলের মাধ্যমে অগ্রগতি নির্দেশ করার জন্য প্রতিধ্বনি কমান্ড command


হাই, আপনি যে ডকটির বিষয়ে উল্লেখ করছেন সেটি শেন নয়, gnu মেক করার জন্য। আপনি কি নিশ্চিত যে এটি কাজ করে? আমি ত্রুটি ./test.sh: line 1: @echo: command not foundপেয়েছি, তবে আমি ব্যাশ ব্যবহার করছি।

বাহ, দুঃখিত আমি পুরোপুরি প্রশ্নটি ভুল করে পড়েছি। হ্যাঁ, আপনি @কেবল মেকফাইলে প্রতিধ্বনিত হলেই কাজ করে।
ডেরেক

@ ডেরেক আমি আপনার মূল উত্তরটি সম্পাদনা করেছি তাই এটি এখন স্পষ্টভাবে জানিয়েছে যে সমাধানটি কেবল মেকফিলের জন্যই সীমাবদ্ধ। আমি আসলে এটির জন্য সন্ধান করছিলাম, তাই আমি চাইছিলাম আপনার মন্তব্যের নেতিবাচক খ্যাতি না ঘটে। আশা করি, লোকেরাও এটি সহায়ক বলে মনে করবে।
শাকারন

-1

মডারেটরের প্রতি 29 অক্টোবর 2016 সম্পাদিত পরামর্শে যে ঘটছে তা বোঝার জন্য মূলটিতে পর্যাপ্ত তথ্য নেই।

এই "কৌশল" টার্মিনালে বার্তা আউটপুট কেবল একটি লাইন উত্পাদন করে যখন xtrace সক্রিয় থাকে:

আসল প্রশ্নটি হল -x সক্ষম করার কোনও উপায় আছে তবে দুটি লাইনের পরিবর্তে কেবলমাত্র বার্তা আউটপুট দেয় । এটি হুবহু প্রশ্নের বক্তব্য।

আমি প্রশ্নটি বুঝতে পেরেছি, কীভাবে "সেট-এক্স সক্ষম থাকতে হবে এবং একটি বার্তার জন্য একটি একক লাইন উত্পাদন করতে হবে"?

  • বৈশ্বিক অর্থে, এই প্রশ্নটি মূলত নন্দনতত্ত্ব সম্পর্কে - প্রশ্নকর্তা অক্সট্রেস সক্রিয় থাকাকালীন উত্পাদিত দুটি কার্যত সদৃশ রেখার পরিবর্তে একটি লাইন তৈরি করতে চান produce

সুতরাং সংক্ষেপে, ওপি এর প্রয়োজন:

  1. আছে সেট -x কার্যকর
  2. মানব পাঠযোগ্য, একটি বার্তা উত্পন্ন করুন
  3. বার্তা আউটপুট কেবল একটি লাইন উত্পাদন।

ওপি নেই না প্রয়োজন যে প্রতিধ্বনি কমান্ড ব্যবহৃত হবে না। তারা এটিকে বার্তা উত্পাদনের উদাহরণ হিসাবে সংক্ষিপ্তসার উদাহরণ হিসাবে উল্লেখ করেছেন যা লাতিনের উদাহরণস্বরূপ গ্র্যাটিয়া বা "উদাহরণস্বরূপ" ব্যবহার করে।

"বাক্সের বাইরে" ভাবনা এবং বার্তা তৈরি করতে প্রতিধ্বনি ব্যবহার ত্যাগ করা , আমি নোট করি যে একটি অ্যাসাইনমেন্ট বিবৃতি সমস্ত প্রয়োজনীয়তা পূরণ করতে পারে।

একটি নিষ্ক্রিয় ভেরিয়েবলের জন্য একটি পাঠ্য স্ট্রিংয়ের (অ্যাসেসর্ট) বার্তাটি করুন।

কোনও স্ক্রিপ্টে এই লাইনটি যুক্ত করা কোনও যুক্তি পরিবর্তিত করে না, তবুও ট্রেসিং সক্রিয় থাকাকালীন একটি একক লাইন তৈরি করে: (আপনি যদি ভেরিয়েবল- ইকো ব্যবহার করছেন তবে কেবল নামটি অন্য অব্যবহৃত ভেরিয়েবলে পরিবর্তন করুন)

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

আপনি টার্মিনালে যা দেখবেন তা কেবলমাত্র 1 লাইন:

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

দু'টি নয়, ওপি অপছন্দ করে:

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

এখানে নমুনা স্ক্রিপ্ট প্রদর্শিত হয়। নোট করুন যে একটি বার্তায় ভেরিয়েবল প্রতিস্থাপন (from 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
দ্রষ্টব্য, এমনকি আপনার মোছা উত্তরের সম্পাদিত সংস্করণ (এটি এটির একটি অনুলিপি) এখনও প্রশ্নের উত্তর দেয় না, কারণ উত্তরটি সম্পর্কিত প্রতিধ্বনি কমান্ড ব্যতিরেকে কেবল বার্তাটি আউটপুট দেয় না, যা ওপি চেয়েছিল।
ডেভিডপস্টিল


@ ডেভিড আমি মেটা ফোরামে মন্তব্য অনুসারে ব্যাখ্যাটি প্রসারিত করেছি।
হাইটেকহটাইচ

@ ডেভিড আবার আমি আপনাকে ল্যাটিন ".eg" এ মনোযোগ দিয়ে খুব মনোযোগ সহকারে ওপিটি পড়তে উত্সাহিত করি। পোস্টারটির জন্য ইকো কমান্ডটি ব্যবহারের প্রয়োজন নেই। সমস্যা সমাধানের সম্ভাব্য পদ্ধতিগুলির উদাহরণ হিসাবে (পুনর্নির্দেশের পাশাপাশি) ওপি কেবল প্রতিবেদনের প্রতিধ্বনি দেয়। দেখা যাচ্ছে আপনার কোনও প্রয়োজন নেই,
হাইটেকহিটচ

এবং যদি ওপি কিছু করতে চায় echo "Here are the files in this directory:" *?
জি-ম্যান বলছেন 'পুনরায় ইনস্টল করুন মনিকা'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.