বাশ স্ক্রিপ্টের কোন লাইনটি কার্যকর করা হচ্ছে তা কীভাবে পরীক্ষা করবেন


15

"এখনই" কোনও স্ক্রিপ্টের কোন লাইন সংখ্যাটিbash কার্যকর করা হচ্ছে তা পরীক্ষা করার কোনও উপায় আছে ?

bash -x script.shআশাব্যঞ্জক দেখাচ্ছে ব্যবহার করে ; তবে, আমার বর্তমান লাইন নম্বরটি পাওয়া দরকার।

উত্তর:


20

একত্রিত xtraceসঙ্গে PS4স্ক্রিপ্ট ভিতরে:

$ cat test.sh 
#!/usr/bin/env bash
set -x
PS4='+${LINENO}: '

sleep 1m
sleep 1d
$ timeout 5 ./test.sh
+3: PS4='+${LINENO}: '
+5: sleep 1m

বা মূল শেল মধ্যে :

$ cat test.sh 
sleep 1m
sleep 1d
$ export PS4='+${LINENO}: '
$ timeout 5 bash -x ./test.sh
+1: sleep 1m

10

হ্যাঁ, একটি উপায় আছে।
লাইন নম্বরগুলির একটি অ্যারে রয়েছে যেখানে একটি ফাংশন কল করা হয়েছে।

এই ফাংশনটি সংজ্ঞায়িত করুন:

f(){ echo "${BASH_LINENO[-2]}"; }

এবং fযে কোনও লাইনে আপনি লাইন নম্বরটি চান তা কল করুন , উদাহরণস্বরূপ:

#!/bin/bash


f(){ echo "${BASH_LINENO[-2]}"; }

f

echo next1
f

echo next2
f

echo next 3
f

মুদ্রণ করবে:

6
next 1
9
next 2
12
next 3
15

যাকে ডাকা ফাংশনগুলির ট্রেইল দেখানোর জন্য এটি বাড়ানো যেতে পারে:

#!/bin/bash

