মূলত, এটি একটি বহনযোগ্যতা (এবং নির্ভরযোগ্যতা) ইস্যু।
প্রথমদিকে, echoকোনও বিকল্প গ্রহণ করা হয়নি এবং কোনও কিছু প্রসারিত হয়নি। এটি যা করছিল তা হ'ল তার আর্গুমেন্টগুলিকে একটি স্থানের অক্ষর দ্বারা পৃথক করা এবং একটি নতুন লাইন চরিত্র দ্বারা সমাপ্ত করা।
এখন, কেউ ভেবেছিল, আমরা যদি echo "\n\t"নিউলাইন বা ট্যাব অক্ষরগুলি আউটপুট দেওয়ার মতো জিনিসগুলি করতে পারি , বা অনুবর্তিত নিউলাইন চরিত্রটিকে আউটপুট না দেওয়ার বিকল্প পাই তবে এটি বেশ ভাল হবে ।
তারপর কঠিন চিন্তা কিন্তু এর পরিবর্তে শেল (যেমন যে কার্যকারিতা যোগ করার perlযেখানে উদ্ধৃতি চিহ্ন ভিতরে, \tআসলে একটি ট্যাব অক্ষর মানে), তারা এটা যোগ করা echo।
ডেভিড কর্ন ভুল বুঝতে পেরে শেল উদ্ধৃতিগুলির একটি নতুন ফর্ম প্রবর্তন করেছিলেন: $'...'এটি পরে অনুলিপি করা হয়েছিল bashএবং zshততক্ষণে এটি অনেক দেরিতে ছিল।
এখন যখন একটি স্ট্যান্ডার্ড ইউনিক্স echoএকটি আর্গুমেন্ট গ্রহণ করে যার মধ্যে দুটি অক্ষর থাকে \এবং tসেগুলি আউটপুট না দিয়ে, এটি একটি ট্যাব অক্ষরের আউটপুট দেয়। এবং যত তাড়াতাড়ি এটি \cএকটি আর্গুমেন্টে দেখা যায়, এটি আউটপুটিং বন্ধ করে দেয় (সুতরাং পিছনে থাকা নতুন লাইনও আউটপুট নয়)।
অন্যান্য শেলস / ইউনিক্স বিক্রেতারা / সংস্করণগুলি এটি আলাদাভাবে করতে বেছে নিয়েছিল: তারা -eএস্কেপ সিকোয়েন্সগুলি প্রসারিত করার একটি -nবিকল্প এবং ট্রেলিং নতুন লাইনের আউটপুট না দেওয়ার বিকল্প যুক্ত করেছে। কারও কারও -Eকাছে পালানোর ক্রম অক্ষম করতে হবে, কিছু রয়েছে -nতবে তা নয় -e, একটি echoবাস্তবায়ন দ্বারা সমর্থিত পালানো সিকোয়েন্সগুলির তালিকাগুলি অপর দ্বারা সমর্থিত হিসাবে প্রয়োজনীয় নয় is
সোভেন মাসচেকের একটি দুর্দান্ত পৃষ্ঠা রয়েছে যা সমস্যার পরিমাণটি দেখায় ।
ঐ উপর echoবাস্তবায়নের যে অপশন সমর্থন, সেখানে সাধারণত একটি কোন সমর্থন নেই --অপশন শেষে চিহ্নিত করতে ( echoকিছু অ বোর্ন মত শেল builtin করি এবং zsh সমর্থন -যে যদিও জন্য), তাই উদাহরণস্বরূপ, এটা আউটপুট কঠিন "-n"সঙ্গে echoএ অনেক শাঁস
কিছু শেল যেমন bash¹ বা ksh93² বা yash( $ECHO_STYLEভেরিয়েবল) এর উপর, শেলটি কীভাবে সংকলিত হয়েছিল বা পরিবেশের (জিএনইউ'র echoআচরণটি $POSIXLY_CORRECTপরিবেশে থাকলে এবং সংস্করণ 4 , zshএর bsd_echoবিকল্পের সাথে রয়েছে তার উপরও আচরণ নির্ভর করে , কিছু পিডিএক্স-ভিত্তিক তাদের posixবিকল্পের সাথে বা তাদের হিসাবে ডাকা হয়েছে কিনা sh) সুতরাং দুটি bash echoগুলি এমনকি একই সংস্করণ থেকেও একই bashআচরণ করার গ্যারান্টি নেই।
পক্সিক্স বলেছেন: প্রথম যুক্তিটি যদি হয় -nবা কোনও যুক্তিতে ব্যাকস্ল্যাশ থাকে, তবে আচরণটি অনির্দিষ্ট । bashএই ক্ষেত্রে প্রতিধ্বনি POSIX echo -eনয় -e<newline>যেমন POSIX এর প্রয়োজন হিসাবে আউটপুট দেয় না । ইউএনআইএক্স স্পেসিফিকেশন আরও কঠোর, এটি আউটপুটিং বন্ধ করার -nজন্য কয়েকটি পালানোর ক্রমকে নিষিদ্ধ করে এবং এর প্রসারণ প্রয়োজন \c।
এই বাস্তবায়নগুলি এখানে বাস্তবায়নের জন্য আসে না যে অনেক বাস্তবায়ন মেনে চলে না। এমনকি ম্যাকোএস 5 এর মতো কিছু শংসাপত্রপ্রাপ্ত সিস্টেমও উপযুক্ত নয়।
প্রকৃতপক্ষে বর্তমান বাস্তবতার প্রতিনিধিত্ব করতে, পসিক্সকে আসলে বলা উচিত : প্রথম যুক্তি যদি ^-([eEn]*|-help|-version)$বর্ধিত রেজিপ্স্পের সাথে মেলে বা কোনও যুক্তিতে ব্যাকস্ল্যাশ থাকে (বা অক্ষরগুলির এনকোডিংয়ে αবিআইজি 5 অক্ষর ব্যবহার করে স্থানীয়ভাবে অক্ষরের এনকোডিং থাকে ) তবে আচরণটি হ'ল অনির্দিষ্ট।
সব মিলিয়ে আপনি জানেন না যে echo "$var"আউটপুট কী হবে যদি না আপনি নিশ্চিত না করতে পারেন যে $varএতে ব্যাকস্ল্যাশ অক্ষর নেই এবং শুরু না হয় -। পসিক্স স্পেসিফিকেশন আসলে printfসেই ক্ষেত্রে পরিবর্তে আমাদের ব্যবহার করতে বলে ।
সুতরাং এর অর্থ হ'ল আপনি echoঅনিয়ন্ত্রিত ডেটা প্রদর্শনের জন্য ব্যবহার করতে পারবেন না । অন্য কথায়, আপনি যদি কোনও স্ক্রিপ্ট লিখছেন এবং এটি বাহ্যিক ইনপুট নিচ্ছে (ব্যবহারকারী থেকে যুক্তি হিসাবে, বা ফাইল সিস্টেম থেকে ফাইলের নাম ...), আপনি echoএটি প্রদর্শনের জন্য ব্যবহার করতে পারবেন না ।
এটা ঠিক আছে:
echo >&2 Invalid file.
এটি হবে না:
echo >&2 "Invalid file: $file"
(যদিও এটি কয়েকটি (UNIX- র অনুবর্তী নয়) echoবাস্তবায়নের সাথে ঠিক আছে bashযখন xpg_echoবিকল্পটি সংকলনের সময় বা পরিবেশের মাধ্যমে একরকম বা অন্য কোনওভাবে সক্ষম করা হয়নি ) like
file=$(echo "$var" | tr ' ' _)(ব্যতিক্রম হচ্ছে সবচেয়ে বাস্তবায়নের মধ্যে ঠিক আছে নয় yashসঙ্গে ECHO_STYLE=raw(সতর্কীকরণ যে সঙ্গে yashএর ভেরিয়েবল) বাইটের নির্বিচারে সিকোয়েন্স তাই নির্বিচারে ফাইল নাম এবং রাখা যাবে না zshs 'এর echo -E - "$var"6 )।
printfঅন্যদিকে, এটি আরও নির্ভরযোগ্য, অন্তত যখন এটির প্রাথমিক ব্যবহারের মধ্যে সীমাবদ্ধ থাকে echo।
printf '%s\n' "$var"
এতে $varকোনও অক্ষর থাকতে পারে তা নির্বিশেষে একটি নতুন লাইন চরিত্রের বিষয়বস্তু আউটপুট দেয় ।
printf '%s' "$var"
এর পেছনের নতুন লাইন অক্ষর ছাড়াই আউটপুট দেবে।
এখন, printfবাস্তবায়নের মধ্যেও পার্থক্য রয়েছে । POSIX দ্বারা নির্দিষ্ট করা বৈশিষ্ট্যগুলির একটি মূল রয়েছে, তবে তারপরে অনেকগুলি এক্সটেনশান রয়েছে। উদাহরণস্বরূপ, কিছু %qআর্গুমেন্টের উদ্ধৃতি দিতে a সমর্থন করে তবে এটি কীভাবে শেল থেকে শেলের পরিবর্তিত হয়, কিছু \uxxxxইউনিকোড অক্ষরের জন্য সমর্থন করে । আচরণটি printf '%10s\n' "$var"বহু-বাইট লোকেলের ক্ষেত্রে পরিবর্তিত হয়, এর জন্য কমপক্ষে তিনটি পৃথক ফলাফল রয়েছেprintf %b '\123'
তবে শেষ পর্যন্ত, আপনি যদি পসিক্স বৈশিষ্ট্যটির সেটটিতে লেগে থাকেন printfএবং এটির সাথে খুব অভিনব কিছু করার চেষ্টা না করেন, আপনি সমস্যার বাইরে রয়েছেন।
তবে মনে রাখবেন প্রথম আর্গুমেন্টটি ফর্ম্যাট, সুতরাং ভেরিয়েবল / অনিয়ন্ত্রিত ডেটা থাকা উচিত নয়।
আরও নির্ভরযোগ্য echoব্যবহার করে প্রয়োগ করা যেতে পারে printf, যেমন:
echo() ( # subshell for local scope for $IFS
IFS=" " # needed for "$*"
printf '%s\n' "$*"
)
echo_n() (
IFS=" "
printf %s "$*"
)
echo_e() (
IFS=" "
printf '%b\n' "$*"
)
সাব শেল (যা বেশিরভাগ শেল বাস্তবায়নে একটি অতিরিক্ত প্রক্রিয়া তৈরি করে বোঝায়) local IFSঅনেকগুলি শেল ব্যবহার করে বা এ জাতীয় লেখার মাধ্যমে এড়ানো যায় :
echo() {
if [ "$#" -gt 0 ]; then
printf %s "$1"
shift
fi
if [ "$#" -gt 0 ]; then
printf ' %s' "$@"
fi
printf '\n'
}
নোট
1. কিভাবে bashএর echoআচরণ পরিবর্তন করা যেতে পারে।
সঙ্গে bash, রান সময়ে, দুই জিনিস আচরণকে নিয়ন্ত্রণ echo(পাশে enable -n echoবা redefining echoএকটি ফাংশন হিসাবে বা ওরফে): xpg_echo bashবিকল্প এবং কিনা bashposix মোডে রয়েছে। posixমোড সক্ষম করা যায় যদি bashবলা হয় shবা হিসাবে POSIXLY_CORRECTপরিবেশে বা posixবিকল্পের সাথে থাকে:
বেশিরভাগ সিস্টেমে ডিফল্ট আচরণ:
$ bash -c 'echo -n "\0101"'
\0101% # the % here denotes the absence of newline character
xpg_echo ইউএনআইএক্সের প্রয়োজন অনুসারে ক্রমগুলি প্রসারিত করে:
$ BASHOPTS=xpg_echo bash -c 'echo "\0101"'
A
এটি এখনও সম্মান দেয় -nএবং -e(এবং -E):
$ BASHOPTS=xpg_echo bash -c 'echo -n "\0101"'
A%
সহ xpg_echoএবং পসিক্স মোড:
$ env BASHOPTS=xpg_echo POSIXLY_CORRECT=1 bash -c 'echo -n "\0101"'
-n A
$ env BASHOPTS=xpg_echo sh -c 'echo -n "\0101"' # (where sh is a symlink to bash)
-n A
$ env BASHOPTS=xpg_echo SHELLOPTS=posix bash -c 'echo -n "\0101"'
-n A
এবার bashপসিক্স এবং ইউনিক্স উভয়ই অনুগত। নোট করুন যে পসিক্স মোডে, bashএখনও পসিক্সের মত নয় কারণ এটি আউটপুট দেয় না -e:
$ env SHELLOPTS=posix bash -c 'echo -e'
$
Xpg_echo এবং posix জন্য ডিফল্ট মান সংকলন সময়ে সংজ্ঞায়িত করা যায় --enable-xpg-echo-defaultএবং --enable-strict-posix-defaultকরতে অনেক বিকল্প configureস্ক্রিপ্ট। যা সাধারণত কি ওএস / এক্স সাম্প্রতিক সংস্করণ তাদের গড়ে তুলতে করি /bin/sh। কোন ইউনিক্স / লিনাক্স বাস্তবায়ন / তাদের অধিকার মনে বিতরণের জন্য যে কি সাধারণত হবে /bin/bashযদিও । প্রকৃতপক্ষে, এটি সত্য নয়, /bin/bashসোলারিস 11 (একটি alচ্ছিক প্যাকেজে) সহ ওরাকল জাহাজগুলি নির্মিত হয়েছিল বলে মনে হয় --enable-xpg-echo-default(সোলারিস 10 তে এটি ছিল না)।
২. কীভাবে ksh93এর echoআচরণ পরিবর্তন করা যায়।
ইন ksh93, echoএস্কেপ সিকোয়েন্সগুলি প্রসারিত করে কিনা এবং বিকল্পগুলি সনাক্ত করতে হবে $PATHএবং / অথবা $_AST_FEATURESপরিবেশের ভেরিয়েবলের সামগ্রীর উপর নির্ভর করে ।
যদি $PATHএকটি উপাদান যে রয়েছে রয়েছে /5binবা /xpgসামনে /binবা /usr/binকম্পোনেন্ট তারপর এটি সিস / ইউনিক্স এইরকম আচরণ (ক্রম বিস্তৃতি, বিকল্প গ্রহণ করে না)। যদি এটি সন্ধান করে /ucbবা /bsdপ্রথমে বা $_AST_FEATURES7 টি থাকে UNIVERSE = ucbতবে তা BSD 3 টির সাথে আচরণ করে ( -eসম্প্রসারণ সক্ষম করতে, স্বীকৃতি দিতে -n)।
ডিফল্টটি সিস্টেম নির্ভর, builtin getconf; getconf UNIVERSEদেবিয়ানের বিএসডি ( ksh93 এর সাম্প্রতিক সংস্করণে আউটপুট দেখুন ):
$ ksh93 -c 'echo -n' # default -> BSD (on Debian)
$ PATH=/foo/xpgbar:$PATH ksh93 -c 'echo -n' # /xpg before /bin or /usr/bin -> XPG
-n
$ PATH=/5binary:$PATH ksh93 -c 'echo -n' # /5bin before /bin or /usr/bin -> XPG
-n
$ PATH=/5binary:$PATH _AST_FEATURES='UNIVERSE = ucb' ksh93 -c 'echo -n' # -> BSD
$ PATH=/ucb:/foo/xpgbar:$PATH ksh93 -c 'echo -n' # /ucb first -> BSD
$ PATH=/bin:/foo/xpgbar:$PATH ksh93 -c 'echo -n' # /bin before /xpg -> default -> BSD
৩. ইকো-ই এর জন্য বিএসডি?
-eবিকল্পটি হ্যান্ডলিংয়ের জন্য বিএসডি-র উল্লেখটি এখানে কিছুটা বিভ্রান্তিকর। এই বিভিন্ন এবং বেমানান echoআচরণগুলির বেশিরভাগই এটিএন্ডটিটিতে চালু হয়েছিল:
\n, \0ooo, \cপ্রোগ্রামার এর কাজ বেঞ্চ ইউনিক্স (ইউনিক্স V6 উপর ভিত্তি করে), এবং বাকি (ইন \b, \r...) ইউনিক্স সিস্টেম তৃতীয় মধ্যে সূত্র ।
-nইউনিক্স ভি 7 এ (ডেনিস রিচি রেফ দ্বারা )
-eইউনিক্স ভি 8 এ (ডেনিস রিচি রেফ দ্বারা )
-Eনিজেই সম্ভবত প্রথম থেকেই এসেছিলেন bash( সংস্করণ ১.১13.৫-এ সিডাব্লুআরইউ / সিডাব্লুআরইউ.চ্লাগ উল্লেখ করেছেন ব্রায়ান ফক্স এটি 1992-10-18-এ যুক্ত করেছেন, জিএনইউ এটি শি-ইউস -১.৮ echo-এর পরে অনুলিপি করে 10 দিন পরে প্রকাশিত হয়েছে)
যদিও 90 বা দশকের গোড়ার দিকে তারা এর জন্য অ্যালকুইস্ট শেলটি ব্যবহার শুরু করার দিন থেকেই echoবিএসটি- shর -eবিল্টিন সমর্থন করেছে , এখনও echoপর্যন্ত এই স্ট্যান্ডেলোন ইউটিলিটি এটি সমর্থন করে না ( ফ্রিবিএসডিecho এখনও সমর্থন করে না -e, যদিও এটি সমর্থন করে -nনা ইউনিক্স ভি 7 (এবং এটি \cকেবলমাত্র শেষ যুক্তির শেষে))।
সামলাচ্ছে -eযোগ করা হয়েছিল ksh93'র echoবাসদ যখন মহাবিশ্ব 2006 সালে মুক্তি পান এবং ksh93r সংস্করণে সংকলন সময়ে নিষ্ক্রিয় করা যাবে।
৪.৩১-এ জিএনইউ প্রতিবেদনের প্রতিধ্বনি পরিবর্তন করেছে
Coreutils 8.31 (এবং যেহেতু এই কমিট ), গনুহ echoএখন ডিফল্ট ভাবে সিকোয়েন্স অব্যাহতি যখন POSIXLY_CORRECT পরিবেশে হয়, আচরণ মেলে বিস্তৃতি bash -o posix -O xpg_echoএর echobuiltin (দেখুন বাগ রিপোর্ট )।
5. ম্যাকোস echo
ম্যাকোসের বেশিরভাগ সংস্করণ ওপেনগ্রুপ থেকে ইউনিক্স শংসাপত্র পেয়েছে ।
তাদের shবিল্টিনটি ( echoএটি bashএকটি খুব পুরানো সংস্করণ) মেনে চলতে সক্ষম হিসাবে এটি xpg_echoডিফল্টরূপে সক্ষম হয়েছে তবে তাদের একা একা echoইউটিলিটি নেই। env echo -nআউটপুট পরিবর্তে কিছুই না -n<newline>, env echo '\n'আউটপুট \n<newline>পরিবর্তে <newline><newline>।
যে /bin/echoযা সম্পর্কে newline আউটপুট শুষে যদি প্রথম যুক্তি FreeBSD থেকে এক -n(1995 সাল থেকে) অথবা যদি গত যুক্তি শেষ হয় \c, কিন্তু, ইউনিক্স প্রয়োজনীয় এমনকি অন্য কোন ব্যাকস্ল্যাশ সিকোয়েন্স সমর্থন করে না \\।
Implement. echoবাস্তবায়নগুলি যা স্বেচ্ছাসেবী ডেটা ভারব্যাটিম আউটপুট করতে পারে
কঠোরভাবে বলতে, আপনার কাছে গণনা করতে পারে যে FreeBSD 'র / MacOS /bin/echoউপরে (তাদের শেল এর echobuiltin) যেখানে zsh' র echo -E - "$var"বা yashএর ECHO_STYLE=raw echo "$var"( printf '%s\n' "$var") লেখা যেতে পারে:
/bin/echo "$var
\c"
বাস্তবায়নগুলি যা সমর্থন করে -Eএবং -n(বা এতে কনফিগার করা যায়) এছাড়াও করতে পারে:
echo -nE "$var
"
এবং zshএর echo -nE - "$var"( printf %s "$var") লেখা যেতে পারে
/bin/echo "$var\c"
7. _AST_FEATURESএবং এএসটিUNIVERSE
_AST_FEATURESসরাসরি কাজে ব্যবহৃত হতে বোঝানো হয় না, এটা কমান্ড সঞ্চালনের জুড়ে এবং AST কনফিগারেশন সেটিংস সঞ্চারিত করতে ব্যবহৃত হয়। কনফিগারেশনটি হ'ল (অননুমোদিত) astgetconf()API এর মাধ্যমে করা । ভিতরে ksh93, getconfঅন্তর্নির্মিত (অনুরোধ সহ builtin getconfবা দ্বারা সক্রিয় command /opt/ast/bin/getconf) হ'ল ইন্টারফেসastgetconf()
উদাহরণস্বরূপ, আপনি সেটিংটি ( অন্যান্য জিনিসের মধ্যে সিসভি পদ্ধতিতে আচরণের কারণ হিসাবে) builtin getconf; getconf UNIVERSE = attপরিবর্তন করতে চান । এটি করার পরে, আপনি এনভায়রনমেন্ট ভেরিয়েবলের সাথে লক্ষ্য রাখবেন ।UNIVERSEattecho$_AST_FEATURESUNIVERSE = att
echo -e?