সিনট্যাক্স ত্রুটিতে স্ক্রিপ্টের প্রয়োগকে কীভাবে বাশ বাতিল করতে হবে?


15

নিরাপদ দিকে থাকতে, আমি চাই স্ক্রিপ্টের সিন্টেক্স ত্রুটির সম্মুখীন হলে কোনও স্ক্রিপ্ট কার্যকর করা বাতিল করা উচিত।

আমার অবাক করার বিষয়, আমি এটি অর্জন করতে পারি না। ( set -eযথেষ্ট নয়)) উদাহরণ:

#!/bin/bash

# Do exit on any error:
set -e

readonly a=(1 2)

# A syntax error is here:

if (( "${a[#]}" == 2 )); then
    echo ok
else
    echo not ok
fi

echo status $?

echo 'Bad: has not aborted execution on syntax error!'

ফলাফল (bash-3.2.39 বা bash-3.2.51):

$ ./sh-on-syntax-err
./sh-on-syntax-err: line 10: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$ 

ঠিক আছে, $?সিনট্যাক্স ত্রুটিগুলি ধরার জন্য আমরা প্রতিটি বিবৃতি পরে পরীক্ষা করতে পারি না ।

(আমি একটি বুদ্ধিমান প্রোগ্রামিং ভাষা থেকে এই ধরনের নিরাপদ আচরণের প্রত্যাশা করেছি ... সম্ভবত এটি অবশ্যই বাগ হিসাবে রিপোর্ট করা উচিত / বিকাশকারীদের বাশ করতে ইচ্ছুক)

আরও পরীক্ষা নিরীক্ষা

if কোন পার্থক্য করে না।

সরানো হচ্ছে if:

#!/bin/bash

set -e # exit on any error
readonly a=(1 2)
# A syntax error is here:
(( "${a[#]}" == 2 ))
echo status $?
echo 'Bad: has not aborted execution on syntax error!'

ফলাফল:

$ ./sh-on-syntax-err 
./sh-on-syntax-err: line 6: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$ 

সম্ভবত, এটি http://mywiki.wooledge.org/BashFAQ/105 থেকে অনুশীলন 2 সম্পর্কিত এবং এর সাথে কিছু করার আছে (( ))। তবে আমি সিনট্যাক্স ত্রুটির পূর্বে সম্পাদন চালিয়ে যাওয়া অযৌক্তিক মনে করি।

না, (( ))কোন পার্থক্য!

পাটিগণিত পরীক্ষা না করেও এটি খারাপ আচরণ করে! কেবল একটি সাধারণ, প্রাথমিক স্ক্রিপ্ট:

#!/bin/bash

set -e # exit on any error
readonly a=(1 2)
# A syntax error is here:
echo "${a[#]}"
echo status $?
echo 'Bad: has not aborted execution on syntax error!'

ফলাফল:

$ ./sh-on-syntax-err 
./sh-on-syntax-err: line 6: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$ 

set -eআপনার সিনট্যাক্স ত্রুটিটি একটি ifবিবৃতিতে থাকার কারণে যথেষ্ট নয় । অন্য কোথাও স্ক্রিপ্ট বাতিল করা উচিত।
জর্ডানম

@ জর্ডানম ঠিক আছে, set -eএটি কেন কাজ হয়নি তা একটি ব্যাখ্যা হতে পারে । তবে আমার প্রশ্নটি এখনও বোধগম্য। কোনও সিনট্যাক্স ত্রুটি বাতিল করা কি সম্ভব?
ইম্জ - ইভান জ্যাচারিয়াশেভ

@ জোর্ডানম সরানো "যদি"; কোন প্রবণতা তোলে (আমার প্রশ্ন আপডেট)।
ইম্জ - ইভান জ্যাকারিয়াশেভ

উত্তর:


9

পুরোপুরি কোনও কার্যক্রমে মুড়িয়ে ফেলার জন্য কৌশলটি মনে হচ্ছে:

#!/bin/bash -e

