লিনাক্স শেল স্ক্রিপ্ট: যদি কোনও প্রোগ্রাম উপস্থিত থাকে তবেই এটি চালান, এটি উপস্থিত না থাকলে তা এড়িয়ে যান


15

আমি একটি লিনাক্স শেল স্ক্রিপ্ট প্রোগ্রাম করছি যা কার্যকর করার সময় স্ট্যাটাস ব্যানারগুলি প্রিন্ট করবে কেবলমাত্র যদি উপযুক্ত সরঞ্জামটি বলা figletহয় তবে এটি ইনস্টল করা আছে (এটি হল: সিস্টেমের পথে পৌঁছানোর যোগ্য )।

উদাহরণ:

#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"

আমি কাজ করার জন্য আমার স্ক্রিপ্টের জন্য চাই ত্রুটি ছাড়া এমনকি যখন figletকরা হয় ইনস্টল করা নেই

ব্যবহারিক পদ্ধতি কী হতে পারে ?



@ সুদোডাস: 'ফিগলেট' (এবং এর পরামিতি) কমান্ড ঠিক হবে উপেক্ষা করা। অব্যাহত কার্যকর, অবশ্যই।
সোপালাজো ডি অ্যারিরেজ

2
এই প্রশ্নের শিরোনামটি আমাকে সব ধরণের
রূপক

2
আপনি কি সমস্ত ত্রুটি উপেক্ষা করতে চান ? শুধু ব্যবহার figlet ... || true
গিয়াকোমো আলজেটা

যদি আপনি প্রস্থান কোডগুলির বিষয়ে চিন্তা না করেন তবে একটি শর্টকাট ব্যবহার করা উচিত figlet || trueতবে আপনার ক্ষেত্রে সম্ভবত একটি শেল ফাংশন যা ইকোস প্লেইনেক্সট যদি কোনও ব্যানার প্রিন্ট করা না যায় তবে আপনি যা চান তার সম্ভাবনা বেশি থাকে।
eckes

উত্তর:


30

আমার ব্যাখ্যায় সরঞ্জাম হিসাবে একই নামে একটি মোড়ক ফাংশন ব্যবহার করা হবে; এই ফাংশনে, আসল সরঞ্জামটি উপস্থিত থাকলে তা কার্যকর করুন:

figlet() {
  command -v figlet >/dev/null && command figlet "$@"
}

তারপরে আপনি figlet arg1 arg2...আপনার স্ক্রিপ্টে অপরিবর্তিত থাকতে পারেন ।

@ অলরিন একটি সহজ পদ্ধতি নিয়ে এসেছিল: আমাদের প্রয়োজন হলে কেবল একটি র‍্যাপার ফাংশনটি সংজ্ঞায়িত করুন (যদি সরঞ্জামটি উপস্থিত না থাকে):

if ! command -v figlet > /dev/null; then figlet() { :; }; fi

যদি আপনি figletফিগলেট ইনস্টল না করা হয়েও আর্গুমেন্টগুলি মুদ্রিত হতে চান তবে ওলরিনের পরামর্শটি নীচে সামঞ্জস্য করুন:

if ! command -v figlet > /dev/null; then figlet() { printf '%s\n' "$*"; }; fi

1
কোথা commandথেকে আসে? আমার ইনস্টলেশনগুলিতে আমার এটি নেই (রেড হ্যাট 6.8 এন্টারপ্রাইজ এবং সাইগউইন 64))
ইভানকো

1
@ আইওয়ানকো, unix.stackexchange.com/a/85250/117549 দেখুন ; দীর্ঘ গল্প সংক্ষিপ্ত, এটি ব্যাশ অন্তর্নির্মিত, সম্ভবত এটি আপনার শেল।
জেফ শ্যাচলার

4
commandএকটি পসিক্স বোর্ন শেল অন্তর্নির্মিত। এটি সাধারণত প্রদত্ত কমান্ডটি কার্যকর করে, তবে -vপতাকাটি typeঅন্য শেলটি অন্তর্নির্মিত করে এটির মতো আচরণ করে ।
wyrm

@ আইয়ানকো type -a commandআপনাকে দেখিয়ে দেবে। whichহবে শুধুমাত্র আপনার এর উপর এক্সেকিউটেবল দেন $PATH, না বিল্ট-ইন, কীওয়ার্ড, ফাংশন বা উপনাম।
l0b0

