Hanya tampilkan direktori saat ini dan induk di bash prompt

16

Saya baru mengenal bash dan ingin agar prompt saya menunjukkan sesuatu yang dalam tcsh sepele, namun setelah pencarian google yang baik saya masih belum bisa melakukannya.

Saya ingin prompt saya menyertakan hanya direktori saat ini dan direktori induk seperti ini:

/parent/currentdir $

Dalam tcsh ini dicapai dengan:

set prompt = "%C2 %"

Namun dalam bash sejauh ini saya hanya menemukan bahwa saya harus mengurai pwd untuk mendapatkan hasil yang sama.

Apakah tidak ada cara yang lebih sederhana, seperti melakukan:

export PS1="$(some_command) $" 
twalbaum
sumber
2
Secara teori, PS1='\w \$'; PROMPT_DIRTRIM=2seharusnya memberi Anda setara bash, tetapi itu tidak berfungsi dengan baik pada sistem saya.
Mikel
Ini tidak berfungsi sama sekali pada saya: GNU bash, versi 3.2.57 (1) -release (x86_64-apple-darwin14).
twalbaum
PROMPT_DIRTRIMdiperkenalkan di Bash 4 . Saya baru saja menguji pada Ubuntu 16.04 di bawah WSL dan itu berhasil!
Mike Branski

Jawaban:

18

Fitur kontrol cepat Bash agak statis. Jika Anda ingin lebih banyak kontrol, Anda bisa memasukkan variabel di prompt Anda; pastikan Anda belum mematikan promptvarsopsi .

PS1='${PWD#"${PWD%/*/*}/"} \$ '

Perhatikan tanda kutip tunggal: ekspansi variabel harus terjadi pada saat prompt ditampilkan, bukan pada saat PS1variabel didefinisikan.

Jika Anda ingin lebih mengontrol apa yang ditampilkan, Anda dapat menggunakan pergantian perintah. Misalnya, cuplikan di atas kehilangan ~singkatan untuk direktori home.

PS1='$(case $PWD in
        $HOME) HPWD="~";;
        $HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        $HOME/*) HPWD="~/${PWD##*/}";;
        /*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        *) HPWD="$PWD";;
      esac; printf %s "$HPWD") \$ '

Kode ini agak rumit, jadi alih-alih menempelkannya ke dalam PS1variabel, Anda bisa menggunakan PROMPT_COMMANDvariabel untuk menjalankan kode untuk mengatur HPWDdan kemudian menggunakannya dalam prompt Anda.

PROMPT_COMMAND='case $PWD in
        $HOME) HPWD="~";;
        $HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        $HOME/*) HPWD="~/${PWD##*/}";;
        /*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        *) HPWD="$PWD";;
      esac'
PS1='$HPWD \$'

Karena prompt yang diperpendek hanya berubah pada perubahan direktori, Anda tidak perlu menghitung ulang setiap kali prompt ditampilkan. Bash tidak menyediakan pengait yang berjalan pada perubahan direktori saat ini, tetapi Anda dapat mensimulasikannya dengan menimpa cddan sepupunya.

cd () { builtin cd "$@" && chpwd; }
pushd () { builtin pushd "$@" && chpwd; }
popd () { builtin popd "$@" && chpwd; }
chpwd () {
  case $PWD in
    $HOME) HPWD="~";;
    $HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
    $HOME/*) HPWD="~/${PWD##*/}";;
    /*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
    *) HPWD="$PWD";;
  esac
}
PS1='$HPWD \$'

Perhatikan bahwa Anda tidak perlu, dan tidak boleh, mengekspor PS1, karena ini adalah pengaturan shell, bukan variabel lingkungan. PS1Pengaturan bash tidak akan dimengerti oleh shell lain.

PS Jika Anda ingin pengalaman shell interaktif yang bagus, beralihlah ke zsh , di mana semua ini ( %ekspansi cepat sebagian besar mencakup tcsh's chpwd,, dll.) Adalah fitur asli.

PS1='%2~ %# '
Gilles 'SO- berhenti menjadi jahat'
sumber
2
Ini seharusnya jawaban yang diterima dan paling banyak dipilih.
LarsH
3

Sintaks untuk mendapatkan orang tua dan direktori saat ini diambil dari jawaban Munai .

Namun, seperti yang dicatat oleh Gilles, kode itu hanya menunjukkan direktori saat .bashrcini saat dimuat, tetapi tidak akan berubah saat Anda menavigasi sistem ke folder lain.

Memiliki ini di .bashrcfile Anda membuat prompt diperbarui secara otomatis ke direktori Anda saat ini:

prompt_command () {
    PS1='$(basename $(dirname "$PWD"))/$(basename "$PWD") $ '
}
PROMPT_COMMAND=prompt_command
twalbaum
sumber
1
Apakah mendefinisikan prompt_command()harus melakukan sesuatu sendiri? Bukan untuk saya. Apakah Anda bermaksud juga menggunakan prompt_command()definisi ulang dari cd& co, seperti yang dilakukan Gilles? Atau maksud Anda PROMPT_COMMAND='...'?
LarsH
2
Juga, perintah ini gagal ketika $PWDberisi spasi.
LarsH
1
Terima kasih telah membawa saya kembali ke sini. Dikutip $ PWDs untuk memungkinkan spasi dan termasuk perintah terakhir. Prompt saya saat ini lebih kompleks dari ini, oleh karena itu kebutuhan akan definisi prompt_command. Kalau tidak, PS1 = ... berfungsi pada on.
twalbaum
Adakah ide untuk membersihkan output saat bernavigasi /? Seperti yang tertulis, Anda mendapatkan/// $
ezrock
0

Prompt string dapat dengan mudah diubah bashdengan mengedit variabel shell PS1. Ini adalah singkatan dari Prompt String 1. Info lebih lanjut di sini .

Untuk sekarang jalankan bashcangkang Anda .

vi ~/.bashrc

Tambahkan definisi PS1 dalam file

`export PS1="$(basename $(dirname $PWD))/$(basename $PWD)"`

Lebih banyak tutorial di sini dan di sini , untuk membantu Anda mengubah lebih banyak lagi.

Munai Das Udasin
sumber
1
Saya mengerti bagaimana cara memodifikasi prompt. Pertanyaan saya adalah bagaimana mendapatkan hanya direktori saat ini dan orang tua, bukan seluruh jalur.
twalbaum
@twalbaum mengedit jawaban saya
Munai Das Udasin
senang membantu @twalbaum :)
Munai Das Udasin
1
Ini menetapkan prompt ke direktori saat ini pada saat .bashrcdimuat, prompt tidak akan berubah jika Anda cdke direktori lain! @twalbaum
Gilles 'SO- stop being evil'
@Gilles itu bagi saya.
twalbaum
0

Mungkin lebih sederhana dengan "~" untuk direktori Home.

function PWDN {
  echo "${PWD/#$HOME/~}" | rev | cut -d "/" -f1 -f2 | rev
}
Baskar
sumber
0
export PS1='[\u@\h $(basename $(dirname ${PWD}))/$(basename ${PWD})]\$ '
export PROMPT_COMMAND='echo -ne "\033]0;$(basename $(dirname $PWD))/$(basename ${PWD})\007"'
Marius
sumber