বাশ স্ক্রিপ্টে প্যারামিটারগুলি বৈধ করা হচ্ছে


96

অনেকগুলি ফোল্ডার অপ্রয়োজনীয় হয়ে যাওয়ার কারণে অপসারণের প্রক্রিয়াটি স্বয়ংক্রিয় করতে সহায়তা করার জন্য আমি একটি বেসিকটি নিয়ে এসেছি।

#!/bin/bash
rm -rf ~/myfolder1/$1/anotherfolder
rm -rf ~/myfolder2/$1/yetanotherfolder
rm -rf ~/myfolder3/$1/thisisafolder

এটি এর মতো উদ্রেকিত হয়:

./myscript.sh <{id-number}>

সমস্যাটি হ'ল আপনি যদি টাইপ করতে ভুলে যান id-number (ঠিক তখনই আমি যেমনটি করেছি) , তবে এটি সম্ভবত মুছে ফেলার মতো অনেকগুলি জিনিস মুছতে পারে।

কমান্ড লাইন পরামিতিগুলিতে কোনও প্রকারের বৈধতা যুক্ত করার উপায় আছে কি? আমার ক্ষেত্রে এটি পরীক্ষা করা ভাল হবে যে ক) একটি প্যারামিটার রয়েছে, খ) এটি সংখ্যাসূচক এবং গ) যে ফোল্ডারটি বিদ্যমান; স্ক্রিপ্ট দিয়ে চালিয়ে যাওয়ার আগে।

উত্তর:


160
#!/bin/sh
die () {
    echo >&2 "$@"
    exit 1
}

[ "$#" -eq 1 ] || die "1 argument required, $# provided"
echo $1 | grep -E -q '^[0-9]+$' || die "Numeric argument required, $1 provided"

while read dir 
do
    [ -d "$dir" ] || die "Directory $dir does not exist"
    rm -rf "$dir"
done <<EOF
~/myfolder1/$1/anotherfolder 
~/myfolder2/$1/yetanotherfolder 
~/myfolder3/$1/thisisafolder
EOF

সম্পাদনা : ডিরেক্টরিগুলি প্রথমে উপস্থিত রয়েছে কিনা তা পরীক্ষা করার অংশটি আমি মিস করেছি, তাই আমি স্ক্রিপ্টটি সম্পূর্ণ করে এটিকে যুক্ত করেছি। এছাড়াও, মন্তব্যে উত্থাপিত বিষয়গুলিকে সম্বোধন করেছেন; নিয়মিত অভিব্যক্তি স্থির করে, থেকে সরিয়ে নেওয়া ==হয় eq

এটি যতদূর আমি বলতে পারি একটি পোর্টেবল, পসিক্স অনুগত স্ক্রিপ্ট হওয়া উচিত; এটি কোনও বাশিজম ব্যবহার করে না, যা প্রকৃতপক্ষে গুরুত্বপূর্ণ কারণ /bin/shউবুন্টুতে আসলে dashএই দিনগুলি, না bash


পূর্ণসংখ্যার তুলনার জন্য '==' এর পরিবর্তে 'ই' সেট করতে এবং 'মেরু' ব্যবহার করতে মনে রাখবেন
বন্দুকগুলি

এটি -eq এ পরিবর্তন করা হয়েছে; এখানে সেট + ই আপনাকে কেনে?
ব্রায়ান ক্যাম্পবেল 1

আমি আমার উত্তরে দুটি জিনিস পেয়েছি যা আপনি নিজের মধ্যেও ঠিক করতে চাইতে পারেন: প্রথমে এসও হিলিটারটি $ # এর জন্য পাগল হয়ে যায় (এটি একটি মন্তব্যকারী হিসাবে বিবেচনা করে)। আমি এটি ঠিক করতে "$ #" করেছি। দ্বিতীয়ত, রেজেক্সটি "foo123bar" এর সাথেও মেলে। আমি এটি ^ [0-9] + doing করে ঠিক করেছি $ আপনি
গ্রেপ-এক্স

4
@ojblass আমি যে পরীক্ষাগুলির বিষয়ে জিজ্ঞাসা করছিলাম সেগুলির মধ্যে সে অনুপস্থিত ছিল। এটি যুক্ত করার অর্থ তার ডিরেক্টরিগুলির বিরুদ্ধে পরীক্ষা করার জন্য যুক্ত করা যা উত্তরের আকারটি উল্লেখযোগ্যভাবে প্রসারিত করায় যেহেতু তারা এক লাইনে ফিট করতে পারে না। আপনি প্রতিটি ডিরেক্টরি অস্তিত্ব জন্য পরীক্ষা আরও কমপ্যাক্ট উপায় প্রস্তাব করতে পারেন?
ব্রায়ান ক্যাম্পবেল

4
নীচে @ মর্টেন নীলসনের উত্তর-মন্তব্য অনুসারে গ্রেপ '$ [0-9] +।' সত্যই অদ্ভুত দেখাচ্ছে। এটি '^ [0-9] + $' হওয়া উচিত নয়?
মার্টিন জাকুবিক