@ l0b0: বাশ এবং ডিফল্ট প্রোফাইল (গুলি) এর সাথে রেডহ্যাট-পরিবারে একটি প্রযোজ্য ওরফে খুঁজে which পায় , কারণ এটি whichচালানোর /usr/bin/whichএবং এটি শেল এর এলিয়াসগুলির একটি তালিকা পাইপ করার জন্য (!) দেখা দেয় (অবশ্যই \whichউপনামটি দমন করে এবং কেবলমাত্র প্রোগ্রামটি ব্যবহার করে, যা উপাধি প্রদর্শন করে না))
dave_thompson_085

14

figletউপস্থিত আছে কিনা তা পরীক্ষা করতে পারেন

if type figlet >/dev/null 2>&1
then
    echo Figlet is installed
fi

6

এটি করার একটি সাধারণ উপায় হ'ল test -xওরফে [ -x। এখানে /etc/init.d/ntpএকটি লিনাক্স সিস্টেম থেকে নেওয়া উদাহরণ :

if [ -x /usr/bin/lockfile-create ]; then
    lockfile-create $LOCKFILE
    lockfile-touch $LOCKFILE &
    LOCKTOUCHPID="$!"
fi

এই রূপটি এক্সিকিউটেবলের পুরো পথটি জানার উপর নির্ভর করে। এর মধ্যে /bin/lesspipeআমি একটি উদাহরণ পেয়েছি যা এর চারপাশে কাজ করে -xএবং whichকমান্ডটি যুক্ত করে:

if [ -x "`which bunzip`" ]; then bunzip -c "$1"
else echo "No bunzip available"; fi ;;

এই ভাবে এই আগাম বুদ্ধিমান যেখানে ছাড়া কাজ করবে এক্সিকিউটেবল হয়।PATHbunzip


4
ব্যবহার করবেন নাwhich । এমনকি যদি whichকাজ করা test -xহয় তবে এর আউটপুটটি ব্যবহার করা নিরীহ: আপনি যদি কোনও পথ পান তবে whichতা বিদ্যমান।
গিলস 'খারাপ হয়ে যাওয়া বন্ধ করুন'

1
@ গিলস: প্রযুক্তিগতভাবে বলতে গেলে, test -xকোনও ফাইল উপস্থিত রয়েছে কিনা তা যাচাই করার চেয়ে বেশি কিছু করে না ( test -eএটিই এর জন্য)। এটিতেও ফাইলটি নির্বাহের অনুমতি সেট রয়েছে কিনা তাও পরীক্ষা করে।
comfreak

@ কমফ্রেকও তাই করে which
গিলস 'অশুভ হওয়া বন্ধ করুন'

5

আপনার স্ক্রিপ্টের শুরুতে, figletউপস্থিত আছে কিনা তা পরীক্ষা করুন এবং এটি না থাকলে শেল ফাংশনটি সংজ্ঞায়িত করুন যা কিছুই করে না:

type figlet >/dev/null 2>&1 || figlet() { :; }

typefigletশেল বিল্ট-ইন, ফাংশন, ওরফে, বা কীওয়ার্ড হিসাবে উপস্থিত রয়েছে কিনা তা পরীক্ষা করে >/dev/null 2>&1স্টিডিন এবং স্টডআউটকে বাতিল করে দেয় যাতে আপনার কোনও আউটপুট না পাওয়া যায় এবং যদি এটি উপস্থিত না থাকে তবে একটি ফাংশন হিসাবে figlet() { :; }সংজ্ঞা figletদেয় যা কিছুই করে না।

এইভাবে আপনাকে ব্যবহার করা আপনার স্ক্রিপ্টের প্রতিটি লাইন সম্পাদনা করতে হবে না figletবা প্রতিবার figletডেকে ডাকা হবে কিনা তা যাচাই করতে হবে না ।

আপনি যদি চান তবে আপনি ডায়গনিস্টিক বার্তা যুক্ত করতে পারেন:

type figlet >/dev/null 2>&1 || { echo 'figlet not installed.' ; figlet() { :; } ; }

বোনাস হিসাবে, আপনি যে শেলটি ব্যবহার করছেন তা উল্লেখ না করে, আমি বিশ্বাস করি এটি পসিক্স অনুগত, সুতরাং এটি বেশিরভাগ শেলের উপর কাজ করা উচিত।


