Keluar dari karakter yang tidak dicetak dalam fungsi untuk Bash prompt


22

Dalam Bash Prompt (variabel PS1), saya memanggil fungsi untuk berpotensi menambahkan teks ke prompt: export PS1="\u@\h \$(my_function) \$ "

Namun, fungsi di prompt berisi kode warna ANSI yang berubah berdasarkan output fungsi (kadang-kadang merah, kadang-kadang hijau). Menambahkan " \[" ke variabel PS1 harus lolos dari kode-kode itu sebagai non-pencetakan, tetapi jika saya melakukan suatu echofungsi, " \[" akan dicetak secara harfiah di prompt.

Bagaimana saya bisa lepas kode warna ANSI ini dari dalam fungsi untuk digunakan dalam bash prompt?

Jawaban:


34

The readline perpustakaan menerima \001dan \002(ASCII SOH dan STX ) sebagai pembatas teks non-printable. Ini juga berfungsi di aplikasi apa pun yang menggunakan readline .

Dari lib/readline/display.c:243dalam kode sumber bash :

243 /* Current implementation:
244         \001 (^A) start non-visible characters
245         \002 (^B) end non-visible characters
246    all characters except \001 and \002 (following a \001) are copied to
247    the returned string; all characters except those between \001 and
248    \002 are assumed to be `visible'. */

The pesta -specific \[dan \]yang sebenarnya diterjemahkan ke \001dan \002di y.tab.c:7640.


Catatan: Jika Anda menggunakan bash 's printfatau echo -e, dan jika teks Anda memiliki \001atau \002segera sebelum angka, Anda akan menekan bug bash yang menyebabkannya memakan satu digit terlalu banyak saat memproses lolos oktal - yaitu, \00142akan ditafsirkan sebagai oktal 014 (diikuti oleh ASCII "2"), bukannya oktal yang benar 01 (diikuti oleh ASCII "42"). Untuk alasan ini, gunakan versi heksadesimal \x01dan \x02sebagai gantinya.


Itu berhasil! echo -e "\001\e[31m\002RED"bekerja seperti yang diharapkan. Terima kasih!
MidnightLightning

Maaf untuk membangkitkan kembali jawaban, tapi apa yang setara di dash / ash / sh?
Hosh Sadiq

@ Wah Jika mereka menggunakan readline, \001dan \002akan bekerja. Kalau tidak, saya tidak yakin. Dash misalnya tidak menggunakan readline .
wjandrea

1

Inilah jawaban lengkap yang bagus. Saya harus melakukan lebih banyak penggalian untuk mencari tahu ke mana \ 001 dll harus pergi. Semoga ini membantu.

# Color prompt for git
reset=$(tput sgr0)
boldgreen=$(tput setaf 2)$(tput bold)
cyan=$(tput sgr0)$(tput setaf 6)
boldred=$(tput setaf 1)$(tput bold)
boldwhite=$(tput setaf 7)$(tput bold)
boldyellow=$(tput setaf 3)$(tput bold)

PARENCLR=$'\001\e[0;36m\002'
BRANCHCLR=$'\001\e[1;33m\002'

alias branchname="git branch 2>/dev/null | grep '*' | sed 's/* \(.*\)/ ${PARENCLR}(${BRANCHCLR}\1${PARENCLR}\)/'"

GIT_STATUS='$(branchname)'

PROMPT_CHAR="\$"
PS1="\[$boldgreen\]\u\[$cyan\]::\[$boldred\]\h \[$cyan\]{\[$boldwhite\].../\W\[$cyan\]}\[$reset\]$GIT_STATUS\[$reset\]$PROMPT_CHAR "

Cara saya mengaturnya di sini, kurung cabang git hanya muncul jika Anda berada di cabang git, jika tidak maka kosong.


0

Berdasarkan jawaban grawity , berikut ini akan menyertakan urutan kontrol ANSI di ASCII SOH( ^A) dan STX( ^B) yang setara dengan \[dan \]masing - masing:

function readline_ANSI_escape() {
  if [[ $# -ge 1 ]]; then
    echo "$*"
  else
    cat  # Read string from STDIN
  fi | \
  perl -pe 's/(?:(?<!\x1)|(?<!\\\[))(\x1b\[[0-9;]*[mG])(?!\x2|\\\])/\x1\1\x2/g'
}

Gunakan seperti:

$ echo $'\e[0;1;31mRED' | readline_ANSI_escape

Atau:

$ readline_ANSI_escape "$string"

Sebagai bonus, menjalankan fungsi beberapa kali tidak akan keluar lagi dari kode kontrol yang sudah lolos.


-2

Jika Anda ingin menggunakannya dalam prompt, maka Anda perlu melakukan itu \[. Tetapi jika Anda ingin menggunakannya dalam gema, Anda harus menggunakannya \033[.


Hmmm ... Menambahkan \ 033 [sebelum perintah ANSI ("\ e [31m") dan \ 033] setelah itu tampaknya membuat karakter yang dicetak berikutnya dalam prompt tidak dicetak.
MidnightLightning

1
Anda tidak ingin melakukan \ 033] setelah itu. \ 033 [31m memulai warna, setelah itu Anda harus mengaturnya kembali dengan \ 033 [0m
Wuffers
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.