বাশ: প্রম্পটে প্রস্থান স্থিতি প্রদর্শন করুন:


11
GREEN="\e[1;32m"
RED="\e[1;31m"
NONE="\e[m"

get_exit_status(){
   es=$?
   if [ $es -eq 0 ]
   then
       echo -e "${GREEN}${es}${NONE}"
   else
       echo -e "${RED}${es}${NONE}"
   fi
}

get_path(){
    #dummy function
    echo "PATH"
}

PROMPT_COMMAND='exitStatus=$(get_exit_status)'

নিম্নলিখিতটি আমাকে সঠিক প্রস্থান স্ট্যাটাস দেয় তবে রঙের ভেরিয়েবলগুলি প্রসারিত হয় না:

PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '

তবে নীচের একটিটি আমাকে রঙ দেয় তবে প্রস্থান স্থিতি আপডেট হয় না:

PS1="${RED}\h $(get_path) ${exitStatus}${NONE} "

এটি করার সঠিক উপায় কী? আমি কীভাবে এটি ঠিক করতে পারি যাতে প্রস্থানস্থান এবং রঙ উভয়ই কাজ করে?

উত্তর:


8

গিলস আপনার মূল সমস্যাটি সনাক্ত করেছে, তবে আমি এটিকে অন্যভাবে ব্যাখ্যা করার চেষ্টা করতে চেয়েছিলাম।

ব্যাশ ব্যাখ্যা করে বিশেষ প্রম্পট বেরিয়ে শুধুমাত্র সামনে প্রম্পট কোনো ভেরিয়েবল বিস্তৃত। এর অর্থ \eহ'ল প্রম্পট থেকে প্রসারিত কোনও চলকটি ব্যবহার করা কার্যকর হয় না, যদিও এটি সরাসরি কাজ করে PS1

উদাহরণস্বরূপ, এটি প্রত্যাশার মতো কাজ করে এবং লাল পাঠ্য দেয়:

PS1='\e[1;31m this is in red '

তবে এটি তা নয়, এটি \eপ্রম্পটে কেবল একটি আক্ষরিক রাখে :

RED='\e[1;31m'
PS1="$RED not in red "

আপনি যদি ভেরিয়েবলের মধ্যে রঙের পলায়ন সংরক্ষণ করতে চান তবে আপনি ভেরিয়েবেলে $'...'আক্ষরিক অব্যাহতি অক্ষর রাখার জন্য এএনএসআই-সি উদ্ধৃতি ( ) ব্যবহার করতে পারেন ।

এই কাজের জন্য, আপনি আপনার সংজ্ঞা পরিবর্তন করতে পারেন GREEN, REDএবং NONE, তাই তাদের মূল্য প্রকৃত পালাবার ক্রম।

GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'

যদি আপনি এটি PS1করেন তবে একক উদ্ধৃতি সহ আপনার প্রথমটি কাজ করা উচিত:

PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '

তবে, তবে আপনার দ্বিতীয় সমস্যা হবে।

এটি চালানোর চেষ্টা করুন, তারপরে চাপুন Up Arrow, Homeএবং আপনার কার্সারটি লাইনের শুরুতে ফিরে যাবে না।

এটি ঠিক করার জন্য, রঙের পালানোর ক্রমগুলি PS1অন্তর্ভুক্ত করতে \[এবং পরিবর্তনের জন্য \]উদাহরণস্বরূপ

PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '

আপনি get_exit_statusএখানে সঠিকভাবে ব্যবহার করতে পারবেন না , কারণ এর আউটপুটে মুদ্রণ (প্রস্থান কোড) এবং অপ-মুদ্রণ অক্ষর (রঙ কোডগুলি) উভয়ই রয়েছে এবং প্রম্পটে সঠিকভাবে চিহ্নিত করার কোনও উপায় নেই। পুটিং \[...\]এটিকে সম্পূর্ণ মুদ্রণবিহীন হিসাবে চিহ্নিত করবে, যা সঠিক নয়। আপনাকে ফাংশনটি পরিবর্তন করতে হবে যাতে এটি কেবল সঠিক রঙ-কোড মুদ্রণ করে এবং তারপরে \[...\]প্রম্পটে এটি ঘিরে ।