21

মহৎ এবং কার্যকরভাবে চালিত হওয়ার সময় এর shসমাধানটিতে Brian Campbellকয়েকটি সমস্যা রয়েছে, তাই আমি ভেবেছিলাম আমি নিজের bashসমাধানটি সরবরাহ করব।

shএকের সাথে সমস্যাগুলি :

  • টিলড ~/fooহাইড্রোকসের অভ্যন্তরে আপনার হোম ডিরেক্টরিতে প্রসারিত হয় না। এবং যখনই এটি readবিবৃতি দ্বারা পড়া হয় না বা বিবৃতিতে উদ্ধৃত হয় rm। যার অর্থ আপনি No such file or directoryত্রুটি পাবেন।
  • grepবেসিক অপারেশনগুলির জন্য ফোরকিং অফ করা এবং মূর্খতা। বিশেষত যখন আপনি বাশকের "ভারী" ওজন এড়াতে ক্রেপি শেল ব্যবহার করছেন।
  • আমি কয়েকটি উদ্ধৃতিযুক্ত বিষয়গুলিও লক্ষ্য করেছি, উদাহরণস্বরূপ তার মধ্যে একটি প্যারামিটার বিস্তৃতি ঘিরে echo
  • বিরল হলেও, সমাধানটি নতুন ফাইলগুলি ধারণ করে এমন ফাইলের নামগুলির সাথে লড়াই করতে পারে না। (প্রায় কোনও সমাধানই shসেগুলি মোকাবেলা করতে পারে না - এজন্য আমি প্রায় সবসময়ই পছন্দ করি bash, এটি ব্যবহারের চেয়ে আরও বেশি বুলেটপ্রুফ এবং শোষণ করা আরও শক্ত)।

হ্যাঁ, /bin/shআপনার হ্যাশবাংয়ের জন্য ব্যবহারের অর্থ আপনাকে সর্বদা ব্যয়বহুল এড়িয়ে চলতে bashহবে, আপনি bashউবুন্টুতে বা যখন সৎ #!/bin/bashথাকবেন এবং শীর্ষে রাখবেন তখনও আপনি আপনার পছন্দসই সমস্ত বিষয় ব্যবহার করতে পারেন ।

সুতরাং, এখানে এমন একটি bashসমাধান রয়েছে যা ছোট, পরিষ্কার, আরও স্বচ্ছ, সম্ভবত "দ্রুত" এবং আরও বুলেটপ্রুফ।

[[ -d $1 && $1 != *[^0-9]* ]] || { echo "Invalid input." >&2; exit 1; }
rm -rf ~/foo/"$1"/bar ...
  1. লক্ষ্য করুন কোট প্রায় $1মধ্যে rmবক্তব্য!
  2. -dযদি চেক এছাড়াও ব্যর্থ হবে $1খালি থাকে, যাতে এক এর ভিতর দুই চেক আছে।
  3. আমি কোনও কারণে নিয়মিত অভিব্যক্তি এড়িয়ে চলি। আপনার যদি অবশ্যই =~ব্যাশে ব্যবহার করা হয় তবে আপনার নিয়মিত এক্সপ্রেশনটি একটি চলকতে রাখা উচিত putting যাই হোক না কেন, আমার মতো গ্লোবগুলি বরাবরই পছন্দসই এবং আরও অনেক বেশি সংস্করণে সমর্থিত।

4
তাহলে গ্লোব্বিং টুকরা $1 != *[^0-9]*বাশ কি তখন নির্দিষ্ট?
গ্রিঞ্চ


13

উপরের উত্তরের মতো বুলেটপ্রুফ নয়, তবে এখনও কার্যকর:

#!/bin/bash
if [ "$1" = "" ]
then
  echo "Usage: $0 <id number to be cleaned up>"
  exit
fi

# rm commands go here

11

set -uস্ক্রিপ্টটি তাত্ক্ষণিকভাবে ব্যর্থ করতে যে কোনও অনসেট আর্গুমেন্ট রেফারেন্সের কারণ হিসাবে ব্যবহার করুন ।

: দয়া করে, নিবন্ধটি দেখুন - ডেভিড Pashley.com শক্তসমর্থ ব্যাশ শেল স্ক্রিপ্ট লেখা


এটি অনেক ক্ষেত্রে একটি দুর্দান্ত সহজ ফিক্স এবং ফাংশনগুলির জন্যও কাজ করে। ধন্যবাদ!
মানফ্রেড মজার

9

পরীক্ষার জন্য ম্যান পেজটি man testসমস্ত উপলভ্য অপারেটরগুলি সরবরাহ করে যা আপনি ব্যাশে বুলিয়ান অপারেটর হিসাবে ব্যবহার করতে পারেন। আপনার স্ক্রিপ্টের শুরুতে (বা ফাংশনগুলি) সেই পতাকাগুলি যেমন আপনি অন্য কোনও প্রোগ্রামিং ভাষায় করতে চান ঠিক তেমনভাবে ইনপুট বৈধতার জন্য ব্যবহার করুন। উদাহরণ স্বরূপ:

