শেল স্ক্রিপ্টগুলির জন্য নিদর্শনগুলি বা সেরা অনুশীলনগুলি [বন্ধ]


167

শেল স্ক্রিপ্টগুলির জন্য সর্বোত্তম অনুশীলনগুলি বা নকশার নকশাগুলির বিষয়ে কথা বলা এমন কোনও সংস্থান সম্পর্কে কি কেউ জানেন?


2
আমি গতকাল রাতে BASH তে টেমপ্লেট প্যাটার্ন নিয়ে একটি সামান্য নিবন্ধ লিখেছিলাম । আপনি কি মনে করেন দেখুন।
কুইকশিফ্টিন

উত্তর:


222

আমি বেশ জটিল শেল স্ক্রিপ্ট লিখেছিলাম এবং আমার প্রথম পরামর্শটি "না"। কারণটি হ'ল একটি ছোট্ট ভুল করা মোটামুটি সহজ যা আপনার স্ক্রিপ্টকে বাধা দেয় এমনকি বিপজ্জনকও করে তোলে।

এটি বলেছিল, আপনাকে পাস করার মতো আমার কাছে অন্য সম্পদ নেই তবে আমার ব্যক্তিগত অভিজ্ঞতা। এখানে কি আমি সাধারণত যা Overkill, কিন্তু কঠিন হতে থাকে না, যদিও, হয় খুব বাগাড়ম্বরপূর্ণ।

আবাহন

আপনার স্ক্রিপ্ট দীর্ঘ এবং সংক্ষিপ্ত বিকল্প গ্রহণ করতে। সতর্কতা অবলম্বন করুন কারণ বিকল্পগুলি পার্স করার দুটি আদেশ রয়েছে, গোটোপট এবং গিওপ্টস। আপনি যেমন কম ঝামেলার মুখোমুখি হন তেমন ব্যবহার করুন।

CommandLineOptions__config_file=""
CommandLineOptions__debug_level=""

getopt_results=`getopt -s bash -o c:d:: --long config_file:,debug_level:: -- "$@"`

if test $? != 0
then
    echo "unrecognized option"
    exit 1
fi

eval set -- "$getopt_results"

while true
do
    case "$1" in
        --config_file)
            CommandLineOptions__config_file="$2";
            shift 2;
            ;;
        --debug_level)
            CommandLineOptions__debug_level="$2";
            shift 2;
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "$0: unparseable option $1"
            EXCEPTION=$Main__ParameterException
            EXCEPTION_MSG="unparseable option $1"
            exit 1
            ;;
    esac
done

if test "x$CommandLineOptions__config_file" == "x"
then
    echo "$0: missing config_file parameter"
    EXCEPTION=$Main__ParameterException
    EXCEPTION_MSG="missing config_file parameter"
    exit 1
fi

আর একটি গুরুত্বপূর্ণ বিষয় হ'ল কোনও প্রোগ্রামের সর্বদা শূন্য ফিরে আসা উচিত যদি সফলভাবে সম্পূর্ণ হয় তবে কিছু ভুল হয়ে থাকলে শূন্য নয়।

ফাংশন কল

আপনি ব্যাশে ফাংশনগুলি কল করতে পারেন, কেবল কল করার আগে সেগুলি সংজ্ঞায়িত করতে ভুলবেন না। ফাংশনগুলি স্ক্রিপ্টগুলির মতো হয়, তারা কেবল সংখ্যাসম্যকেই ফিরিয়ে দিতে পারে। এর অর্থ হ'ল স্ট্রিংয়ের মানগুলি ফেরত দেওয়ার জন্য আপনাকে একটি ভিন্ন কৌশল উদ্ভাবন করতে হবে। আমার কৌশলটি ফলাফল সংরক্ষণের জন্য RESULT নামক একটি ভেরিয়েবল ব্যবহার করা এবং যদি ফাংশনটি পরিষ্কারভাবে সম্পন্ন হয় তবে 0 এ ফিরে আসছেন। এছাড়াও, আপনি যদি শূন্যের চেয়ে আলাদা কোনও মান ফিরিয়ে দিচ্ছেন তবে আপনি ব্যতিক্রম বাড়াতে পারেন এবং তারপরে দুটি "ব্যতিক্রমী ভেরিয়েবল" (খনি: এক্সেসিপশন এবং এক্সেসিপশন_এমএসজি) সেট করুন, প্রথমটি ব্যতিক্রমের ধরণ এবং দ্বিতীয়টি একটি মানব পাঠযোগ্য বার্তা।