\[হয় \1, এবং \[হয় \2RL_PROMPT_{START,END}_IGNOREস্ক্রিনে প্রম্পট দৈর্ঘ্য গণনা করার সময় এটি কিছু রিডলাইনের জিনিসের সাথে মিলে যায় যা এটি বাইটগুলি উপেক্ষা করতে বলে। List.gnu.org/archive/html/bug-bash/2015-08/msg00027.html দেখুন ।
আর্থার 2e5

@ আর্থার 2e5 আপনার অর্থ \]কি \2? এবং আপনি কি এর অর্থ এটির প্রয়োজন ${exitStatus}? আমার বক্তব্যটি হ'ল যে ${exitStatus}মুদ্রণবিহীন অক্ষরগুলি ধারণ করে না, সুতরাং বাশ সঠিকভাবে নির্ধারণ করতে সক্ষম হবে যে এটি কতগুলি অক্ষর প্রম্পটটি ইন \[এবং \]ইন ছাড়াই সরিয়ে দেয় \[${exitStatus}\]
মাইকেল

সমস্যাটি হ'ল এতে কয়েকটি রয়েছে - রঙগুলি। (এএনএসআই
পলাতক

@ আর্থার 2e5 ইও, আমি এটি পুরোপুরি মিস করেছি। :) আপনি রঙ কেন রাখবেন ... কিছু মনে করবেন না। :)
মাইকেল

1
"বাশ কার্যকরভাবে আপনার পিএস 1 এ প্রতিধ্বনি জানায়, প্রতিধ্বনি -e নয়" - ভাল এটি ভুল বা কেবল পয়েন্টটি মিস করছে। ব্যাশ প্রসারিত করে ব্যাকস্ল্যাশ-বেরিয়ে মত \eএবং \033(এবং \[/ \], \uএবং \hপ্রম্পট থেকে), এটা ঠিক তাই আছে সামনে ভেরিয়েবল বিস্তৃত। তাই PS1='\e[1;31m red'কাজ, red='\e[1;31m'; PS1='$red red'না।
ilkkachu

3

