Chỉ hiển thị tên thư mục hiện tại (không phải đường dẫn đầy đủ) trên dấu nhắc bash


71

Cách nhắc bash của tôi hiện được cấu hình, nó hiển thị toàn bộ đường dẫn đến thư mục hiện tại. Điều này thật khó chịu khi tôi ở sâu bên trong cây thư mục, vì dấu nhắc trở nên quá dài đến nỗi mọi lệnh sẽ kết thúc thành dòng tiếp theo. Làm thế nào để tôi làm cho nó chỉ hiển thị phần cuối của con đường?

Đây là những gì tôi có trong .bashrc:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007"'
    ;;
*)
    ;;
esac

Câu trả lời:


98

Thay đổi \w(chữ thường) thành \W(chữ hoa):

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]\$ '
                                                                                       ^^
           this one waaaaaay over here ------------------------------------------------+    

Hãy xem Bash Prompt HOWTO để biết nhiều chi tiết thú vị. thí dụ:

user@host:/usr/local/bin$ echo $PS1
${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\w\[\033[00m\]\$ 

user@host:/usr/local/bin$ export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\W\[\033[00m\]\$ '

user@host:bin$

Các PROMPT_COMMANDbiến, nếu được thiết lập, là một lệnh được chạy trước khi hiển thị dấu nhắc quy định tại PS1. Trong trường hợp của bạn, PROMPT_COMMANDđiều hành một echotuyên bố với một số chuỗi ANSI thoátthao tác thanh tiêu đề của một xterm .

Nếu bạn nghi ngờ bạn PROMPT_COMMANDđang ghi đè PS1lời nhắc của mình , bạn có thể thực hiện unsetvà kiểm tra mọi thứ:

$ unset PROMPT_COMMAND

Cuối cùng, hãy chắc chắn rằng bạn đang thay đổi PS1định nghĩa thực sự được sử dụng. Địa điểm phổ biến là /etc/bash.bashrc, /etc/profile, ~/.bashrc, ~/.bash_profile, ~/.profile. Các tệp hệ thống thường (nhưng không phải luôn luôn) chạy trước các tệp người dùng.


Hm ... Tôi sợ nó đã \ w, nhưng nó có vẻ như rằng casetuyên bố sẽ ghi đè nó khi tôi đang trên một xterm, và các vấn đề có vẻ là với PWDtrong PROMPT_COMMANDdòng. Bạn có biết những gì tôi nên đặt ở đó?
hsribei

4
\w(chữ thường) đặt nó thành đường dẫn đầy đủ, \W(chữ hoa) cắt thành bit cuối cùng. PROMPT_COMMAND đang đặt tiêu đề cửa sổ trong xterm. kiểm tra biến TATE của bạn; nếu nó không bắt đầu bằng "xterm" hoặc "rxvt" thì PROMPT_COMMAND thậm chí không được chạy.
quack quixote

Ồ, vâng, duh. Xin lỗi, tôi trộn lẫn chữ hoa và chữ thường. Điều đó đã làm việc. Cảm ơn! :)
hsribei

Câu trả lời chính xác. Hãy chắc chắn rằng bạn khởi động lại để điều này có hiệu lực. Cảm ơn!
Kết hợp

14

Lệnh thay thế bash đơn giản là

${VAR/pattern_to_find/pattern_to_replace}

Để hiển thị thư mục cuối cùng bạn có thể làm ${PWD/*\//}, tức là tìm bất kỳ thứ gì trước và bao gồm cả '' cuối cùng /và thay thế nó không có gì.

Trên máy ubfox của tôi, tôi sử dụng:

export PS1='$(whoami):${PWD/*\//}#'. 

1
Tôi thích câu trả lời này tốt hơn câu trả lời được chấp nhận vì nó chung cho mọi tình huống thay vì chỉ logic phân tích cú pháp đặc biệt của $ PS1. Càng ít công cụ mạnh hơn càng dễ nhớ và sáng tác. :)
David Ellis

4

Giải pháp của tôi là hiển thị ba thư mục trên cùng và dưới cùng 2 khi có nhiều hơn 5

Vì vậy, lời nhắc của tôi (cũng có thông tin khác) trông giống như:

08:38:42 durrantm U2017 /home/durrantm/Dropbox/_/rails/everquote

khi pwd của tôi thực sự

/home/durrantm/Dropbox/93_2016/work/code/ruby__rails/rails/everquote

Dấu nhắc PS1 của tôi được thiết lập như sau:

HOST='\[\033[02;36m\]\h'; HOST=' '$HOST
TIME='\[\033[01;31m\]\t \[\033[01;32m\]'
LOCATION=' \[\033[01;34m\]`pwd | sed "s#\(/[^/]\{1,\}/[^/]\{1,\}/[^/]\{1,\}/\).*\(/[^/]\{1,\}/[^/]\{1,\}\)/\{0,1\}#\1_\2#g"`'
BRANCH=' \[\033[00;33m\]$(git_branch)\[\033[00m\]\n\$ '
PS1=$TIME$USER$HOST$LOCATION$BRANCH

git_branch là một hàm hiển thị nhánh git hiện tại, tôi giữ nó trong dotfiles của mình, đó là:

git_branch () {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
  }

Điều này thật tuyệt! Cảm ơn rất nhiều cho câu trả lời này.
Carlos F

4

Giải pháp của tôi cho vấn đề này hơi khác một chút về cách tôi xuất nó, vì vậy tôi nghĩ tôi sẽ chia sẻ nó ở đây:

Tạo một biến chuỗi nhắc khác; PS5 và xuất chuỗi sau trong tập tin .profile/ của bạn .bash_profile:

\ u : Hiển thị tên người dùng hiện tại.

\ W : In cơ sở của thư mục làm việc hiện tại.

# Display username and current directory only.
export PS5='export PS1="\u:\W$";';

Bây giờ bất cứ khi nào bạn cần sử dụng PS tốc ký, chỉ cần chạy: eval $PS5


Hoặc thậm chí tốt hơn nữa, tạo một bí danh trong .bash_aliasestệp của bạn : (cảm ơn @muru )

alias PS5='export PS1="\u:\W$";';

sourcemột lần nữa, và bây giờ bạn có thể chỉ cần gõ PS5để chuyển đổi.


1
Điều này trông giống như một frankenalias. Tại sao không chỉ sử dụng một bí danh hoặc một chức năng?
muru

1

Chỉ hiển thị tên thư mục hiện tại (không phải đường dẫn đầy đủ) trên dấu nhắc bash

Hầu hết các giải pháp khác không hoạt động với tôi trên tất cả các hệ điều hành chia sẻ tệp chấm của tôi: AIX, Windoze và Linux. Các cổng bash là phiên bản cũ không hỗ trợ cấu trúc nhất định và tôi không muốn đến ngã ba quá trình khác (ví dụ sed, awkvv) mà đáng chú ý là đắt dưới Cygwin.

Sau đây là dài nhưng thực hiện:

# takes a number argument of the number of last dirs to show
function DIR_LAST {
    # read -a didn't seem to work under bash 3
    IFS='/' array=($PWD)
    len=${#array[@]}
    start=$((len - $1))
    # leading / if fewer dir args: /usr/flastname not usr/flastname
    if (( $start <= 1 )); then
        start=1
        echo -n /
    fi
    for (( i = $start; $i < $len; i++ )); do
        if (( $i > $start )); then
            echo -n /
        fi
        echo -n ${array[$i]}
    done
}
export PS1="\$(DIR_LAST 2) {$(hostname)} "

Tôi muốn nó nhổ ra:

/
/usr
/usr/foo
foo/bin

Lưu ý rằng thiếu một dấu gạch chéo hàng đầu trong dòng cuối cùng là cách tôi thích nó. Ngoài ra, bạn có thể nhổ 3 thư mục cuối bằng cách thay đổi arg thành DIR_LAST.

Ngoài ra, tôi đã cố gắng thực hiện điều này với regex và BASH_REMATCHnhưng bash v3 dường như không thích parens và tôi không thể tìm ra cách thoát chúng đúng cách. Thở dài.


0

Tôi tin rằng tùy chọn này dễ dàng hơn nhiều, chỉ bằng cách thực hiện:

echo $PWD | rev | cut -d '/' -f 1 | rev

Vì vậy, gán giá trị này cho biến PS1 trong tệp .bashrc của bạn:

PS1='$(PWD | rev | cut -d '/' -f 1 | rev)'

0
root:~/project#  -> root:~/project(dev)# 

thêm đoạn mã sau vào cuối ~ / .bashrc của bạn

force_color_prompt=yes
color_prompt=yes
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[01;31m\]$(parse_git_branch)\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(parse_git_branch)\$ '
fi
unset color_prompt force_color_prompt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.