নীচে পদ্ধতিগুলি বেশ কয়েকটি অনুষ্ঠানে এর আগে যেভাবে কাজ করেছে সে সম্পর্কে আমি ইতিমধ্যে ইতিমধ্যে আলোচনা করেছি যাতে আমি এটি আর করব না। ব্যক্তিগতভাবে, বিষয়টিতে আমার নিজের পছন্দগুলি এখানে এবং এখানে রয়েছে ।
আপনি যদি এটি পড়তে আগ্রহী না হন তবে এখনও কৌতূহলী কেবল বুঝতে পারেন যে ফাংশনটি চালনার আগে ফাংশনটির ইনপুটটির সাথে সংযুক্ত হ'ল ডক্সগুলি শেল সম্প্রসারণের জন্য মূল্যায়ন করা হয় , এবং ফাংশনটি সংজ্ঞায়িত করার সময় তারা যে অবস্থায় ছিল তাদের নতুনভাবে উত্পন্ন হয় প্রতিটি সময় ফাংশন বলা হয়।
ঘোষণা করা
আপনার কেবল এমন একটি ফাংশন প্রয়োজন যা অন্যান্য ফাংশনগুলি ঘোষণা করে।
_fn_init() { . /dev/fd/4 ; } 4<<INIT
${1}() { $(shift ; printf %s\\n "$@")
} 4<<-REQ 5<<-\\RESET
: \${_if_unset?shell will ERR and print this to stderr}
: \${common_param="REQ/RESET added to all funcs"}
REQ
_fn_init $(printf "'%s' " "$@")
RESET
INIT
চালাও এটা
এখানে আমি _fn_init
আমাকে একটি ক্রিয়াকলাপ ডেকে আনার আহ্বান জানাই fn
।
set -vx
_fn_init fn \
'echo "this would be command 1"' \
'echo "$common_param"'
#OUTPUT#
+ _fn_init fn 'echo "this would be command 1"' 'echo "$common_param"'
shift ; printf %s\\n "$@"
++ shift
++ printf '%s\n' 'echo "this would be command 1"' 'echo "$common_param"'
printf "'%s' " "$@"
++ printf ''\''%s'\'' ' fn 'echo "this would be command 1"' 'echo "$common_param"'
#ALL OF THE ABOVE OCCURS BEFORE _fn_init RUNS#
#FIRST AND ONLY COMMAND ACTUALLY IN FUNCTION BODY BELOW#
+ . /dev/fd/4
#fn AFTER _fn_init .dot SOURCES IT#
fn() { echo "this would be command 1"
echo "$common_param"
} 4<<-REQ 5<<-\RESET
: ${_if_unset?shell will ERR and print this to stderr}
: ${common_param="REQ/RESET added to all funcs"}
REQ
_fn_init 'fn' \
'echo "this would be command 1"' \
'echo "$common_param"'
RESET
REQUIRED টি
যদি আমি এই ফাংশনটি কল করতে চাই তবে পরিবেশের পরিবর্তনশীল _if_unset
সেট না করা এটি মারা যায় ।
fn
#OUTPUT#
+ fn
/dev/fd/4: line 1: _if_unset: shell will ERR and print this to stderr
শেল ট্রেসের ক্রমটি দয়া করে নোট করুন - আনসেট থাকা fn
অবস্থায় _if_unset
কেবল যখন ডাকা হয় তখনই এটি ব্যর্থ হয় না, তবে এটি কখনই প্রথম স্থানে চলে না । এখানে-নথি বিস্তারের সাথে কাজ করার সময় এটি বোঝার জন্য সর্বাধিক গুরুত্বপূর্ণ বিষয় - এগুলি সর্বদা প্রথমে হওয়া উচিত কারণ তারা সব <<input
পরে।
ত্রুটিটি এসেছিল /dev/fd/4
কারণ পিতামাত্ত শেলটি ইনপুটটিকে ফাংশনে দেওয়ার আগে before ইনপুটটিকে মূল্যায়ন করে। প্রয়োজনীয় পরিবেশের জন্য এটি পরীক্ষা করা সবচেয়ে সহজতম উপায়।
যাইহোক, ব্যর্থতা সহজেই প্রতিকার করা যায়।
_if_unset=set fn
#OUTPUT#
+ _if_unset=set
+ fn
+ echo 'this would be command 1'
this would be command 1
+ echo 'REQ/RESET added to all funcs'
REQ/RESET added to all funcs
নমনীয়
ভেরিয়েবল common_param
দ্বারা ঘোষিত প্রতিটি কার্যের জন্য ইনপুটটিতে একটি ডিফল্ট মানকে মূল্যায়ন করা হয় _fn_init
। তবে সেই মানটি অন্য যে কোনও ক্ষেত্রেও পরিবর্তনযোগ্য যা একইভাবে ঘোষিত প্রতিটি কার্যক্রমে সম্মানিত হবে। আমি এখন শেলের চিহ্নগুলি ছেড়ে দেব - আমরা এখানে কোনও অরক্ষিত অঞ্চল বা কোনও কিছুর মধ্যে যাচ্ছি না।
set +vx
_fn_init 'fn' \
'echo "Hi! I am the first function."' \
'echo "$common_param"'
_fn_init 'fn2' \
'echo "This is another function."' \
'echo "$common_param"'
_if_unset=set ;
উপরে আমি দুটি ফাংশন এবং সেট ঘোষণা করি _if_unset
। এখন, উভয় ফাংশন কল করার আগে, আমি আনসেট করব common_param
যাতে আপনি দেখতে পাবেন যে আমি তাদের কল করার পরে তারা সেগুলি সেট করবে।
unset common_param ; echo
fn ; echo
fn2 ; echo
#OUTPUT#
Hi! I am the first function.
REQ/RESET added to all funcs
This is another function.
REQ/RESET added to all funcs
এবং এখন কলারের সুযোগ থেকে:
echo $common_param
#OUTPUT#
REQ/RESET added to all funcs
তবে এখন আমি এটি পুরোপুরি অন্য কিছু হতে চাই:
common_param="Our common parameter is now something else entirely."
fn ; echo
fn2 ; echo
#OUTPUT#
Hi! I am the first function.
Our common parameter is now something else entirely.
This is another function.
Our common parameter is now something else entirely.
আর আমি যদি আনসেট না করি _if_unset
?
unset _if_unset ; echo
echo "fn:"
fn ; echo
echo "fn2:"
fn2 ; echo
#OUTPUT#
fn:
dash: 1: _if_unset: shell will ERR and print this to stderr
fn2:
dash: 1: _if_unset: shell will ERR and print this to stderr
রিসেট
আপনার যদি কোনও সময়ে ফাংশনটির স্থিতি পুনরায় সেট করতে হয় তবে এটি সহজেই হয়ে যায়। আপনার কেবলমাত্র (ফাংশন থেকে) করতে হবে:
. /dev/fd/5
5<<\RESET
ইনপুট ফাইল-বর্ণনাকারীতে প্রাথমিকভাবে ফাংশনটি ঘোষণার জন্য ব্যবহৃত যুক্তিগুলি সংরক্ষণ করেছি saved সুতরাং .dot
গুন যে কোন সময়ে শেল প্রক্রিয়া এটি প্রথম স্থানে সেট আপ পুনরাবৃত্তি করবেন। এটি খুব সুন্দর, সত্যই এবং পুরোপুরি পুরোপুরি পোর্টেবল যদি আপনি পসিক্স আসলে ফাইল-বর্ণনাকারী ডিভাইস নোড পাথগুলি নির্দিষ্ট করে না (যা শেলটির প্রয়োজনীয়তা .dot
) তবে এই বিষয়টি উপেক্ষা করতে আগ্রহী ।
আপনি সহজেই এই আচরণটি প্রসারিত করতে পারেন এবং আপনার ফাংশনের জন্য বিভিন্ন রাজ্যকে কনফিগার করতে পারেন।
আরো বেশী?
এটি সবেমাত্র পৃষ্ঠটি স্ক্র্যাচ করে। আমি প্রায়শই কোনও মূল ফাংশনের ইনপুটটিতে ঘোষিতযোগ্য কিছু সহায়ক সহায়ক ফাংশন এম্বেড করতে এই কৌশলগুলি ব্যবহার করি - উদাহরণস্বরূপ, $@
প্রয়োজন হিসাবে অতিরিক্ত অবস্থানিক অ্যারেগুলির জন্য । আসলে - যেমনটি আমি বিশ্বাস করি এটি অবশ্যই এর খুব কাছাকাছি কিছু হতে হবে যা উচ্চতর অর্ডার শেলগুলি যাইহোক করে। আপনি দেখতে পারেন যে এগুলি খুব সহজেই প্রোগ্রামের নামকরণ হয়েছে।
আমি এমন একটি জেনারেটর ফাংশনও ঘোষণা করতে চাই যা সীমিত প্রকারের প্যারামিটার গ্রহণ করে এবং তারপর ল্যাম্বডা - বা একটি লাইন ফাংশনের লাইনের সাথে একক-ব্যবহার বা অন্যথায় স্কোপ-লিমিটেড বার্নার-ফাংশন সংজ্ঞায়িত করে - যা কেবল unset -f
তখনই নিজের মাধ্যম. আপনি চারপাশে একটি শেল ফাংশন পাস করতে পারেন।