প্রম্পটের ডান সারিবদ্ধ করুন


27

আমি নিশ্চিত যে আমি দেখেছি যে কেউ তাদের প্রম্পটের একটি অংশ তাদের টার্মিনাল উইন্ডোতে ডানদিকে প্রান্তীকৃত করেছে এবং তারপরে প্রকৃত কার্সারটি দ্বিতীয় লাইনে শুরু করা হয়েছে। আমি জানি যে আমি PS1 এ "\ n" দিয়ে দ্বিতীয় লাইনটি অর্জন করতে পারি তবে এর অংশটি কীভাবে ডানদিকে প্রান্তিক করা যায় তা আমি বুঝতে পারি না। আমি কি কেবল দুটি স্ট্রিংয়ের মধ্যেই হোয়াইটস্পেস যুক্ত দেখেছি?

উত্তর:


17

আপনি যা চান তা প্রম্পট প্রদর্শনের আগে প্রথম লাইনটি প্রদর্শন করে মোটামুটি সহজেই করা যায়। উদাহরণস্বরূপ, নিম্নলিখিতটি \wপ্রথম লাইনের বাম দিকে একটি প্রম্পট এবং প্রথম লাইনের \u@\hডানদিকে একটি প্রম্পট প্রদর্শন করে। এটি $COLUMNSভেরিয়েবলটি ব্যবহার করে যা টার্মিনালের প্রস্থ এবং $PROMPT_COMMANDপরামিতি যা বাশ প্রম্পট প্রদর্শনের আগে মূল্যায়ন করা হয় contains

