Apakah cangkang selain Bash dan Zsh mendukung kutipan ANSI-C? mis. $ 'string'

13

Saya memiliki skrip shell yang menggunakan yang berikut ini untuk mencetak tanda centang hijau di outputnya:

col_green="\e[32;01m"
col_reset="\e[39;49;00m"

echo -e "Done ${col_green}✓${col_reset}"

Setelah membaca tentang Bash's ANSI-C Quoting , saya menyadari saya bisa menggunakannya ketika mengatur variabel warna saya dan menghapus -ebendera dari gema saya .

col_green=$'\e[32;01m'
col_reset=$'\e[39;49;00m'

echo "Done ${col_green}✓${col_reset}"

Ini tampaknya menarik, karena itu berarti pesan dicetak dengan benar apakah itu diteruskan ke gema bawaan Bash atau util eksternal /bin/echo(saya menggunakan MacOS).

Tetapi apakah ini membuat skrip kurang portabel? Saya tahu Bash dan Zsh mendukung gaya mengutip ini, tetapi saya tidak yakin tentang yang lain.

ivan
sumber
Ya, karena ketika hanya ksh dan variasinya yang mendukungnya untuk saat ini. Tapi kutipan IIRC, ANSI-C akan ada dalam spesifikasi POSIX berikutnya.
cuonglm
ksh doc: debian ksh (1)
Arthur2e5

Jawaban:

12

$'…'adalah fitur ksh93 yang juga hadir dalam zsh, bash, mksh, FreeBSD sh dan dalam beberapa build dari BusyBox sh (BusyBox ash built with ENABLE_ASH_BASH_COMPAT). Itu belum ada dalam bahasa sh POSIX. /bin/shShell seperti Bourne umum yang tidak memilikinya termasuk dash (yang secara default di Ubuntu antara lain), ksh88, shell Bourne, NetBSD sh, yash, turunan dari pdksh selain mksh dan beberapa build dari BusyBox.

Cara portabel untuk mendapatkan huruf backslash dan backslash-octal diuraikan sebagai karakter kontrol adalah dengan menggunakan printf. Ini hadir pada semua sistem yang mendukung POSIX.

esc=$(printf '\033') # assuming an ASCII (as opposed to EBCDIC) system
col_green="${esc}[32;01m"

Perhatikan bahwa \eini tidak portabel. Ini didukung oleh banyak implementasi printftetapi tidak oleh yang ada di dash¹. Gunakan kode oktal sebagai gantinya.

¹ Ini didukung dalam Debian dan turunannya yang mengirimkan setidaknya 0,5,8-2,4, misalnya sejak Debian stretch dan Ubuntu 17,04.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Anda yakin \etidak didukung dash? dash -c 'printf "\e[1;31m"; type printf; printf "\e[m"'akan mencetak printf is a shell builtindengan huruf tebal merah di sini (dash-0.5.8). Shell yang tidak mendukung \eadalah yash.
Mosvy
@mosvy Mencetak di \e[1;31mprintf is a shell builtin \e[msini. Ubuntu 16.04, dash 0.5.8-2.1ubuntu2. Mencetak warna merah pada Ubuntu 18.04 dengan dash 0.5.8-2.10. Sepertinya Ubuntu membuat tambalan untuk mendukungnya.
Gilles 'SANGAT berhenti menjadi jahat'
Ya, maaf, sepertinya itu tambalan debian (9,7 stretch). ini aslinya.
Mosvy
0

Tingkat $'...'dukungan juga perlu dipertimbangkan ketika melakukan porting. The Proposal POSIX Folks' untuk menempatkan ini dalam POSIX sh menyebutkan orang tertentu:

stephane: ksh93 adalah shell $ '...' berasal dari (sementara $'\uxxxx'[ dan$'\Uxxxxxxxx' ] berasal dari zsh: http://www.zsh.org/mla/workers/2003/msg00223.html ) [^]

Dari apa yang saya dapatkan di sini di Debse Bullseye saya, ksh2020dari AT&T mengerti $'\U1F600'. Ini adalah satu-satunya shell Korn "resmi" yang bisa saya dapatkan di distro baru ini.

mkshmenguraikannya tetapi gagal sepenuhnya dengan U + FFFE. Karena tidak mengeluh tentang kesalahan sintaksis pasti ada sesuatu yang salah dengan pemahaman tentang Unicode. Ini menangani dengan $'\U01F60'baik.

Arthur2e5
sumber
Sayangnya, sebagai akibat kudeta baru-baru ini ksh2020 telah menghilang. Tapi ya, ksh93 asli memang mendukung $'...'dan iirc itu yang pertama kali melakukannya.
Mosvy
@ Arthur2e5. ksh2020bukan dari AT&T. Beberapa orang, satu dari Red Hat, pada dasarnya membajak pohon AT&T AST github beberapa tahun yang lalu dan mengklaim mengendalikan ksh93perkembangan masa depan
fpmurphy