f(){
    for ((i=${#BASH_LINENO[@]}-1;i>=0;i--)); do
    printf '<%s:%s> ' "${FUNCNAME[i]}" "${BASH_LINENO[i]}";
    done
    echo "$LINENO"
 }

SomeOtherFunction(){ echo -n "test the line numbering:  "; f; }

f

echo next 1
echo -n "    This line numbering:  "; f
SomeOtherFunction

echo next 2
echo -n "    This line numbering:  "; f
SomeOtherFunction

echo next 3
echo -n "    This line numbering:  "; f

যা মুদ্রণ করবে:

$ ./script
<main:0> <f:12> 7
next 1
    This line numbering:  <main:0> <f:15> 7
test the line numbering:  <main:0> <SomeOtherFunction:16> <f:10> 7
next 2
    This line numbering:  <main:0> <f:19> 7
test the line numbering:  <main:0> <SomeOtherFunction:20> <f:10> 7
next 3
    This line numbering:  <main:0> <f:23> 7

নোট করুন যে উপরে echo "$LINENO"আউটপুট সবসময় একই (এই ক্ষেত্রে 7)।


7

এখানে এমন একটি সমাধান রয়েছে যা l0b0 এবং ডোপগোতির উত্তরগুলির অংশগুলি ধার করে (এবং কিছুটা হলেও সোরোনটারের )। এই উত্তরগুলির মতো, খনি $LINENOলাইন নম্বরটি আবিষ্কার করতে ব্যবহার করে; তাদের মত নয়, আমি trapপ্রতিবেদনটি ট্রিগার করতে ব্যবহার করি । বাশের trapনির্দেশ আদেশে (1) বর্ণিত হয়েছে :

trap [-lp] [[arg] sigspec ...]

    কমান্ড ARG পড়া এবং নিষ্পন্ন করা হবে যখন শেল পায় সংকেত (গুলি) হল sigspec । ... ⁠ ︙
    ... একটি যদি sigspec হয় ডিবাগ কমান্ড ARG প্রত্যেক আগে মৃত্যুদন্ড কার্যকর করা হয় সহজ কমান্ড , forকমান্ড caseকমান্ড selectকমান্ড প্রত্যেক গাণিতিক forকমান্ড, এবং একটি শেল ফাংশন প্রথম বিধান সামনে ...

সুতরাং এই লিপি:

$ cat -n myscript
     1  #!/bin/bash
     2  trap 'printf "%3d: " "$LINENO"' DEBUG
     3  date
     4  sleep 30
     5  date
     6  sleep \
     7        11
     8  date
     9
    10  ls -l
    11  for f in *
    12  do
    13          echo "$f"  &&
    14                         ls -ld "$f"
    15  done
    16
    17  for ((i=0; i<3; i++))
    18  do
    19          echo "i = $i"; date
    20  done
    21
    22  echo $((5+25+12))
$

printf "%3d: " "$LINENO"স্ক্রিপ্টের প্রতিটি কমান্ডের আগে কমান্ড চালায় এবং এই আউটপুট উত্পাদন করে:

$ ./myscript
  3: বুধ, এপ্রিল 05, 2017 10:16:17 এএম
  4: 5: বুধ, এপ্রিল 05, 2017 10:16:47 এএম
  7: 8: বুধ, এপ্রিল 05, 2017 10:16:58 এএম
 10: মোট 4
-rwxr-xr-x 1 myusername মাইগ্রুপ 221 এপ্রিল 5 10:01 রহস্য
-rwxr-xr-x 1 myusername মাইগ্রুপ 252 এপ্রিল 5 10:01 myscript2
-rw-r - r-- 1 myusername mygroup 132 এপ্রিল 5 09:59 myscript2.log
-rw-r - r-- 1 myusername   মাইগ্রুপ 45 এপ্রিল 5 08:34 other_file ile
 11: 13: রহস্য
 14: -rwxr-xr-x 1 myusername মাইগ্রুপ 221 এপ্রিল 5 10:01 রহস্য
 11: 13: myscript2
 14: -rwxr-xr-x 1 myusername মাইগ্রুপ 252 এপ্রিল 5 10:01 myscript2
 11: 13: myscript2.log
 14: -rw-R - r-- 1 myusername mygroup 132 এপ্রিল 5 09:59 myscript2.log
 11: 13: অন্যান্য_ ফাইল
 14: -rw-R - r-- 1 myusername mygroup   45 এপ্রিল 5 08:34 other_file
 17: 17: 19: i = 0
 19: বুধ, এপ্রিল 05, 2017 10:16:59 পূর্বাহ্ন
 17: 17: 19: i = 1
 19: বুধ, এপ্রিল 05, 2017 10:16:59 পূর্বাহ্ন
 17: 17: 19: i = 2
 19: বুধ, এপ্রিল 05, 2017 10:16:59 পূর্বাহ্ন
 17: 17: 22: 42
$

মন্তব্য:

  • L0b0 এর উত্তরের মতো এটিও ন্যূনতম আক্রমণাত্মক - কেবল লাইন 2 যুক্ত করুন।
  • L0b0 এর উত্তরের বিপরীতে , কমান্ডগুলি সেগুলি তাদের প্রদর্শিত হয় না - তবে আপনি এটি করার জন্য বলেননি।
  • দ্বিতীয়টি sleep, যা স্ক্রিপ্টের লাইন and এবং sp বিস্তৃত করে, line নম্বর লাইন হিসাবে রিপোর্ট করা হয়।
  • লাইন 11 ( for f in *) লুপটির প্রতিটি পুনরাবৃত্তির আগে একবার রিপোর্ট করা হয় for
  • echo "$f"এবং ls -ld "$f"সঠিকভাবে তাদের নিজ নিজ লাইনে রিপোর্ট করা হয়েছে (13 এবং 14)।
  • 17 লাইনটি লুপটির প্রতিটি পুনরাবৃত্তির আগে দু'বার এবং শেষ পুনরাবৃত্তির পরে আরও দুবার for ((i=0; i<3; i++))রিপোর্ট করা হয়for
  • অসদৃশ set -x, LINENOএবং PS4 (যা POSIX মান দ্বারা নির্দিষ্ট করা হয়), DEBUG trapবাশ এক্সটেনশন এবং সমস্ত শেলগুলিতে কাজ করবে না।
  • DEBUG trapযে কোনও কমান্ড (গুলি) চালাতে পারে, এবং স্ক্রিপ্টের স্ট্যান্ডার্ড আউটপুট বা স্ট্যান্ডার্ড ত্রুটিতে লিখিতভাবে সীমাবদ্ধ নয়।

প্রশ্নটি বলছে, «কোনও ব্যবহারকারী ইন্টারফেস নির্দিষ্ট না করেই" এখনই "বাশ স্ক্রিপ্টের কোন লাইন নম্বরটি কার্যকর করা হচ্ছে তা পরীক্ষা করুন। আরেকটি পদ্ধতি হ'ল একটি লগ ফাইলে নিয়মিতভাবে বর্তমান লাইন নম্বরটি লিখতে হয়:

mys পার্থক্য মাইক্রিপ্ট myscript2
2C2
<ট্র্যাপ 'প্রিন্টফ "% 3 ডি:" "$ লিনেনো"' ডিবগ
---
> নির্বাহ 6> myscript2.log && ট্র্যাপ 'প্রিন্টফ "% 3 ডি \ n" "$ লিনেনো"> & 6' ডিবগ
$ ./myscript2
বুধ, এপ্রিল 05, 2017 10:23:50 এএম
বুধ, এপ্রিল 05, 2017 10:24:20 পূর্বাহ্ন
বুধ, এপ্রিল 05, 2017 10:24:31 এএম
মোট 4
-rwxr-xr-x 1 myusername মাইগ্রুপ 221 এপ্রিল 5 10:01 রহস্য
-rwxr-xr-x 1 myusername মাইগ্রুপ 252 এপ্রিল 5 10:01 myscript2
-rw-r - r-- 1 myusername   মাইগ্রুপ 24 এপ্রিল 5 10:23 myscript2.log
-rw-r - r-- 1 myusername   মাইগ্রুপ 45 এপ্রিল 5 08:34 other_file ile
myscript
-rwxr-xr-x 1 myusername মাইগ্রুপ 221 এপ্রিল 5 10:01 রহস্য
myscript2
-rwxr-xr-x 1 myusername মাইগ্রুপ 252 এপ্রিল 5 10:01 myscript2
myscript2.log
-rw-r - r-- 1 myusername   mygroup 60 এপ্রিল 5 10:23 myscript2.log
other_file
-rw-r - r-- 1 myusername   মাইগ্রুপ 45 এপ্রিল 5 08:34 other_file ile
i = 0
বুধ, এপ্রিল 05, 2017 10:24:31 এএম
i = 1
বুধ, এপ্রিল 05, 2017 10:24:31 এএম
i = 2
বুধ, এপ্রিল 05, 2017 10:24:31 এএম
42
$

আমরা myscript2.logঅন্য স্ক্রিন থেকে ফাইলের বিষয়বস্তু পর্যবেক্ষণ করে এই স্ক্রিপ্টটির কার্যকারিতা পর্যবেক্ষণ করতে পারি । উদাহরণস্বরূপ, দ্বিতীয় সময়ে sleep,

$ tail myscript2.log
  3
  4
  5
  7

6

আপনি echo $LINENOকোনও স্ক্রিপ্টে করতে পারেন এবং যে কমান্ডটি চালু হতে পারে তাতে যে কোনও লাইন আউটপুট করা উচিত।

#!/bin/bash
echo $LINENO

$ ./foo.sh
2

-1
#!/bin/bash -x

আপনার স্ক্রিপ্টের শুরুতে "-x" যুক্ত করুন। তারপরে আপনি যখন স্ক্রিপ্টটি কার্যকর করবেন তখন এটি আপনার স্ক্রিপ্টটি সম্পাদন করছে এমন রেখাটি প্রতিধ্বনিত করবে। আপনার স্ক্রিপ্টের এক্সিকিউশন ট্রি এর মতো।


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