আপনি যখন কোনও ফাংশন কল করেন তখন ফাংশনের প্যারামিটারগুলি বিশেষ ওয়ার্স $ 0, $ 1 ইত্যাদির জন্য বরাদ্দ করা হয় I স্থানীয় হিসাবে ফাংশনটির ভিতরে ভেরিয়েবলগুলি ঘোষণা করুন:

function foo {
   local bar="$0"
}

ত্রুটি প্রবণ পরিস্থিতি

ব্যাশে, যদি আপনি অন্যথায় ঘোষণা না করেন, একটি আনসেট ভেরিয়েবলটি খালি স্ট্রিং হিসাবে ব্যবহৃত হয়। টাইপোর ক্ষেত্রে এটি অত্যন্ত বিপজ্জনক, কারণ খারাপভাবে টাইপ করা ভেরিয়েবলটি রিপোর্ট করা হবে না এবং এটি খালি হিসাবে মূল্যায়ন করা হবে। ব্যবহার

set -o nounset

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

if test "x${foo:-notset}" == "xnotset"
then
    echo "foo not set"
fi

আপনি ভেরিয়েবলগুলি কেবলমাত্র পঠন হিসাবে ঘোষণা করতে পারেন:

readonly readonly_var="foo"

modularization

আপনি যদি নিম্নলিখিত কোডটি ব্যবহার করেন তবে আপনি "পাইথনের মতো" মডুলারাইজেশন অর্জন করতে পারেন:

set -o nounset
function getScriptAbsoluteDir {
    # @description used to get the script path
    # @param $1 the script $0 parameter
    local script_invoke_path="$1"
    local cwd=`pwd`

    # absolute path ? if so, the first character is a /
    if test "x${script_invoke_path:0:1}" = 'x/'
    then
        RESULT=`dirname "$script_invoke_path"`
    else
        RESULT=`dirname "$cwd/$script_invoke_path"`
    fi
}

script_invoke_path="$0"
script_name=`basename "$0"`
getScriptAbsoluteDir "$script_invoke_path"
script_absolute_dir=$RESULT

function import() { 
    # @description importer routine to get external functionality.
    # @description the first location searched is the script directory.
    # @description if not found, search the module in the paths contained in $SHELL_LIBRARY_PATH environment variable
    # @param $1 the .shinc file to import, without .shinc extension
    module=$1

    if test "x$module" == "x"
    then
        echo "$script_name : Unable to import unspecified module. Dying."
        exit 1
    fi

    if test "x${script_absolute_dir:-notset}" == "xnotset"
    then
        echo "$script_name : Undefined script absolute dir. Did you remove getScriptAbsoluteDir? Dying."
        exit 1
    fi

    if test "x$script_absolute_dir" == "x"
    then
        echo "$script_name : empty script path. Dying."
        exit 1
    fi

    if test -e "$script_absolute_dir/$module.shinc"
    then
        # import from script directory
        . "$script_absolute_dir/$module.shinc"
    elif test "x${SHELL_LIBRARY_PATH:-notset}" != "xnotset"
    then
        # import from the shell script library path
        # save the separator and use the ':' instead
        local saved_IFS="$IFS"
        IFS=':'
        for path in $SHELL_LIBRARY_PATH
        do
            if test -e "$path/$module.shinc"
            then
                . "$path/$module.shinc"
                return
            fi
        done
        # restore the standard separator
        IFS="$saved_IFS"
    fi
    echo "$script_name : Unable to find module $module."
    exit 1
} 

তারপরে আপনি এক্সটেনশন সহ ফাইলগুলি আমদানি করতে পারেন following নিম্নলিখিত সিনট্যাক্সের সাথে সংযোগ করুন

"আমোডুল / মডিউলফাইল" আমদানি করুন

যা SHELL_LIBRARY_PATH এ অনুসন্ধান করা হবে। আপনি সর্বদা বিশ্বব্যাপী নেমস্পেসে আমদানি করার সময়, আপনার সমস্ত ক্রিয়াকলাপ এবং ভেরিয়েবলগুলি একটি উপসর্গের সাথে উপসর্গ করা মনে রাখবেন, অন্যথায় আপনি নামের সংঘর্ষের ঝুঁকি নিয়ে থাকেন। আমি পাইথন ডট হিসাবে ডাবল আন্ডারস্কোর ব্যবহার করি।

