
আপনার প্রশ্নে আপনি যে একই আউটপুট নোট করেছেন তা পেতে, যা প্রয়োজন তা হ'ল:
PS1='${PS2c##*[$((PS2c=0))-9]}- > '
PS2='$((PS2c=PS2c+1)) > '
আপনার দরকার নেই এই দুটি লাইন এটি পসিক্সের সামঞ্জস্যের কাছের যে কোনও কিছুতে ভান করে এমন কোনও শেলের মধ্যে এটি করবে।
- > cat <<HD
1 > line 1
2 > line $((PS2c-1))
3 > HD
line 1
line 2
- > echo $PS2c
0
তবে আমি এটি পছন্দ করেছি। এবং আমি এই কাজটি আরও কিছুটা আরও ভাল করে তোলে এর মূলসূত্রগুলি প্রদর্শন করতে চেয়েছিলাম। সুতরাং আমি এটি একটি সামান্য সম্পাদিত। আমি /tmpআপাতত এটি আটকে রেখেছি তবে আমি মনে করি এটি নিজের জন্যও রাখব। এটা এখানে:
cat /tmp/prompt
প্রম্পট লিপি:
ps1() { IFS=/
set -- ${PWD%"${last=${PWD##/*/}}"}
printf "${1+%c/}" "$@"
printf "$last > "
}
PS1='$(ps1)${PS2c##*[$((PS2c=0))-9]}'
PS2='$((PS2c=PS2c+1)) > '
দ্রষ্টব্য: সম্প্রতি যশ শিখেছি, গতকালই আমি এটি তৈরি করেছি। যে কারণেই হোক না কেন এটি %cস্ট্রিং সহ প্রতিটি যুক্তির প্রথম বাইট মুদ্রণ করে না - যদিও দস্তাবেজগুলি সেই ফর্ম্যাটটির জন্য প্রশস্ত-চর এক্সটেনশন সম্পর্কে নির্দিষ্ট ছিল এবং তাই এটি সম্পর্কিত হতে পারে - তবে এটি দিয়ে ঠিক আছে%.1s
এটাই পুরো জিনিস। সেখানে দুটি মূল বিষয় চলছে। এবং এটি দেখতে এটির মতো:
/u/s/m/man3 > cat <<HERE
1 > line 1
2 > line 2
3 > line $((PS2c-1))
4 > HERE
line 1
line 2
line 3
/u/s/m/man3 >
পদান্বয় $PWD
প্রতিটি সময় $PS1মূল্যায়ন করা $PWDহয় এটি প্রম্পটে যোগ করার জন্য পার্স এবং প্রিন্ট করে। তবে আমি $PWDআমার স্ক্রিনটি পুরো ভিড় পছন্দ করি না , তাই আমি বর্তমান পাতায় প্রতিটি রুটিচক্রের প্রথম অক্ষরটি বর্তমান ডিরেক্টরিতে চাই, যা আমি সম্পূর্ণরূপে দেখতে চাই। এটার মত:
/h/mikeserv > cd /etc
/etc > cd /usr/share/man/man3
/u/s/m/man3 > cd /
/ > cd ~
/h/mikeserv >
এখানে কয়েকটি পদক্ষেপ রয়েছে:
IFS=/
আমরা বর্তমান বিভক্ত করতে আছে চলুন $PWDএবং যে সঙ্গে কি সবচেয়ে নির্ভরযোগ্য উপায় $IFSউপর বিভক্ত /। এটির পরে একেবারেই বিরক্ত করার দরকার নেই - এখান থেকে সমস্ত বিভাজন $@পরবর্তী কমান্ডের শেলের পজিশনাল প্যারামিটার অ্যারে দ্বারা সংজ্ঞায়িত করা হবে :
set -- ${PWD%"${last=${PWD##/*/}}"}
সুতরাং এটি একটি খুব কৃপণ, কিন্তু মূল বিষয় হ'ল আমরা চিহ্নগুলিতে বিভক্ত $PWDহয়ে যাচ্ছি /। $lastবাম-সর্বাধিক এবং ডান-সর্বাধিক /স্ল্যাশের মধ্যে যে কোনও মান হওয়ার পরে সমস্ত কিছুর জন্য নির্ধারণ করতে আমি প্যারামিটার সম্প্রসারণও ব্যবহার করি । এইভাবে আমি জানি যে আমি যদি কেবলমাত্র থাকি /এবং কেবল একটি থাকে /তবে $lastএখনও পুরোটির সমান হবে $PWDএবং $1খালি থাকবে। এই বিষয়টি। আমি এটি নির্ধারণের আগে $lastলেজ প্রান্ত থেকে $PWDফালাও $@।
printf "${1+%c/}" "$@"
সুতরাং এখানে - যতক্ষণ না ${1+is set}আমরা আমাদের শেলটির প্রতিটি আর্গুমেন্টের printfপ্রথম %cহ্যার্যাক্টর - যা আমরা আমাদের বর্তমান প্রতিটি ডিরেক্টরিতে রেখেছি $PWD- শীর্ষ ডিরেক্টরিটি কম - বিভক্ত হয়ে গেছে /। সুতরাং আমরা মূলত কেবল প্রতিটি ডিরেক্টরিতে প্রথম অক্ষরটি ছাপিয়ে যাচ্ছি $PWDতবে শীর্ষস্থানীয়। এটি গুরুত্বপূর্ণ যদিও উপলব্ধি করা এই শুধুমাত্র কিছু ঘটে তাহলে এর $1সব এ সেট, যার মূলে ঘটবে না /বা এক থেকে সরানো /মধ্যে যেমন /etc।
printf "$last > "
$lastআমি সবেমাত্র আমাদের শীর্ষ ডিরেক্টরিতে নির্ধারিত পরিবর্তনশীল। সুতরাং এখন এটি আমাদের শীর্ষ ডিরেক্টরি। এটি শেষ বিবৃতিটি করেছে কিনা তা মুদ্রণ করে। এবং >ভাল পরিমাপের জন্য এটি একটি ঝরঝরে সামান্য লাগে ।
তবে কী বাড়বে?
এবং তারপরে $PS2শর্তযুক্ত বিষয়টি আছে । আমি এটি পূর্বে দেখিয়েছি এটি কীভাবে করা যায় যা আপনি এখনও নীচে খুঁজে পেতে পারেন - এটি মূলত একটি সুযোগের বিষয়। তবে আপনি যদি printf \bঅ্যাক্স স্পেসগুলির একগুচ্ছ কাজ শুরু করতে না চান এবং তারপরে তাদের চরিত্রের গণনাটি সামঞ্জস্য করার চেষ্টা না করেন তবে এর সাথে আরও কিছু আছে ... সুতরাং আমি এটি করি:
PS1='$(ps1)${PS2c##*[$((PS2c=0))-9]}'
আবারও ${parameter##expansion}দিন বাঁচায়। যদিও এটি এখানে কিছুটা অদ্ভুত - আমরা এটির নিজের থেকে আলাদা করে নেওয়ার সময় আমরা আসলে পরিবর্তনশীলটি সেট করি। আমরা এর নতুন মানটি সেট করি - মিড-স্ট্রিপ সেট করি - যে গ্লোব থেকে আমরা ফালাটি পাই। দেখেন তো? আমরা ##*আমাদের ইনক্রিমেন্ট ভেরিয়েবলের মাথা থেকে শেষ চরিত্রের মধ্যে থেকে সমস্ত কিছু ফেলা যা যা হতে পারে [$((PS2c=0))-9]। আমাদের মান এইভাবে আউটপুট না দেওয়ার গ্যারান্টিযুক্ত এবং এখনও আমরা এটি নির্ধারণ করি। এটি বেশ দুর্দান্ত - আমি এর আগে কখনও করিনি। তবে পসিক্স আমাদের গ্যারান্টি দেয় যে এটি করা যায় এটি সবচেয়ে বহনযোগ্য উপায়।
এবং এটি পসিএক্স-নির্দিষ্ট করার জন্য ধন্যবাদ ${parameter} $((expansion))যা এই সংজ্ঞাগুলি বর্তমান শেলটিতে রাখে না requ আর এই কেন এটা কাজ করে dashএবং shশুধু সেইসাথে এতে করে bashএবং zsh। আমরা কোনও শেল / টার্মিনাল নির্ভর পলায়ন ব্যবহার করি না এবং আমরা ভেরিয়েবলগুলি তাদের পরীক্ষা করতে পারি। এটিই পোর্টেবল কোডটিকে দ্রুত করে তোলে ।
বাকিগুলি মোটামুটি সহজ - প্রতিটি বারের জন্য আমাদের কাউন্টারটিকে কেবলমাত্র পুনরায় সেট না করা $PS2পর্যন্ত মূল্যায়ন করা $PS1হয়। এটার মত:
PS2='$((PS2c=PS2c+1)) > '
সুতরাং এখন আমি করতে পারি:
ড্যাশ ডেমো
ENV=/tmp/prompt dash -i
/h/mikeserv > cd /etc
/etc > cd /usr/share/man/man3
/u/s/m/man3 > cat <<HERE
1 > line 1
2 > line 2
3 > line $((PS2c-1))
4 > HERE
line 1
line 2
line 3
/u/s/m/man3 > printf '\t%s\n' "$PS1" "$PS2" "$PS2c"
$(ps1)${PS2c##*[$((PS2c=0))-9]}
$((PS2c=PS2c+1)) >
0
/u/s/m/man3 > cd ~
/h/mikeserv >
এসএইচ ডেমো
এটিতে bashবা একই কাজ করে sh:
ENV=/tmp/prompt sh -i
/h/mikeserv > cat <<HEREDOC
1 > $( echo $PS2c )
2 > $( echo $PS1 )
3 > $( echo $PS2 )
4 > HEREDOC
4
$(ps1)${PS2c##*[$((PS2c=0))-9]}
$((PS2c=PS2c+1)) >
/h/mikeserv > echo $PS2c ; cd /
0
/ > cd /usr/share
/u/share > cd ~
/h/mikeserv > exit
আমি উপরে যেমন বলেছি, প্রাথমিক সমস্যা হ'ল আপনি কোথায় আপনার গণনা করেন তা বিবেচনা করা উচিত। আপনি প্যারেন্ট শেলের মধ্যে রাজ্যটি পাবেন না - সুতরাং আপনি সেখানে গণনা করবেন না। আপনি সাব-শেলের মধ্যে রাজ্যটি পাবেন - সুতরাং যেখানে আপনি গণনা করছেন। তবে আপনি প্যারেন্ট শেলের মধ্যে সংজ্ঞাটি করেন।
ENV=/dev/fd/3 sh -i 3<<\PROMPT
ps1() { printf '$((PS2c=0)) > ' ; }
ps2() { printf '$((PS2c=PS2c+1)) > ' ; }
PS1=$(ps1)
PS2=$(ps2)
PROMPT
0 > cat <<MULTI_LINE
1 > $(echo this will be line 1)
2 > $(echo and this line 2)
3 > $(echo here is line 3)
4 > MULTI_LINE
this will be line 1
and this line 2
here is line 3
0 >
man 1 mktemp।