main () {
readonly a=(1 2)
    # A syntax error is here:
    if (( "${a[#]}" == 2 )); then
        echo ok
    else
        echo not ok
    fi
    echo status $?
    echo 'Bad: has not aborted execution on syntax error!'
}

main "$@"

ফলাফল:

$ ./sh-on-syntax-err 
$ ./sh-on-syntax-err line 6: #: syntax error: operand expected (error token is "#")
$ 

যদিও আমার কোনও ধারণা নেই কেন - সম্ভবত অন্য কেউ ব্যাখ্যা করতে পারেন?


2
এখন আপনার ফাংশন সংজ্ঞা পার্স এবং মূল্যায়ন করা হয়, এবং এটি ব্যর্থ হয়।
ট্রিপলি

চমৎকার সমাধান! বিটিডাব্লু, এটিও এই ক্ষেত্রে পুরো প্রোগ্রামটি বাতিল করে দেয় না। আমি echo 'Bad2: has not aborted the execution after bad main!'আপনার উদাহরণে সর্বশেষ হিসাবে সংযুক্ত হয়েছি এবং আউটপুটটি হ'ল: C এলসি_এলএল = সি। ত্রুটি টোকেন "#") খারাপ 2: খারাপ প্রধান পরে মৃত্যুদন্ড কার্যকর করা বাতিল করে দেয় না! $
imz - ইভান জ্যাচারিয়াশেভ

তবে আমাদের কেবল তখনই একটি লাইন যুক্ত করা উচিত নয়, আমাদের সমস্ত কিছু একটি ফাংশনের ভিতরে রাখা উচিত।
ইম্জ - ইভান জ্যাকারিয়াশেভ

@ ট্রিপলি হ্যাঁ, মনে হচ্ছে এটি ফাংশনটি পার্স করা ব্যর্থ হয়েছে, সুতরাং এটি সম্পূর্ণ নয়, তবে পুরো প্রোগ্রামটি বাস্তবে এই ক্ষেত্রে বাতিল করা হয়নি (সুতরাং এটি সম্ভবত প্রস্থান-অন-ত্রুটির প্রভাব নয়)।
ইম্জ - ইভান জ্যাকারিয়াশেভ

6

আপনি সম্ভবত এর আসল অর্থ সম্পর্কে বিভ্রান্ত set -ehelp setশোগুলির আউটপুটটি যত্ন সহকারে পড়া :

-e  Exit immediately if a command exits with a non-zero status.

সুতরাং -eপ্রদর্শন করে প্রস্থান অবস্থা সম্পর্কে কমান্ড হচ্ছে নন-জিরো, আপনার স্ক্রিপ্টের মধ্যে সিনট্যাক্স ত্রুটি সম্পর্কে না।

সাধারণভাবে এটি ব্যবহার করা খারাপ অনুশীলন হিসাবে বিবেচিত হয় set -e, কারণ সমস্ত ত্রুটি (যেমন, আদেশগুলি থেকে সমস্ত শূন্য-প্রত্যাবর্তন) স্ক্রিপ্ট দ্বারা চালিতভাবে পরিচালনা করা উচিত (শক্তিশালী স্ক্রিপ্টটি মনে করুন, আপনি ফাইলের সাথে একটি ফাইলের নাম লেখার পরে বুনো হবে না স্পেস বা এটি হাইপেন দিয়ে শুরু হয়)।

সিনট্যাক্স ত্রুটির ধরণের উপর নির্ভর করে স্ক্রিপ্টটি এমনকি চালানোও হতে পারে না। সিনট্যাক্স ত্রুটিগুলির ঠিক কোন শ্রেণির (কেবল যদি সেগুলি শ্রেণিবদ্ধ করা যায়) স্ক্রিপ্টটির তাত্ক্ষণিক গর্ভপাত ঘটতে পারে বা না হতে পারে তা বলার জন্য আমি যথেষ্ট পরিমাণে জ্ঞানী নই । হয়তো কিছু বাশ গুরু যোগদান করবেন এবং সমস্ত কিছু স্পষ্ট করবেন y

আমি কেবল আশা করি আমি set -eবিবৃতিটি পরিষ্কার করে দিয়েছি !

