স্ক্রিপ্টের বাইরের দিক থেকে বাশ এক্সিকিউশন ট্রেস (সেট-এক্স) দমন করুন


17

আমি এই প্রশ্নের উত্তর খোঁজার চেষ্টা করেছি, তবে এখনও ভাগ্য পাইনি:

আমার কাছে একটি স্ক্রিপ্ট রয়েছে যা কিছু অন্যান্য স্ক্রিপ্ট চালায় এবং অন্যান্য স্ক্রিপ্টগুলির অনেকটির মধ্যে "সেট-এক্স" রয়েছে, যা তাদের চালানো প্রতিটি আদেশ মুদ্রণ করে। আমি এ থেকে পরিত্রাণ পেতে চাই তবে স্ক্রিপ্টগুলির মধ্যে যদি কোনও স্ট্যান্ডারকে ত্রুটি বার্তা প্রেরণ করে তবে তথ্যটি ধরে রাখতে চাই।

সুতরাং আমি সহজভাবে লিখতে পারি না ./script 2>/dev/null

এছাড়াও, আমার কাছে এই অন্যান্য স্ক্রিপ্টগুলি সম্পাদনা করার অধিকার নেই, তাই আমি নিজেই সেট বিকল্পটি পরিবর্তন করতে পারি না।

আমি স্ট্যাডার থেকে পৃথক ফাইলে সবকিছু লগিং এবং ট্রেসিং কমান্ডগুলি ফিল্টার আউট করার বিষয়ে ভাবছিলাম, তবে সম্ভবত আরও সহজ উপায় আছে?


উত্তর:


25

সঙ্গে bash4.1 এবং, আপনি কি করতে পারেন

BASH_XTRACEFD=7 ./script.bash 7> /dev/null

(যখন bashআহ্বান করা হয় তখনও কাজ করেsh )।

মূলত, আমরা 2-এর ডিফল্ট পরিবর্তে ফাইল বর্ণনাকারী 7 bashxtraceআউটপুট আউটপুট দিতে বলছি এবং সেই ফাইল বিবরণীতে পুনঃনির্দেশিত করব /dev/null। এফডি সংখ্যাটি নির্বিচারে। 2 এর উপরে একটি এফডি ব্যবহার করুন যা অন্যথায় আপনার স্ক্রিপ্টে ব্যবহৃত হয় না। আপনি যে কমান্ডটি এই কমান্ডটি প্রবেশ করিয়ে দিচ্ছেন তা যদি হয় bashবা yashআপনি 9 এর উপরে একটি সংখ্যাও ব্যবহার করতে পারেন (যদিও শেল দ্বারা ফাইলের বর্ণনাকারী অভ্যন্তরীণভাবে ব্যবহার করা থাকলে আপনি সমস্যা হতে পারে)।

আপনি যে bashস্কেলটি থেকে যে স্কেলটি কল করছেন সেটি যদি হয় তবে আপনি এটি zshকরতেও পারেন:

(export BASH_XTRACEFD; ./script.bash {BASH_XTRACEFD}> /dev/null)

ভেরিয়েবলটি স্বয়ংক্রিয়ভাবে 9 এর উপরে প্রথম বিনামূল্যে এফডি নির্ধারণ করা হবে।