যখন আপনি চালাতে PS1='${RED}\h $(get_path) ${exitStatus}${NONE} ', PS1পরিবর্তনশীল সেট করা হয় ${RED}\h $(get_path) ${exitStatus}${NONE}, যেখানে শুধুমাত্র \hএকটি প্রম্পট পালাবার ক্রম। প্রম্পট সিকোয়েন্সগুলি প্রসারিত হওয়ার পরে (ফলনশীল ${RED}darkstar $(get_path) ${exitStatus}${NONE}) শেলটি স্বাভাবিক প্রসার যেমন যেমন পরিবর্তনশীল বিস্তৃতি সম্পাদন করে। আপনি দেখতে একটি প্রদর্শিত প্রম্পট পাবেন \e[1;31mdarkstar PATH 0\e[m। পথে কিছুই কিছুই \eপ্রকৃত পালানোর অক্ষরের ক্রমগুলি প্রসারিত করে ।

আপনি যখন চালান PS1="${RED}\h $(get_path) ${exitStatus}${NONE} ", PS1ভেরিয়েবল সেট করা হয় \e[1;31m\h PATH 0\e[m। ভেরিয়েবলগুলি RED, exitStatusএবং NONEঅ্যাসাইনমেন্টের সময় প্রসারিত হয়। তারপর প্রম্পট তিন প্রম্পট পালাবার ক্রম ধারণ করে ( \e, \h, এবং \eআবার)। এই পর্যায়ে প্রসারিত করার জন্য কোনও শেল ভেরিয়েবল নেই।

রঙগুলি দেখতে, আপনার প্রকৃত পালানোর অক্ষরগুলি ধারণ করতে রঙের পরিবর্তনশীলগুলি দরকার। আপনি এটি এইভাবে করতে পারেন:

RED=$'\033[1;31m'
NONE=$'\033[m'
PS1='\[${RED}\]\h \w $?\[${NONE}\] '

$'…'ব্যাকস্ল্যাশ-অক্টাল সিকোয়েন্সগুলি এবং কিছু ব্যাকস্ল্যাশ-লেটার সিকোয়েন্সগুলি প্রসারিত করে \nতবে এতে অন্তর্ভুক্ত নয় \e। আমি আপনার প্রম্পটে আরও তিনটি পরিবর্তন করেছি:

  • \[…\]রঙ-পরিবর্তনকারী কমান্ডের মতো মুদ্রণ-বিহীন ক্রমগুলি ব্যবহার করুন । অন্যথায় আপনার ডিসপ্লে শেষ হয়ে যাবে কারণ বাশ প্রম্পটের প্রস্থটি বের করতে পারে না।
  • \w বর্তমান ডিরেক্টরি মুদ্রণের জন্য একটি অন্তর্নির্মিত পালাবার ক্রম।
  • আপনার $?যদি PROMPT_COMMANDপ্রথম স্থানে না থাকে তবে আপনাকে প্রম্পটে দেখানোর জন্য জটিল কিছু করার দরকার নেই ।

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

হ্যাঁ, PS1ভুল, কিন্তু ব্যবহারের পরামর্শ $'...'জন্য REDএবং GREENএটা dogbane এর ব্যবহার কাজ করা উচিত PS1
মাইকেল

1

চেষ্টা করুন:

PS1='`exitStatus=$?;if [ $exitStatus -eq 0 ];then echo "\['${GREEN}'\]";else echo "\['${RED}'\]";fi;echo "\h $(get_path) ${exitStatus}${NONE}"`'

1
ধন্যবাদ, এটি কাজ করে, তবে প্রম্পটের মধ্যে যদি একটি বিবৃতি এম্বেড না করে এটি সম্পন্ন করার কোনও উপায় আছে?
ডগবনে

1

আমি যে পদ্ধতির সাথে চলেছি এটি এখানে, এটি ব্যবহার এড়ানো হয় PROMPT_COMMAND

# This function is called from a subshell in $PS1,
# to provide a colourised visual indicator of the exit status of the last run command
__COLOURISE_EXIT_STATUS() {
    # uncomment the next line for exit code output after each command, useful for debugging and testing
    #printf -- "\nexit code: $1\n" >&2
    [[ 0 == "$1" || 130 == "$1" ]] && printf -- "$GREEN" || printf -- "$RED"
}

তারপরে আমার $PS1নিম্নরূপ:

PS1='# ${debian_chroot:+($debian_chroot)}'"${GREEN}\u${YELLOW}@${DARK_YELLOW}\h${WHITE}:${LIGHT_BLUE}\w${WHITE}\n"'\[$(__COLOURISE_EXIT_STATUS $?)\]# \$'"\[${WHITE}\] "

1
যদিও এই বিশেষ ক্ষেত্রে এটি গুরুত্বপূর্ণ নয় তবে একমাত্র মানটি $?একটি পূর্ণসংখ্যা যেমন হতে পারে তবে এর printf '%b' "$GREEN"পরিবর্তে আপনার ব্যবহার করা উচিত । এছাড়াও, ফ্যাশনের নামগুলি উপসর্গযুক্ত __বা _বাশ-সমাপ্তি দ্বারা ব্যবহৃত হয় এমন হিসাবে ব্যবহার করা এড়িয়ে চলুন ।
nyuszika7h

1

আপনি এখানে যান - উবুন্টু এবং অন্যান্য লিনাক্সে (লিনাকেন?) এই আমার জন্য কাজ করে (টিএমএস)।

প্রস্থান কোড সনাক্তকরণের ভিতরে রাখার কারণটি $PS1হ'ল একমাত্র হোস্টের $PROMPT_COMMAND.bashrc পড়ার আগে কেবল পঠনযোগ্য সেট থাকে।


0

কারণ PROMPT_COMMANDএটি কোনও ফাংশন সংজ্ঞায়িত করা এবং এটি ব্যবহার করা পরিষ্কার:

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