আপনার ইচ্ছা সম্পর্কে:

আমি বোধগম্য প্রোগ্রামিং ভাষা থেকে এ জাতীয় নিরাপদ আচরণের প্রত্যাশা করেছি ... সম্ভবত এটি অবশ্যই বাগ / বিকাশকারীদের বাশ করার ইচ্ছা হিসাবে রিপোর্ট করা উচিত

উত্তর অবশ্যই না! আপনি যা পর্যবেক্ষণ করেছেন ( set -eযেমনটি আপনি প্রত্যাশা করছেন তেমন সাড়া দিচ্ছেন না) আসলে খুব ভাল নথিবদ্ধ।


আমি বোঝাতে চাইছি এই জাতীয় বৈশিষ্ট্যের অনুপস্থিতি একটি সমস্যা। আমি ফোকাস করতে চাইনি set -e- এটি আমার লক্ষ্যগুলির সামান্য কাছাকাছি, এজন্যই এখানে এটি উল্লেখ করা এবং ব্যবহৃত হয়েছে। আমার প্রশ্নটি সম্পর্কিত নয় set -e, এটি ব্যাশের অনর্থক সম্পর্কে যদি এটি সিট্যাক্স ত্রুটিগুলি বাতিল করতে না পারেন। আমি এটিকে সর্বদা সিনট্যাক্স ত্রুটিতে বাতিল করতে একটি উপায় খুঁজছি।
ইম্জ - ইভান জাখারিয়াচেভ

4

আপনি স্ক্রিপ্টটি এমন কিছু রেখে নিজেই পরীক্ষা করতে পারেন

bash -n "$0"

স্ক্রিপ্টের শীর্ষের কাছাকাছি - পরে set -eকোনও উল্লেখযোগ্য কোডের আগে।

আমার বলতে হবে এটি খুব দৃust় মনে হয় না তবে এটি যদি আপনার পক্ষে কাজ করে তবে সম্ভবত এটি গ্রহণযোগ্য।


অসাধারণ! বা, ছাড়াই set -e: bash -n "$0" || exit
ড্যানিয়েল এস

0

প্রথমত, (( ))ইন ব্যাশ পাটিগণিত গণনা হিসাবে ব্যবহৃত হয়, যদি ... এর []জন্য ব্যবহার না করে।

দ্বিতীয়ত, এটি ${a[#]}অদ্ভুত এবং এর কারণেই ত্রুটিগুলি দেওয়া হচ্ছে ... এর #কোনও অ্যারের অর্থ নেই

আপনি এটি সহ কী করতে চান তা আমি জানি না, তবে আমি ধরে নিই যে আপনি ক্ষেত্রের সংখ্যা জানতে চান, সুতরাং আপনি ${#a[*]}পরিবর্তে চান

অবশেষে, পূর্ণসংখ্যার সাথে তুলনা করার সময়, এটির -eqউপর সুপারিশ করা হয় ==(স্ট্রিংগুলির জন্য ব্যবহৃত)। ==এছাড়াও কাজ করবে, কিন্তু -eqবাঞ্ছনীয়।

তাহলে তুমি চাও:

if [ ${#a[*]} -eq 2 ]; then 

4
এটা সত্যি না. মূল ((শব্দটি সহ কীওয়ার্ডটি ব্যবহার করা সাধারণ if। উদাহরণস্বরূপ if (( 5 * $b > 53 )),। আপনি যদি পুরানো শাঁসগুলির সাথে বহনযোগ্যতার লক্ষ্য না রাখেন [[তবে সাধারণত এটি সর্বোত্তম[

2
হ্যাঁ, আমি @ ইভানের সাথে একমত - [[এবং (("যদি" ইত্যাদি ব্যবহারের জন্য হালকা ওজনের পরীক্ষার জন্য বিশেষভাবে ডিজাইন করা হয়েছিল - তার বিপরীতে [, তারা শর্তটি মূল্যায়ন করার জন্য কখনও সাব-প্রসেস স্প্যান করে না।
ইম্জ - ইভান জ্যাকারিয়াশেভ

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