এছাড়াও, এটি আপনার মডিউলে প্রথম জিনিস হিসাবে রাখুন

# avoid double inclusion
if test "${BashInclude__imported+defined}" == "defined"
then
    return 0
fi
BashInclude__imported=1

অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং

বাশে, আপনি অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং করতে পারবেন না, যদি না আপনি অবজেক্টের বরাদ্দের একটি জটিল পদ্ধতি তৈরি করেন (আমি এটি সম্পর্কে ভেবেছিলাম it's এটি সম্ভব, তবে উন্মাদ)। অনুশীলনে, আপনি "সিঙ্গেলটন ওরিয়েন্টেড প্রোগ্রামিং" করতে পারেন: আপনার প্রতিটি বস্তুর একটি উদাহরণ রয়েছে এবং কেবল একটি।

আমি যা করি তা হ'ল: আমি কোনও বস্তুকে মডিউলটিতে সংজ্ঞায়িত করি (মডিউলাইজেশন এন্ট্রি দেখুন)। তারপরে আমি খালি ভারগুলি (সদস্য ভেরিয়েবলের সাথে সমতুল্য) একটি init ফাংশন (কনস্ট্রাক্টর) এবং সদস্য ফাংশন সংজ্ঞায়িত করি, যেমন এই উদাহরণ কোডের মতো

# avoid double inclusion
if test "${Table__imported+defined}" == "defined"
then
    return 0
fi
Table__imported=1

readonly Table__NoException=""
readonly Table__ParameterException="Table__ParameterException"
readonly Table__MySqlException="Table__MySqlException"
readonly Table__NotInitializedException="Table__NotInitializedException"
readonly Table__AlreadyInitializedException="Table__AlreadyInitializedException"

# an example for module enum constants, used in the mysql table, in this case
readonly Table__GENDER_MALE="GENDER_MALE"
readonly Table__GENDER_FEMALE="GENDER_FEMALE"

# private: prefixed with p_ (a bash variable cannot start with _)
p_Table__mysql_exec="" # will contain the executed mysql command 

p_Table__initialized=0

function Table__init {
    # @description init the module with the database parameters
    # @param $1 the mysql config file
    # @exception Table__NoException, Table__ParameterException

    EXCEPTION=""
    EXCEPTION_MSG=""
    EXCEPTION_FUNC=""
    RESULT=""

    if test $p_Table__initialized -ne 0
    then
        EXCEPTION=$Table__AlreadyInitializedException   
        EXCEPTION_MSG="module already initialized"
        EXCEPTION_FUNC="$FUNCNAME"
        return 1
    fi


    local config_file="$1"

      # yes, I am aware that I could put default parameters and other niceties, but I am lazy today
      if test "x$config_file" = "x"; then
          EXCEPTION=$Table__ParameterException
          EXCEPTION_MSG="missing parameter config file"
          EXCEPTION_FUNC="$FUNCNAME"
          return 1
      fi


    p_Table__mysql_exec="mysql --defaults-file=$config_file --silent --skip-column-names -e "

    # mark the module as initialized
    p_Table__initialized=1

    EXCEPTION=$Table__NoException
    EXCEPTION_MSG=""
    EXCEPTION_FUNC=""
    return 0

}

function Table__getName() {
    # @description gets the name of the person 
    # @param $1 the row identifier
    # @result the name

    EXCEPTION=""
    EXCEPTION_MSG=""
    EXCEPTION_FUNC=""
    RESULT=""

    if test $p_Table__initialized -eq 0
    then
        EXCEPTION=$Table__NotInitializedException
        EXCEPTION_MSG="module not initialized"
        EXCEPTION_FUNC="$FUNCNAME"
        return 1
    fi

    id=$1

      if test "x$id" = "x"; then
          EXCEPTION=$Table__ParameterException
          EXCEPTION_MSG="missing parameter identifier"
          EXCEPTION_FUNC="$FUNCNAME"
          return 1
      fi

    local name=`$p_Table__mysql_exec "SELECT name FROM table WHERE id = '$id'"`
      if test $? != 0 ; then
        EXCEPTION=$Table__MySqlException
        EXCEPTION_MSG="unable to perform select"
        EXCEPTION_FUNC="$FUNCNAME"
        return 1
      fi

    RESULT=$name
    EXCEPTION=$Table__NoException
    EXCEPTION_MSG=""
    EXCEPTION_FUNC=""
    return 0
}

ফাঁদে ফেলা এবং সংকেতগুলি পরিচালনা করা

আমি ব্যতিক্রমগুলি ধরতে এবং পরিচালনা করতে এটি দরকারী বলে মনে করেছি।

function Main__interruptHandler() {
    # @description signal handler for SIGINT
    echo "SIGINT caught"
    exit
} 
function Main__terminationHandler() { 
    # @description signal handler for SIGTERM
    echo "SIGTERM caught"
    exit
} 
function Main__exitHandler() { 
    # @description signal handler for end of the program (clean or unclean). 
    # probably redundant call, we already call the cleanup in main.
    exit
} 

trap Main__interruptHandler INT
trap Main__terminationHandler TERM
trap Main__exitHandler EXIT

function Main__main() {
    # body
}

# catch signals and exit
trap exit INT TERM EXIT

Main__main "$@"

নির্দেশনা ও সহযোগিতা

যদি কোনও কারণে কিছু কাজ না করে তবে কোডটি পুনরায় অর্ডার করার চেষ্টা করুন। অর্ডার গুরুত্বপূর্ণ এবং সর্বদা স্বজ্ঞাত নয়।

এমনকি tcsh দিয়ে কাজ করা বিবেচনা করবেন না। এটি কার্যকারিতা সমর্থন করে না এবং সাধারণভাবে এটি ভয়াবহ।

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


7
বাহ, এবং আমি ভেবেছিলাম যে আমি বাশকে ওভারকিলের জন্য যাচ্ছি ... আমি বিচ্ছিন্ন ফাংশন এবং অপব্যবহারের সাবস্কেলগুলি ব্যবহার করার প্রবণতা রাখি (গতিটি কোনওভাবেই প্রাসঙ্গিক হলে আমি এটাই ভোগ করি)। কখনও বৈশ্বিক চলক নেই, না হয় বা বাইরেও নয় (বিড়ম্বনার অবশেষ সংরক্ষণের জন্য)। Stdout বা ফাইল আউটপুট মাধ্যমে সমস্ত রিটার্ন। set -u / set -e (খুব খারাপ সেট-ই প্রথম হলেই অকেজো হয়ে যায় এবং আমার কোডের বেশিরভাগ ক্ষেত্রে সেখানে থাকে)। [স্থানীয় কিছু = "$ 1" দিয়ে নেওয়া ফাংশন আর্গুমেন্ট; শিফট] (রিফ্যাক্টর করার সময় সহজ পুনর্নির্মাণের অনুমতি দেয়)। এক পরে 3000 লাইনের বাশ স্ক্রিপ্ট আমি এই ফ্যাশনে এমনকি ক্ষুদ্রতম স্ক্রিপ্টগুলিও লিখতে চাই ...
ইউজিন

মডুলারাইজেশনের জন্য ছোট সংশোধনগুলি: 1 আপনার পরে একটি রিটার্ন দরকার। অনুপস্থিত সতর্কতা এড়াতে "$ স্ক্রিপ্ট_অবসুলিউট_ডির / $ মডিউল.শিংক"। 2 আপনাকে অবশ্যই FS SHELL_LIBRARY_PATH
ডাফ

"মানবিক কারণ" সবচেয়ে খারাপ বিষয়। আপনি যখন আরও ভাল কিছু দেবেন তখন মেশিনগুলি আপনার সাথে লড়াই করে না।
jeremyjjbrown

1
কেন getoptবনাম getopts? getoptsআরও পোর্টেবল এবং কোনও পসিক্স শেলের কাজ করে। বিশেষত যেহেতু প্রশ্নটি বিশেষত সর্বোত্তম অভ্যাসগুলিকে বাশানোর পরিবর্তে শেল সেরা অনুশীলন , তাই আমি যখন সম্ভব তখন একাধিক শেলকে সমর্থন করার জন্য পসিক্স সম্মতিটিকে সমর্থন করব।
ওয়াইমাটিকা

1
শেল স্ক্রিপ্টিংয়ের জন্য সমস্ত পরামর্শ দেওয়ার জন্য ধন্যবাদ যদি আপনি সত্যবাদী হন: "আশা করি এটি সাহায্য করবে, তবে দয়া করে মনে রাখবেন I আমি এখানে যে ধরনের জিনিস লিখেছি তা যদি আপনার ব্যবহার করতে হয় তবে এর অর্থ হল যে আপনার সমস্যাটি সমাধান করা খুব জটিল means শেল। অন্য ভাষা ব্যবহার করুন। মানবিক কারণ এবং উত্তরাধিকারের কারণে আমাকে এটি ব্যবহার করতে হয়েছিল। "
dieHellste

25

কটাক্ষপাত উন্নত ব্যাশ-স্ক্রিপ্টিং গাইড শেল স্ক্রিপ্টিং জ্ঞান অনেক জন্য - না শুধু ব্যাশ, হয়।

অন্যান্য, তর্কযোগ্যভাবে আরও জটিল ভাষাগুলি দেখার জন্য আপনাকে বলছে এমন লোকদের কথা শুনবেন না। শেল স্ক্রিপ্টিং যদি আপনার চাহিদা পূরণ করে তবে এটি ব্যবহার করুন। আপনি সার্থকতা নয়, কার্যকারিতা চান। নতুন ভাষাগুলি আপনার জীবনবৃত্তান্তের জন্য মূল্যবান নতুন দক্ষতা সরবরাহ করে, তবে আপনার যদি এমন কাজ করার প্রয়োজন হয় যা আপনি ইতিমধ্যে শেল জানেন তবে তা কার্যকর হয় না।

যেমন বলা হয়েছে, শেল স্ক্রিপ্টিংয়ের জন্য অনেকগুলি "সেরা অনুশীলন" বা "নকশার ধরণ" নেই। বিভিন্ন প্রোগ্রামিং ভাষার মতো - বিভিন্ন ব্যবহারের বিভিন্ন নির্দেশিকা এবং পক্ষপাত রয়েছে।


9
মনে রাখবেন যে এমনকি সামান্য জটিলতার স্ক্রিপ্টগুলির জন্য, এটি সর্বোত্তম অনুশীলন নয়। কোডিং কেবল কিছু কাজ পাওয়ার কথা নয়। এটি দ্রুত, সহজেই এটি তৈরির বিষয়ে এবং এটি নির্ভরযোগ্য, পুনরায় ব্যবহারযোগ্য এবং পড়া এবং বজায় রাখা সহজ (বিশেষত অন্যদের জন্য)। শেল স্ক্রিপ্টগুলি কোনও স্তরে ভাল স্কেল করে না। আরও দৃust় ভাষা যে কোনও যুক্তিযুক্ত প্রকল্পগুলির জন্য অনেক সহজ।
প্রবাহতাড়িত

20

শেল স্ক্রিপ্ট ফাইল এবং প্রক্রিয়াগুলি পরিচালনা করার জন্য ডিজাইন করা একটি ভাষা। যদিও এটির জন্য এটি দুর্দান্ত, যদিও এটি কোনও সাধারণ উদ্দেশ্য ভাষা নয়, তাই সর্বদা শেল স্ক্রিপ্টে নতুন যুক্তি পুনরায় তৈরি করার পরিবর্তে বিদ্যমান ইউটিলিটিগুলি থেকে যুক্তিকে আটকানোর চেষ্টা করুন।

এই সাধারণ নীতি বাদে আমি কিছু সাধারণ শেল স্ক্রিপ্ট ভুল সংগ্রহ করেছি ।



11

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

শেলের সবচেয়ে বড় সমস্যাটি হ'ল প্রায়শই শেষ ফলাফলটি কেবল কাদা একটি বড় বলের মতো দেখায়, 4000 লাইন ব্যাশ এবং ক্রমবর্ধমান ... এবং আপনি এ থেকে মুক্তি পেতে পারবেন না কারণ এখন আপনার পুরো প্রকল্প এটির উপর নির্ভর করে। অবশ্যই এটি সুন্দর বাশের 40 টি লাইনে শুরু হয়েছিল


9

সহজ: শেল স্ক্রিপ্টগুলির পরিবর্তে অজগর ব্যবহার করুন। আপনার প্রয়োজনীয় কিছু জটিল না করে এবং আপনার স্ক্রিপ্টের কিছু অংশগুলি ফাংশন, অবজেক্টস, অবিচ্ছিন্ন অবজেক্ট (জডব), ডিস্ট্রিবিউটেড অবজেক্টস (পাইরো) তে প্রায় কোনও ছাড়াই আপনি পাঠযোগ্যতার মধ্যে প্রায় 100 গুণ বৃদ্ধি পাবেন get অতিরিক্ত কোড


7
আপনি "জটিলতা না করে" বলে এবং তারপরে বিভিন্ন জটিলতার যে আপনি মূল্য যুক্ত করেন বলে তালিকাভুক্ত করে নিজের সাথে বিরোধিতা করেন, বেশিরভাগ ক্ষেত্রে সমস্যা এবং বাস্তবায়নকে সহজ করার পরিবর্তে কুৎসিত দানবগুলিতে গালি দেওয়া হয়।
ইভজেনি

3
এটি একটি দুর্দান্ত অসুবিধা প্রকাশ করে, অজগর উপস্থিত নেই এমন সিস্টেমে আপনার স্ক্রিপ্টগুলি পোর্টেবল হবে না
অ্যাস্ট্রোপ্যানিক

1
আমি বুঝতে পারি যে এটির উত্তর '08-এ দেওয়া হয়েছিল (এটি এখন '12 এর আগে দু'দিন আগে); যাইহোক, এই বছরগুলিতে পরে যারা খুঁজছেন তাদের জন্য আমি পাইথন বা রুবির মতো ভাষার দিকে মুখ ফিরিয়ে নেওয়ার বিষয়ে কাউকে সতর্ক করব কারণ এটি উপলব্ধ more । আপনার যদি আরও বহনযোগ্যতার প্রয়োজন হয় তবে জাভাতে আপনার প্রোগ্রামটি লেখার বিষয়ে ভাবুন কারণ আপনি এমন একটি মেশিন সন্ধান করতে কঠোর চাপবেন যা একটি জেভিএম উপলব্ধ নেই।
উইল মুর তৃতীয়

আজকাল পাইথনের সাথে সমস্ত বিস্তৃত লিনাক্সের প্যাস্টিকগুলি খুব সুন্দর
পিথিকোস

পাইথিকস, নিশ্চিত, এবং পাইথন 2 বনাম পাইথন 3 এর ঝামেলা সহ ফিডল। আজকাল আমি যেতে আমার সমস্ত সরঞ্জাম লিখি, এবং বেশি খুশি হতে পারে না।
জ্যোতির্বিজ্ঞানী

9

সেট-ই ব্যবহার করুন যাতে ত্রুটির পরে আপনি এগিয়ে লাঙল না। আপনি যদি এটি নন-লিনাক্সে চালিত করতে চান তবে ব্যাশের উপর নির্ভর না করে এটিকে sh উপযোগী করার চেষ্টা করুন।


7

কিছু "সেরা অনুশীলন" সন্ধানের জন্য, দেখুন লিনাক্স ডিস্ট্রোর (উদাহরণস্বরূপ দেবিয়ান) কীভাবে তাদের init-স্ক্রিপ্টগুলি লিখবে (সাধারণত /etc/init.d তে পাওয়া যায়)

তাদের বেশিরভাগই "বাশ-আইএসএস" ছাড়াই এবং কনফিগারেশন সেটিংস, গ্রন্থাগার-ফাইল এবং উত্স বিন্যাসের ভাল বিভাজন রয়েছে।

আমার ব্যক্তিগত স্টাইলটি হ'ল একটি মাস্টার-শেলসক্রিপ্ট লিখুন যা কিছু ডিফল্ট ভেরিয়েবলগুলি সংজ্ঞায়িত করে এবং তারপরে ("উত্স") একটি কনফিগারেশন ফাইল লোড করার চেষ্টা করে যাতে নতুন মান থাকতে পারে।

আমি ফাংশনগুলি এড়াতে চেষ্টা করি কারণ তারা স্ক্রিপ্টটিকে আরও জটিল করে তোলে। (পার্লকে সে উদ্দেশ্যে তৈরি করা হয়েছিল।)

স্ক্রিপ্টটি পোর্টেবল কিনা তা নিশ্চিত করার জন্য, কেবল #! / Bin / sh দিয়েই পরীক্ষা করুন না, তবে #! / Bin / ছাই, #! / বিন / ড্যাশ ইত্যাদি ব্যবহার করুন আপনি খুব শীঘ্রই বাশ নির্দিষ্ট কোডটি সন্ধান করতে পারবেন।


-1

অথবা জোওও যা বলেছে তার মতো পুরানো উক্তি:

"পার্ল ব্যবহার করুন b আপনি বাশ জানতে চাইবেন তবে এটি ব্যবহার করবেন না।"

দুঃখের সাথে আমি ভুলে গিয়েছিলাম যে কে বলেছে।

এবং হ্যাঁ আজকাল আমি পার্লের ওপরে অজগরকে সুপারিশ করব।

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