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 -e
bendera 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.
Jawaban:
$'…'
adalah fitur ksh93 yang juga hadir dalam zsh, bash, mksh, FreeBSD sh dan dalam beberapa build dari BusyBox sh (BusyBox ash built withENABLE_ASH_BASH_COMPAT
). Itu belum ada dalam bahasa sh POSIX./bin/sh
Shell 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.Perhatikan bahwa
\e
ini tidak portabel. Ini didukung oleh banyak implementasiprintf
tetapi 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.
sumber
\e
tidak didukungdash
?dash -c 'printf "\e[1;31m"; type printf; printf "\e[m"'
akan mencetakprintf is a shell builtin
dengan huruf tebal merah di sini (dash-0.5.8). Shell yang tidak mendukung\e
adalahyash
.\e[1;31mprintf is a shell builtin \e[m
sini. 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.Tingkat
$'...'
dukungan juga perlu dipertimbangkan ketika melakukan porting. The Proposal POSIX Folks' untuk menempatkan ini dalam POSIX sh menyebutkan orang tertentu:Dari apa yang saya dapatkan di sini di Debse Bullseye saya,
ksh2020
dari AT&T mengerti$'\U1F600'
. Ini adalah satu-satunya shell Korn "resmi" yang bisa saya dapatkan di distro baru ini.mksh
menguraikannya 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.sumber
$'...'
dan iirc itu yang pertama kali melakukannya.ksh2020
bukan dari AT&T. Beberapa orang, satu dari Red Hat, pada dasarnya membajak pohon AT&T AST github beberapa tahun yang lalu dan mengklaim mengendalikanksh93
perkembangan masa depan