আমি এই উত্তরের সরলতা পছন্দ করি। আপনি ব্যাশ ব্যবহার করলে এটিও প্রতিস্থাপন type figlet >/dev/null 2>&1করতে hash figlet 2>/dev/nullপারেন। (ওপি বলেছে "এটি যদি আমার পথে থাকে"))
জো

5

অন্য বিকল্প - একটি প্যাটার্ন যা আমি প্রজেক্ট অটো কনফিগার স্ক্রিপ্টগুলিতে দেখেছি:

if [ -x /usr/bin/figlet ]
then
    FIGLET=/usr/bin/figlet
else
    FIGLET=:
fi

$FIGLET "Hello, world!"

আপনার নির্দিষ্ট ক্ষেত্রে আপনি এমনকি করতে পারেন,

if [ -x /usr/bin/figlet ]
then
   SAY=/usr/bin/figlet
elif [ -x /usr/local/bin/figlet ]
then
   SAY=/usr/local/bin/figlet
elif [ -x /usr/bin/banner ]
then
   SAY=/usr/bin/banner
else
   SAY=/usr/bin/echo
fi

$SAY "Hello, world!"

আপনি যদি সুনির্দিষ্ট পথটি জানেন না, তবে আপনি elifপরিচিত স্থানগুলি চেষ্টা করতে একাধিক (উপরে দেখুন) চেষ্টা করতে পারেন , বা কেবল PATHসর্বদা আদেশটি সমাধান করতে ব্যবহার করতে পারেন:

if command -v figlet >/dev/null
then
    SAY=figlet
elif command -v banner >/dev/null
then
    SAY=banner
else
    SAY=echo
fi

সাধারণত, স্ক্রিপ্টগুলি লেখার সময়, আমি কেবলমাত্র আমার দ্বারা নির্দিষ্ট নির্দিষ্ট স্থানে কমান্ড কল করতে পছন্দ করি। শেষ ব্যবহারকারী তাদের PATHমধ্যে সম্ভবত তাদের নিজের মধ্যে কী রেখেছিল তার অনিশ্চয়তা / ঝুঁকি আমি পছন্দ করি না ~/bin

উদাহরণস্বরূপ, যদি আমি অন্যদের জন্য একটি জটিল স্ক্রিপ্ট লিখছিলাম যা যে বিশেষ কমান্ডের সাথে কল করছি তার ফলাফলের ভিত্তিতে ফাইলগুলি সরিয়ে ফেলতে পারে, তবে আমি দুর্ঘটনাক্রমে তাদের মধ্যে কিছু বাছাই করতে চাই ~/binনা যা কমান্ড হতে পারে বা নাও হতে পারে আমি আশা করেছিলাম.


3
কি হবে যদি figletছিল /usr/local/binবা /home/bob/stuff/programs/executable/figlet?
গিলস 'অসহায় হওয়া বন্ধ করুন'

3
type -p figlet > /dev/null && figlet "foo"

বাশ typeকমান্ড একটি কমান্ড, ফাংশন, ওরফে, কীওয়ার্ড, বা বিল্টিন (দেখুন help type) সন্ধান করে এবং অবস্থান বা সংজ্ঞা প্রিন্ট করে। এটি অনুসন্ধানের ফলাফলের প্রতিনিধিত্ব করে একটি রিটার্ন কোডও দেয়; সত্য (0) যদি পাওয়া যায়। সুতরাং আমরা এখানে যা করছি তা figletসেই পথটি অনুসন্ধান করার চেষ্টা করছে (তার -pঅর্থ কেবল ফাইলগুলি সন্ধান করা, বিল্ট-ইনগুলি বা ফাংশনগুলি নয়, এবং ত্রুটি বার্তাগুলিও দমন করে), আউটপুট ছাড়ছে (যা তা > /dev/nullকরে) এবং যদি এটি সত্য ফিরে আসে ( &&) , এটি কার্যকর করা হবে figlet

figletস্থির স্থানে থাকলে এটি আরও সহজ :

[ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"

এখানে আমরা testকমান্ডটি (ওরফে [) ব্যবহার করছি /usr/bin/figletএটি নির্বাহযোগ্য ( -x) এবং যদি তাই ( &&) কার্যকর হয় কিনা তা দেখতে। আমি মনে করি এই সমাধানটি ব্যবহারের চেয়ে পোর্টেবল typeযা আমি বিশ্বাস করি এটি একটি বাশিজম।

আপনি এমন একটি ফাংশন তৈরি করতে পারেন যা এটি আপনার জন্য করে:

function x() {
    if type -p "$1" >/dev/null; then
        cmd="$1"
        shift
        "$cmd" "$@"
    fi
}

(সম্ভাব্য স্থানের কারণে উদ্ধৃতিগুলি প্রয়োজনীয়)

তাহলে আপনি ঠিক করবেন:

x figlet "foo"

0

ও /, আমি এমন কিছু বলব

#!/usr/bin/env bash
# if figlet is installed :
if [ "$(which figlet 2>/dev/null)" ]; then
       # do what you wanted to do
       echo "foo"
       figlet "Starting"
       echo "moo"
       figlet "Working"
       echo "foo moo"
       figlet "Finished"
# if not
else
       # exit program with an error
       echo "please install figlet"
       exit 1
fi

0

আপনি যে কোনও আউটপুট দমন করে একটি পরীক্ষা সম্পাদন করতে পারেন এবং সাফল্য / ব্যর্থতার কোড পরীক্ষা করতে পারেন। এই পরীক্ষাটি কম ব্যয়বহুল করতে ফিগলেটে যুক্তি চয়ন করুন Choose - বা --help বা --version সুস্পষ্ট সম্ভাবনা।

if figlet --help >/dev/null 2>&1 ; then
    # figlet is available
    echo "foo"
    figlet "starting"
    #etc
else
    rc=$?
    echo "figlet is not installed or not working correctly (return code ${rc})"
fi

নীচের মন্তব্যের জবাবে যুক্ত করা হয়েছে: আপনি যদি সত্যই সেই ফলকটি বিদ্যমান বলে পরীক্ষা করতে চান তবে এটি ব্যবহারযোগ্য নয়, তবে আপনি তা করতে পারেন

figlet --help >/dev/null 2>&1 
rc=$?
if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
    echo "command figlet not found"
else
    figlet "whatever" # use figlet
fi

এখানে সমস্যাটি হ'ল ফলক ইনস্টল না হওয়া ছাড়াও কারণে ব্যর্থ হতে পারে, সুতরাং কেবলমাত্র প্রস্থান কোডটি পরীক্ষা করা যথেষ্ট নয়।
ক্রিস

আপনি যদি সত্যিই কেবল তার ইনস্টলেশনটির জন্য পরীক্ষা করতে চান তবে আপনি $?127 (আমার লিনাক্স সিস্টেমে) সমান হলে পরীক্ষা করতে চান । 127 "কমান্ড পাওয়া যায় নি"। তবে আমার চিন্তাভাবনাটি হ'ল যুক্তিযুক্ত আদেশের জন্য, যদি command --helpব্যর্থ হয় তবে ইনস্টলেশনটি যথেষ্ট পরিমাণে চাপিয়ে দেওয়া হয়েছে যাতে এটি সেখানে নাও থাকতে পারে!
নিগেল 222

1
126 হ'ল "কমান্ড পাওয়া গেল কিন্তু কার্যকর নয়", সুতরাং আপনি এর বিরুদ্ধেও পরীক্ষা করতে চান। দুর্ভাগ্যক্রমে, আপনি --helpউপলব্ধ থাকার উপর নির্ভর করতে পারবেন না । পিক্স ইউটিলিটিগুলির এটির জন্য একটিও নেই এবং পিক্সিক নির্দেশিকা আসলে এর বিরুদ্ধে প্রস্তাব দেয় । উদাহরণস্বরূপ এবং আমার সিস্টেমে একটি প্রস্থান স্থিতি at --helpদিয়ে ব্যর্থ হয় । at: invalid option -- '-'130
ক্রিস

এছাড়াও, অবশ্যই, যদি ডুমুরটি 127 স্ট্যাটাসের সাথে প্রস্থান করতে পারে তবে এটিও সমস্যা হতে পারে।
ক্রিস

126. সম্পর্কে ফেয়ার বিন্দু সর্বাধিক বিবেকী ইউটিলিটি যেমন লাইটওয়েট নিরীহ কমান্ড বিকল্প, কিছু বাছাই করা আছে -? --help --version... অথবা জানতে পারতে কি figlet -0 --illegalসঙ্গে প্রস্থান করে, এবং আচরণ আপনার সাফল্য সূচক হিসেবে (যতদিন যেমন না 127 এর, যা আমি বর্গ would নাশকতা হিসাবে)।
নিগেল 222
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.