if [ -z $1 ] ; then
  echo "First parameter needed!" && exit 1;
fi

if [ -z $2 ] ; then
  echo "Second parameter needed!" && exit 2;
fi

8

ফাঁকা স্ট্রিংগুলির পরীক্ষা করতে '-z' এবং ডিরেক্টরিগুলি পরীক্ষা করতে '-d' ব্যবহার করুন।

if [[ -z "$@" ]]; then
    echo >&2 "You must supply an argument!"
    exit 1
elif [[ ! -d "$@" ]]; then
    echo >&2 "$@ is not a valid directory!"
    exit 1
fi

4
আপনার দ্বিগুণ [[]] দরকার কেন?
যানজমজ

5

আপনি নীচের মতো কিছু করে বিন্দু a এবং b কে বৈধতা দিতে পারেন:

#!/bin/sh
MYVAL=$(echo ${1} | awk '/^[0-9]+$/')
MYVAL=${MYVAL:?"Usage - testparms <number>"}
echo ${MYVAL}

যা আমাদের দেয় ...

$ ./testparams.sh 
Usage - testparms <number>

$ ./testparams.sh 1234
1234

$ ./testparams.sh abcd
Usage - testparms <number>

এই পদ্ধতিটি sh এ সূক্ষ্মভাবে কাজ করা উচিত।


2

এক লাইনার বাশ যুক্তির বৈধতা, ডিরেক্টরি বৈধতা সহ এবং ছাড়াই

এখানে কিছু পদ্ধতি যা আমার পক্ষে কাজ করেছে। আপনি এগুলিকে গ্লোবাল স্ক্রিপ্ট নেমস্পেসে ব্যবহার করতে পারেন (যদি বিশ্বব্যাপী নেমস্পেসে থাকে তবে আপনি ফাংশন বিল্টিন ভেরিয়েবলগুলি উল্লেখ করতে পারবেন না)

দ্রুত এবং নোংরা একটি লাইনার

: ${1?' You forgot to supply a directory name'}

আউটপুট:

./my_script: line 279: 1: You forgot to supply a directory name

ফ্যানসিয়ার - ফাংশনটির নাম এবং ব্যবহার সরবরাহ করুন supply

${1? ERROR Function: ${FUNCNAME[0]}() Usage: " ${FUNCNAME[0]} directory_name"}

আউটপুট:

./my_script: line 288: 1:  ERROR Function: deleteFolders() Usage:  deleteFolders directory_name

আপনার বর্তমান ফাংশন বিশৃঙ্খলা ছাড়াই জটিল বৈধতা যুক্তি যুক্ত করুন

যুক্তিটি গ্রহণ করে এমন ফাংশন বা স্ক্রিপ্টের মধ্যে নিম্নলিখিত লাইনটি যুক্ত করুন।

: ${1?'forgot to supply a directory name'} && validate $1 || die 'Please supply a valid directory'

তারপরে আপনি একটি বৈধতা ফাংশন তৈরি করতে পারেন যা এর মতো কিছু করে

validate() {

    #validate input and  & return 1 if failed, 0 if succeed
    if [[ ! -d "$1" ]]; then
        return 1
    fi
}

এবং একটি ডাই ফাংশন যা ব্যর্থতার উপরে স্ক্রিপ্টটি বাতিল করে

die() { echo "$*" 1>&2 ; exit 1; }

অতিরিক্ত যুক্তিগুলির জন্য, বিন্যাসটির অনুলিপি করে কেবল একটি অতিরিক্ত লাইন যুক্ত করুন।

: ${1?' You forgot to supply the first argument'}
: ${2?' You forgot to supply the second argument'}

1

পুরানো পোস্ট তবে আমি অনুভব করেছি যেভাবেই আমি অবদান রাখতে পারি।

একটি স্ক্রিপ্ট তর্কযোগ্যভাবে প্রয়োজনীয় নয় এবং কিছুটা সহ্য করার সাথে ওয়াইল্ড কার্ড কমান্ড লাইন থেকে চালানো যেতে পারে।

  1. বন্য কোথাও মিলছে। সাব "ফোল্ডার" এর যে কোনও উপস্থিতি সরাতে দেয়

    $ rm -rf ~/*/folder/*
    
  2. শেল পুনরাবৃত্তি। এক লাইনের সাথে নির্দিষ্ট পূর্ব এবং পোস্ট ফোল্ডারগুলি সরাতে দেয়

    $ rm -rf ~/foo{1,2,3}/folder/{ab,cd,ef}
    
  3. শেল পুনরাবৃত্তি + ভার (BASH পরীক্ষিত)।

    $ var=bar rm -rf ~/foo{1,2,3}/${var}/{ab,cd,ef}
    
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.