print_pre_prompt () 
{ 
    PS1L=$PWD
    if [[ $PS1L/ = "$HOME"/* ]]; then PS1L=\~${PS1L#$HOME}; fi
    PS1R=$USER@$HOSTNAME
    printf "%s%$(($COLUMNS-${#PS1L}))s" "$PS1L" "$PS1R"
}
PROMPT_COMMAND=print_pre_prompt

3
নোট করুন যে আপনি রঙিন বাম প্রম্পট চাইলে জিনিসগুলি উল্লেখযোগ্যভাবে আরও জটিল হয়ে ওঠে, যেহেতু মুদ্রনবিহীন অক্ষরগুলি বোঝায় যে স্ট্রিং দৈর্ঘ্য প্রদর্শিত অক্ষরের সংখ্যার মতো নয়।
মিঃ মাইন্ড

1
উভয় এই এবং সর্বোচ্চ সঠিকভাবে কাজ না হলে উত্তর ভোট .inputrcহয়েছে set show-mode-in-prompt on। উভয় অ prinable দৈর্ঘ্য নিরূপণ না ANSI সিএসআই কোড , এবং সঠিকভাবে তাদের মধ্যে ঘিরা না \[এবং \]@Mu মন দ্বারা হিসাবে উল্লেখ করেছে। একটি উত্তর জন্য এই উত্তর দেখুন ।
টম হেল

26

আমি এখানে যে তথ্যের সন্ধান পেয়েছি তার উপর ভিত্তি করে ডান বা বামে রঙের সমর্থন সহ ভেরিয়েবলের দৈর্ঘ্যের সামগ্রীকে সামঞ্জস্য করার সময় আমি ডান সারিবদ্ধ করার একটি সহজ সমাধান আবিষ্কার করতে সক্ষম হয়েছি। আপনার সুবিধার জন্য এখানে যুক্ত করা হয়েছে ...

রং উপর নোট: ব্যবহার \033বিকল্প পক্ষে অব্যাহতি ছাড়া \[\]সম্পর্কিত, অধিকাংশ সামঞ্জস্যপূর্ণ এবং তজ্জন্য সুপারিশ প্রমাণ করে।

কৌশলটি হ'ল প্রথমে ডান হাতটি লিখতে হবে, তারপরে \rলাইনের শুরুতে ফিরে যেতে ক্যারিজ রিটার্ন ( ) ব্যবহার করুন এবং তার উপরে বাম দিকের সামগ্রীটি ওভাররাইট করে চালিয়ে যান:

prompt() {
    PS1=$(printf "%*s\r%s\n\$ " "$(tput cols)" 'right' 'left')
}
PROMPT_COMMAND=prompt

আমি tput colsম্যাক ওএস এক্সে টার্মিনাল / কনসোল প্রস্থটি পুনরুদ্ধার করার জন্য ব্যবহার করছি terminfoযেহেতু আমার $COLUMNSভেরিটি জনবসতিযুক্ত নয় envতবে আপনি পরিবর্তিত *মানটি %*s" ${COLUMNS}" সরবরাহ করে " " বা তার পরিবর্তে অন্য যে কোনও মান আপনি পছন্দ করতে পারেন।

পরবর্তী উদাহরণে $RANDOMবিভিন্ন দৈর্ঘ্যের সামগ্রী তৈরি করার জন্য রঙগুলি অন্তর্ভুক্ত করে এবং এতে আপনি কীভাবে পুনরায় ব্যবহারযোগ্য ফাংশনগুলিতে বাস্তবায়নটিকে রিফেক্টর করতে ফাংশনগুলি বের করতে পারেন তা দেখায়।

function prompt_right() {
  echo -e "\033[0;36m$(echo ${RANDOM})\033[0m"
}

function prompt_left() {
  echo -e "\033[0;35m${RANDOM}\033[0m"
}

function prompt() {
    compensate=11
    PS1=$(printf "%*s\r%s\n\$ " "$(($(tput cols)+${compensate}))" "$(prompt_right)" "$(prompt_left)")
}
PROMPT_COMMAND=prompt

যেহেতু printfস্ট্রিংয়ের দৈর্ঘ্যটি রঙগুলি রেন্ডার করার জন্য প্রয়োজনীয় অক্ষরের পরিমাণের জন্য আমাদের ক্ষতিপূরণ করতে হবে সেই হিসাবে ধরে নিয়েছে, ক্ষতিপূরণ ছাড়াই মুদ্রিত এএনএসআই অক্ষরগুলির কারণে আপনি এটি পর্দার শেষের দিকে সর্বদা সংক্ষিপ্ত দেখতে পাবেন। রঙের জন্য প্রয়োজনীয় অক্ষরগুলি স্থির থাকে এবং আপনি দেখতে পাবেন যে প্রিন্টফ দৈর্ঘ্যের পরিবর্তনটিকেও বিবেচনায় $RANDOMরাখে, যেমন উদাহরণস্বরূপ ফিরে আসে ', যা কৌশলটিতে আমাদের ডান প্রান্তিককরণকে রাখে।

এই বিশেষ ব্যাশ প্রম্পট পালাবার ক্রম সঙ্গে কেস (অর্থাত। নয় \u, \w, \h, \t) যদিও, এই শুধুমাত্র 2 দৈর্ঘ্য রেকর্ড করব কারণ ব্যাশ শুধুমাত্র তাদের যখন প্রম্পট প্রদর্শন করা হয় অনুবাদ করবে printf, পরে স্ট্রিং অনুষ্ঠিত হয়েছে। এটি বাম দিকে প্রভাবিত করে না তবে ডানদিকে এড়ানো ভাল।

উত্পন্ন সামগ্রী যদিও ধ্রুবক দৈর্ঘ্যে থেকে যায় তবে কোনও ফলস্বরূপ। সময় \tবিকল্পের মতো যা সর্বদা 24 সময়ের জন্য একই পরিমাণের অক্ষর (8) সরবরাহ করে। এই ক্ষেত্রে, মুদ্রণের সময় 8 টি অক্ষরের ফলাফল হিসাবে গণনা করা 2 টি অক্ষরের মধ্যে পার্থক্যের জন্য আমাদের কেবলমাত্র ক্ষতিপূরণের ফ্যাক্টর প্রয়োজন।

মনে রাখবেন যে আপনাকে \\\কিছু পালানোর ক্রম ট্রিপল করতে হবে যা অন্যথায় স্ট্রিংগুলির অর্থ রাখে। নিম্নোক্ত উদাহরণের মতো বর্তমান কার্যকরী ডিরেক্টরি পালানোর \wকোনও অর্থ নেই অন্যথায় এটি প্রত্যাশার মতো কাজ করে তবে সময় \t, যার অর্থ একটি ট্যাব অক্ষর, ট্রিপলটি আগে বেরোনোর ​​আগে প্রত্যাশা অনুযায়ী কাজ করে না।

function prompt_right() {
  echo -e "\033[0;36m\\\t\033[0m"
}

function prompt_left() {
  echo -e "\033[0;35m\w\033[0m"
}

function prompt() {
    compensate=5
    PS1=$(printf "%*s\r%s\n\$ " "$(($(tput cols)+${compensate}))" "$(prompt_right)" "$(prompt_left)")
}
PROMPT_COMMAND=prompt

nJoy!


8

সত্যই ভাল কাজ printfসঙ্গে ব্যবহার করে $COLUMNS, যেমন:

printf "%${COLUMNS}s\n" "hello"

এটা ঠিক আমার জন্য একেবারে ন্যায়সঙ্গত।


6

নিম্নলিখিতটি টার্মিনালের আরএইচএসে রেডে বর্তমান তারিখ এবং সময়টি রাখবে।

# Create a string like:  "[ Apr 25 16:06 ]" with time in RED.
printf -v PS1RHS "\e[0m[ \e[0;1;31m%(%b %d %H:%M)T \e[0m]" -1 # -1 is current time

# Strip ANSI commands before counting length
# From: https://www.commandlinefu.com/commands/view/12043/remove-color-special-escape-ansi-codes-from-text-with-sed
PS1RHS_stripped=$(sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" <<<"$PS1RHS")

# Reference: https://en.wikipedia.org/wiki/ANSI_escape_code
local Save='\e[s' # Save cursor position
local Rest='\e[u' # Restore cursor to save point

# Save cursor position, jump to right hand edge, then go left N columns where
# N is the length of the printable RHS string. Print the RHS string, then
# return to the saved position and print the LHS prompt.

# Note: "\[" and "\]" are used so that bash can calculate the number of
# printed characters so that the prompt doesn't do strange things when
# editing the entered text.

PS1="\[${Save}\e[${COLUMNS:-$(tput cols)}C\e[${#PS1RHS_stripped}D${PS1RHS}${Rest}\]${PS1}"

সুবিধাদি:

  • আরএইচএস প্রম্পটে রঙ এবং এএনএসআই সিএসআই কোডগুলির সাথে সঠিকভাবে কাজ করে
  • কোনও উপ-প্রক্রিয়া নেই। shellcheckপরিষ্কার।
  • কাজ সঠিকভাবে যদি .inputrcগেছে set show-mode-in-prompt on
  • সঠিকভাবে অ প্রম্পট দৈর্ঘ্যের-দান অক্ষর encapsulates মধ্যে \[এবং \]যাতে সম্পাদনা প্রম্পটে প্রবেশ টেক্সট অদ্ভুত পুনর্মুদ্রণ দ্রুত কারণ হবে না।

দ্রষ্টব্য : আপনাকে অবশ্যই নিশ্চিত করতে হবে যে $PS1এই কোডটি বাদ দেওয়ার আগে যে কোনও রঙের সিক্যুয়েন্সগুলি যথাযথভাবে বদ্ধ রয়েছে \[এবং সেগুলির \]কোনও নেস্টিং নেই।


যদিও আমি এই পদ্ধতির মতবাদটি পছন্দ করি, বাস্তবে এটি বাক্সের বাইরে কাজ করে না (উবুন্টু 18.04, জিএনইউ ব্যাশ ৪.৪.১৯): কোডটি সরাসরি .brcrc এ যুক্ত করার পরে প্রথমে ত্রুটি ঘটে bash: local: can only be used in a functionযা সংশোধন করার ক্ষেত্রে তুচ্ছ এবং এর পরে, এটি কোনও কিছুই দেখায় না কারণ COLUMNSএটি সংজ্ঞায়িত নয়: এটির সাথে প্রতিস্থাপন করতে হবে $(tput cols)। স্নিপেটটি যদি অন্য কোনও ফাইলে সংরক্ষণ করা হয় এবং তারপরে উত্সাহিত হয় তবে একই ফলাফল .bashrc
পোলান্টিনো

1
ধন্যবাদ পোলেন্টিনো আনসেট না tput colsথাকলে চালানোর জন্য কোডটি আপডেট করেছি $COLUMNS। এবং হ্যাঁ, এই কোডটি কোনও ফাংশনের ভিতরে থাকা উচিত। আমি PROMPT_COMMAND='_prompt_bash_set'ফাংশনটি ব্যবহার করি এবং নাম দিই _prompt_bash_set
টম হেল

2

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

আমি এটিতে একটি ভাল তিন দিন অতিবাহিত করেছি (কেবলমাত্র একটি ল্যাপটপ চলমান খিলানে পরীক্ষিত), সুতরাং এখানে একটি স্ক্রিনশট এবং তারপরে আমার। /।

কার্যে বাশ প্রম্পটের স্ক্রিনশট

সতর্কতা - এটি একটু ক্রেজি

গুরুত্বপূর্ণ একপাশে - প্রতিটি ^[(যেমন ^[[34m) সত্যিই পালানোর চরিত্র (char)27। এটি কীভাবে সন্নিবেশ করতে হয় তার একমাত্র উপায় হ'ল ctrl+ ( [v) প্রবেশ করা (অর্থাত্ উভয়টি হিট করুন [এবং চেপে ধরার vসময় ctrl)।

# grml battery?
GRML_DISPLAY_BATTERY=1

# battery dir
if [ -d /sys/class/power_supply/BAT0 ]; then
    _PS1_bat_dir='BAT0';
else
    _PS1_bat_dir='BAT1';
fi

# ps1 return and battery
_PS1_ret(){
    # should be at beg of line (otherwise more complex stuff needed)
    RET=$?;

    # battery
    if [[ "$GRML_DISPLAY_BATTERY" == "1" ]]; then
        if [ -d /sys/class/power_supply/$_PS1_bat_dir ]; then
            # linux
            STATUS="$( cat /sys/class/power_supply/$_PS1_bat_dir/status )";
            if [ "$STATUS" = "Discharging" ]; then
                bat=$( printf ' v%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            elif [ "$STATUS" = "Charging" ]; then
                bat=$( printf ' ^%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            elif [ "$STATUS" = "Full" ] || [ "$STATUS" = "Unknown" ] && [ "$(cat /sys/class/power_supply/$_PS1_bat_dir/capacity)" -gt "98" ]; then
                bat=$( printf ' =%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            else
                bat=$( printf ' ?%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            fi;
        fi
    fi

    if [[ "$RET" -ne "0" ]]; then
        printf '\001%*s%s\r%s\002%s ' "$(tput cols)" ":( $bat " "^[[0;31;1m" "$RET"
    else
        printf '\001%*s%s\r\002' "$(tput cols)" "$bat "
    fi;
}

_HAS_GIT=$( type 'git' &> /dev/null );

# ps1 git branch
_PS1_git(){
    if ! $_HAS_GIT; then
        return 1;
    fi;
    if [ ! "$( git rev-parse --is-inside-git-dir 2> /dev/null )" ]; then
        return 2;
    fi
    branch="$( git symbolic-ref --short -q HEAD 2> /dev/null )"

    if [ "$branch" ]; then
        printf ' \001%s\002(\001%s\002git\001%s\002)\001%s\002-\001%s\002[\001%s\002%s\001%s\002]\001%s\002' "^[[0;35m" "^[[39m" "^[[35m" "^[[39m" "^[[35m" "^[[32m" "${branch}" "^[[35m" "^[[39m"
    fi;
}

# grml PS1 string
PS1="\n\[\e[F\e[0m\]\$(_PS1_ret)\[\e[34;1m\]${debian_chroot:+($debian_chroot)}\u\[\e[0m\]@\h \[\e[01m\]\w\$(_PS1_git) \[\e[0m\]% "

আমি এখনও রঙগুলিকে কনফিগারযোগ্য করে তুলতে কাজ করছি তবে রঙগুলি এখন যেমন আছে তেমন খুশি।


বর্তমানে পাগল ^[চরিত্র এবং সহজ রঙের স্যুইচিংয়ের জন্য স্থির করে নিয়ে কাজ করছেন :)


এটি Ctrl + [এবং v একসাথে নয়, এটি Ctrl + v এর পরে Ctrl + [।
নিডজেজেকোব


0

স্টাম্পড উত্তরে যোগ করার পদ্ধতি, আমি হাতল রং কিছু লিখেছিলেন ভালো (যদি তারা সঠিকভাবে ঘিরা করছি \[এবং \]। এটি এর কেস-বাই-কেস এবং প্রতিটি ক্ষেত্রে হ্যান্ডেল নয়, কিন্তু এটা আমার PS1 হিসাবে একই সিনট্যাক্স আমার PS1L সেট করতে দেয় এবং PS1R হিসাবে (বর্ণহীন) তারিখটি ব্যবহার করে।

function title {
    case "$TERM" in
    xterm*|rxvt*)
        echo -en "\033]2;$1\007"
        ;;
    *)
        ;;
    esac
}

print_pre_prompt() {
    PS1R=$(date)
    PS1L_exp="${PS1L//\\u/$USER}"
    PS1L_exp="${PS1L_exp//\\h/$HOSTNAME}"
    SHORT_PWD=${PWD/$HOME/~}
    PS1L_exp="${PS1L_exp//\\w/$SHORT_PWD}"
    PS1L_clean="$(sed -r 's:\\\[([^\\]|\\[^]])*\\\]::g' <<<$PS1L_exp)"
    PS1L_exp=${PS1L_exp//\\\[/}
    PS1L_exp=${PS1L_exp//\\\]/}
    PS1L_exp=$(eval echo '"'$PS1L_exp'"')
    PS1L_clean=$(eval echo -e $PS1L_clean)
    title $PS1L_clean
    printf "%b%$(($COLUMNS-${#PS1L_clean}))b\n" "$PS1L_exp" "$PS1R"
}

এখানে এটি গিথুবে রয়েছে : dbarnett / dotfiles / right_prompt.sh । আমি এটি আমার .Bashrc এ এটি ব্যবহার করি:

source $HOME/dotfiles/right_prompt.sh
PS1L='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]'
PS1='\[\033[01;34m\]\w\[\033[00m\]\$ '
PROMPT_COMMAND=print_pre_prompt

দ্রষ্টব্য: আমি PS1R এর পরে একটি নতুন লাইনও যুক্ত করেছি, যা কোনও দৃষ্টিভঙ্গি তৈরি করে না, তবে আপনি যদি আপনার কমান্ডের ইতিহাসে নির্দিষ্ট কমান্ডের মাধ্যমে ফিরে স্ক্রোল করেন তবে প্রম্পটটি গার্ফ হওয়া থেকে বিরত রাখবে বলে মনে হচ্ছে।

আমি নিশ্চিত যে অন্য কেউ এর উপর উন্নতি করতে পারে এবং বিশেষ-কেস-ইনসকে কিছু সাধারণ করতে পারে।


0

এখানে উপর ভিত্তি করে একটি সমাধান পাওয়া যাবে PROMPT_COMMANDএবং tput:

function __prompt_command() {
  local EXIT="$?"             # This needs to be first
  history -a
  local COL=$(expr `tput cols` - 8)
    PS1="💻 \[$(tput setaf 196)\][\[$(tput setaf 21)\]\W\[$(tput setaf 196)\]]\[$(tput setaf 190)\]"
    local DATE=$(date "+%H:%M:%S")
  if [ $EXIT != 0 ]; then
    PS1+="\[$(tput setaf 196)\]\$"      # Add red if exit code non 0
    tput sc;tput cuu1; tput cuf $COL;echo "$(tput setaf 196)$DATE"; tput rc
  else
  PS1+="\[$(tput setaf 118)\]\$"
    tput sc;tput cuu1; tput cuf $COL;echo "$(tput setaf 118)$DATE"; tput rc
  fi
  PS1+="\[$(tput setaf 255)\] "
}
PROMPT_COMMAND="__prompt_command"

যাদু দ্বারা সঞ্চালিত হয়:

tput sc;tput cuu1; tput cuf $COL;echo "$(tput setaf 196)$DATE"; tput rc

যা ভেঙে গেছে:

tput sc                       # saved the cursor position
tput cuu1                     # up one line
tput cuf $COL                 # move $COL characters left
echo "$(tput setaf 196)$DATE" # set the colour and print the date
tput rc                       # restore the cursor position

পিএস 1 এ, tput\ [\] দিয়ে পালানো হয় যাতে এটি প্রদর্শিত দৈর্ঘ্যের মধ্যে গণনা করা হয় না।

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