পুরানো সংস্করণগুলির জন্য bash, অন্য বিকল্পটি যদি xtraceচালু হয় set -x(এর বিপরীতে #! /bin/bash -xবা এর সাথে set -o xtrace) চালু করা হয় setতখন রফতানি করা ফাংশন হিসাবে পুনরায় সংজ্ঞায়িত করা হবে যা পাস করার পরে কিছুই করেনা -x(যদিও এটি স্ক্রিপ্টটি ভেঙে ফেলবে (অথবা অন্য কোনও bashস্ক্রিপ্ট এটি আহ্বান করে) setঅবস্থানগত পরামিতি সেট করতে ব্যবহৃত )।

ভালো লেগেছে:

set()
  case $1 in
    (-x) return 0;;
    (-[!-]|"") builtin set "$@";;
    (*) echo >&2 That was a bad idea, try something else; builtin set "$@";;
  esac

export -f set
./script.bash

অন্য বিকল্পটি হ'ল একটি ডিবাগিজি ট্র্যাপ যুক্ত করা $BASH_ENVউচিত যা set +xপ্রতিটি কমান্ডের আগে করে।

echo 'trap "{ set +x; } 2>/dev/null" DEBUG' > ~/.no-xtrace
BASH_ENV=~/.no-xtrace ./script.bash

set -xযদিও সাব-শেল-এ করা হয়ে গেলে এটি কাজ করবে না ।

@ ইল্ক্কাছু যেমন বলেছিলেন, আপনি যদি ফাইল সিস্টেমের কোনও ফোল্ডারে লেখার অনুমতি পেয়ে থাকেন তবে আপনার কমপক্ষে স্ক্রিপ্টের একটি অনুলিপি তৈরি করতে এবং এটি সম্পাদনা করতে সক্ষম হওয়া উচিত।

যদি কোথাও না থাকে আপনি স্ক্রিপ্টের একটি অনুলিপি লিখতে পারেন, বা প্রতিবার মূল স্ক্রিপ্টে আপডেট হওয়ার পরে কোনও নতুন অনুলিপি তৈরি করা এবং সম্পাদনা করা সুবিধাজনক না হলে আপনি এখনও করতে সক্ষম হবেন:

 bash <(sed 's/set -x/set +x/g' ./script.bash)

এটি (এবং অনুলিপি পদ্ধতির) ঠিক মতো কাজ করতে পারে না যদি স্ক্রিপ্টটি অভিনব কিছু করে $0বা বিশেষ ভেরিয়েবলের মতো করে $BASH_SOURCE(যেমন স্ক্রিপ্টের অবস্থানের সাথে সম্পর্কিত ফাইলগুলি সন্ধান করা), সুতরাং আপনাকে আরও কিছু সম্পাদনা করার মতো হতে পারে $0স্ক্রিপ্টের পথটি প্রতিস্থাপন করুন ...


আপনার প্রথম উত্তরটি হ'ল আমার যা প্রয়োজন, পরিষ্কার এবং মার্জিত। আপনি একটু ব্যাখ্যা করতে পারেন কিভাবে এটি কাজ করে? 7 নম্বর কেন? অন্যান্য নম্বর কি জন্য ব্যবহার করা যেতে পারে? ধন্যবাদ।
মানব

@ হিউম্যান, সম্পাদনা দেখুন
স্টাফেন চেজেলাস

1
{BASH_XTRACEFD}>কৌতুক কাজ করে bash4.1 বা পরবর্তী হিসাবে ভাল।
চ্যানার

@ চেপনার, হ্যাঁ বৈশিষ্ট্যটি zsh, ksh93 এবং ব্যাশে যুক্ত করা হয়েছিল একই সময়ে একটি zsh বিকাশকারীর পরামর্শ অনুসারে। কিন্তু এখানে এটা না কাজের জন্য নয় ksh93বা bashযে পরিবর্তনশীল কমান্ড (তুলনা পরিবেশ পাস করা হয় না <shell> -c 'export fd; printenv fd {fd}> /dev/null'zsh, bashএবং ksh93)। আপনি এটি দুটি পদক্ষেপে বা সম্ভবত ব্যবহার করে ksh93/ এটিকে কাজ করতে পারেন , তবে xtrace বিকল্পটি চালু থাকলে এর পার্শ্ব প্রতিক্রিয়া হবে। bashevalbash
স্টাফেন চেজেলাস

5

যেহেতু সেগুলি স্ক্রিপ্ট, আপনি করতে পারেন অনুলিপি তৈরি করতে এবং সেগুলি সম্পাদনা পারেন।

ফিল্টারিং সহজ করার জন্য, আউটপুট ফিল্টার করা সহজ বলে মনে হয়, আপনি স্পষ্টভাবে PS4একক প্লাসের চেয়ে আরও অস্বাভাবিক কিছুতে সেট করতে পারেন:

PS4="%%%%" bash script.sh 2>&1 | grep -ve '^%%%%'

(অবশ্যই এটি স্টাডাউট এবং স্টিডিনের পতন ঘটবে, তবে বাশে কেবল স্ট্যাডারকে পাইপিং করা কিছুটা লোমশ হয়ে যায়, তাই আমি এড়িয়ে যাব)


1
শুধু দ্বারা stderr বংশীধ্বনিতুল্য সহজ: PS4="%%%%" bash script.sh 2> >(grep -ve '^%%%%')
প্যাট্রিক

4
@ পেট্রিক, bashএটির মতো সমস্যাগুলি অ্যাসিক্রোনোসিয়ালি grepচালিত হয় (বাশ এটির জন্য অপেক্ষা করে না, সুতরাং এটি স্ক্রিপ্টের পরবর্তী কমান্ড শুরু হওয়ার পরে আউটপুট জিনিসগুলি করতে পারে) এবং does
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.