Apa yang Anda maksud dengan 'bukan baris perintah biasa'? echobiasanya shell builtin, tetapi biasanya juga ada /usr/bin/echo. Ini -ebukan POSIX, tetapi tersedia misalnya dengan bash. Tolong beri lebih detail apa yang Anda maksud dengan 'mereka masih tidak berfungsi'. Apa perilaku yang diharapkan?
maxschlepzig
Saya ingin mencetak -e menggunakan gema. Ada saran?
Sorotan Pabrik
3
pertimbangkan untuk menggunakan printf, ini lebih portabel.
Michael Durrant
1
Anehnya, echo -- -etidak berhasil juga. Secara konvensional (setidaknya dengan utilitas GNU) tanda hubung ganda menunjukkan akhir dari opsi, dengan sisanya disimpan sebagai argumen literal.
Wil Cooley
6
echogila lagi. Jika orang hanya akan menggunakan printfdan tidak pernah melihat ke belakang.
Jens
Jawaban:
9
dengan baris baru
echo -en '-e\n'
tanpa baris baru
echo -e '-e\c'
dengan spasi di sekitar:
echo '-e '
echo ' -e'
menggunakan backspace (terima kasih kepada Joseph R.):
echo -e ' \b-e'
(itu memang menghasilkan SPC BS - e LF, tetapi ketika dikirim ke terminal yang diterjemahkan -esaat BS memindahkan kursor kembali satu kolom ke kiri menyebabkan -menimpa SPC)
Perilaku bash's echobuiltin mungkin tergantung pada versi bash. Itu juga tergantung pada lingkungan ( POSIXLY_CORRECT, SHELLOPTSdan BASHOPTSvariabel), opsi ( posix, xpg_echo), opsi membangun dan argv[0]( shvs bash). Di sini diuji dengan GNU bash 4.2.53(1), build default, opsi default, lingkungan kosong, dipanggil sebagai bash. Bekerja dengan zsh 5.0.5.
Mengapa "pemecahan masalah" yang buruk ini tidak diterima? Charles Duffy di bawah ini memiliki jawaban yang tepat: gunakan printf dan lupakan masalah seperti itu untuk selamanya.
Jens
7
Jens: karena OP bertanya bagaimana melakukannya dengan echoperintah. Sikap tidak perlu.
ctc
1
echo -e ' \b-e'output space-backspace-dash-e. Hanya ditampilkan di terminal yang akan memberi Anda ilusi bahwa itu adalah dash-e.
Stéphane Chazelas
1
@ CharlesDuffy, echo -e "\0-e"apakah output NUL-dash-e. Hanya saja terminal mengabaikan karakter NUL (NUL bahkan digunakan untuk dikirim ke beberapa terminal (yang tidak mendukung kontrol aliran) untuk memberi mereka waktu untuk melakukan hal-hal panjang lainnya seperti carriage return. Lihat bagian di bawah Delay and Padding in terminfo(5).)
Stéphane Chazelas
25
Solusi terbaik bukanlah menggunakan echo, melainkan menggunakan printf.
printf '%s\n'-e
Ini berfungsi dengan variabel arbitrer:
var=-e
printf '%s\n'"$var"
... artinya Anda tidak perlu melakukan persiapan / modifikasi khusus di tempat lain dalam kode Anda berdasarkan pengetahuan bahwa nilainya akan menjadi echod.
Secara kebetulan, spesifikasi perintah POSIX shell untukecho menyatakan bahwa ia tidak dapat diport sebagaimana diimplementasikan, dan berisi catatan tentang subjek itu:
Tidak mungkin untuk menggunakan gema secara portable di semua sistem POSIX kecuali keduanya -n (sebagai argumen pertama) dan urutan escape dihilangkan.
Utilitas printf dapat digunakan dengan mudah untuk meniru perilaku tradisional dari utilitas echo sebagai berikut (dengan asumsi bahwa IFS memiliki nilai standar atau tidak disetel):
Gema Sistem V yang bersejarah dan persyaratan implementasi XSI dalam volume POSIX.1-2008 ini setara dengan:
Menariknya, catatan POSIX memang mengatakan bahwa echo -eitu portabel. Dikatakan -nharus dihindari, dan urutan melarikan diri harus dihindari. echo -emenghindari keduanya. Tetapi seperti yang Anda sebutkan di bagian terakhir dari jawaban Anda, pada sistem GNU, echotidak repot untuk menyesuaikan dengan POSIX sama sekali secara default, dan POSIX hanya mencatat portabilitas di seluruh sistem POSIX.
hvd
@ Hvd, saya tidak melihat -etercakup dalam bagian spesifikasi yang saya tautkan . Bisakah Anda memberikan tautan atau kutipan yang menutupnya?
Charles Duffy
Kurangnya menyebutkan yang mengatakannya. :) Ini mencantumkan penggunaan yang tidak portabel, dan -etidak disebutkan, begitu -ejuga portabel (sekali lagi, di seluruh sistem POSIX). Agar adil, apa yang Anda kutip adalah informatif, tetapi teks normatif mengatakan hal yang sama: "Jika operan pertama adalah -n, atau jika salah satu operan berisi karakter <backslash>, hasilnya ditentukan-implementasi."
hvd
2
@ DVD, sebaliknya. Untuk melakukan seperti yang ditentukan, echoperlu memancarkan semua argumen tanpa perilaku yang ditentukan oleh standar. Jadi - tidak seperti hampir semua alat baris perintah lainnya yang dicakup oleh spesifikasi POSIX - echosebenarnya menentukan perilaku untuk argumen yang tidak diberikan: Mencetaknya. Tidak ada ruang untuk menambahkan bendera baru tanpa melanggar spesifikasi.
Charles Duffy
2
@hvd, ... dalam hal ini, lihat OPTIONSbagian, di mana itu ditetapkan dalam hitam dan putih: Implementations shall not support any options.
Charles Duffy
9
Dengan GNU echo's -edengan kode ASCII untuk karakter:
$ /bin/echo -e '\055'e-e
055adalah nomor ASCII oktal untuk -(lihat man asciiuntuk referensi cepat).
/bin/echomemang ditentukan POSIX. Namun, interpretasinya tentang urutan pelepasan oktal adalah ekstensi XSI ke spesifikasi dasar.
Charles Duffy
@CharlesDuffy Memang, saya salah bicara. +1 untuk printf (pikiran pertama saya juga). Mengingat bahwa -emerupakan perpanjangan, namun, apakah ada cara untuk memaksa perilaku POSIX murni echo? Itu akan menghilangkan semua ketidakpastian atas ini, saya pikir.
muru
2
Sebenarnya ya! Mengekspor POSIXLY_CORRECT=1akan menghasilkan perilaku yang sesuai dengan POSIX untuk GNU /bin/echo.
Charles Duffy
+1 Terima kasih, baik untuk mengetahui agar skrip Anda tetap portabel dan "independen-Linux-mandiri" (yaitu juga mengerjakan pro workstation di tempat kerja).
syntaxerror
@ Kusalananda lupa tentang ini.
muru
3
Sementara solusi yang jelas, standar, dan yang direkomendasikan adalah menggunakan printf, melakukannya dengan echobisa sangat rumit tergantung pada implementasinya (tidak sesulit seperti -nsaat ini).
Sesuai POSIX.2017 echos
POSIX membutuhkanecho -e output -e<newline>. Jadi itu adil
echo -e
sana. Sesuai dengan POSIX echodalam hal itu (kebanyakan dari mereka tidak sesuai dengan POSIX dalam hal lain, spesifikasi POSIX hampir tidak berguna ketika menyangkut echo) meliputi:
yang echobuiltin dari bashketika kedua xpg_echodan posixpilihan telah diaktifkan (pada saat runtime atau membangun waktu seperti untuk /bin/shApple MacOS). set -o posix; shopt -s xpg_echo( posixopsi ini juga dapat diaktifkan jika dipanggil saat shatau ketika POSIXLY_CORRECTatau SHELLOPTS=posixdi lingkungan).
yang /bin/echosistem bersertifikat UNIX (AIX, MacOS, Solaris setidaknya) dan paling BSD
yang echobuiltin dari dash, ksh88, Bourne shell, csh, tcsh, mewah, rc, es, akanga
GNU echo( /bin/echopada sistem GNU) saat POSIXLY_CORRECTberada di lingkungan.
yang echobuiltin dari mkshdan beberapa pdksh-atau diperoleh lain ketika mereka posixpilihan diaktifkan.
yang echobuiltin dari yashsaat $ECHO_STYLEini baik disetel atau salah SYSV, XSI, BSD, DASH,RAW
implementasi yang mendukung -e
Termasuk echopenelitian Unix V8 (dari mana asalnya), GNU, busybox, yang echobuiltin dari bash, zsh, pdkshdan turunannya, fish, beberapa ashkerang berbasis seperti busybox shatau shbeberapa BSD, versi terbaru ksh93(pada beberapa sistem, dan dengan beberapa nilai $PATH) dengan pengaturan default mereka, yashdengan $ECHO_STYLEsalah satu GNUatau ZSH:
echo -e '-e\n\c'
Implementasi yang mendukung -eselalu mendukung -n, jadi:
echo -ne '-e\n'
akan bekerja juga.
zsh
zshIni echoadalah satu-satunya implementasi yang saya tahu bahwa mendukung end-of-opsi penanda ( -).
echo --e
Menjadikannya satu-satunya shell mirip Bourne echoyang dapat menampilkan data sewenang-wenang (juga karena itu satu-satunya yang mendukung byte NUL dalam variabel dan argumen bawaannya) dengan echo -E - "$data")
Kecuali untuk masalah NUL-byte, implementasi lain yang dapat menampilkan data sewenang-wenang adalah FreeBSD atau macOS di /bin/echomana Anda dapat melakukan:
/bin/echo "$data
\c"
(dalam implementasi itu, \chanya dikenali pada akhirnya, dan tidak ada urutan escape lainnya yang didukung).
Dan ini yash:
ECHO_STYLE=RAW echo "$data"
(meskipun perhatikan bahwa yashvariabel hanya dapat menampung teks, jadi bukan urutan byte acak di lokal di mana tidak semua urutan byte dapat membentuk karakter yang valid seperti pada mereka yang menggunakan UTF-8 sebagai charmap mereka).
echo
biasanya shell builtin, tetapi biasanya juga ada/usr/bin/echo
. Ini-e
bukan POSIX, tetapi tersedia misalnya dengan bash. Tolong beri lebih detail apa yang Anda maksud dengan 'mereka masih tidak berfungsi'. Apa perilaku yang diharapkan?echo -- -e
tidak berhasil juga. Secara konvensional (setidaknya dengan utilitas GNU) tanda hubung ganda menunjukkan akhir dari opsi, dengan sisanya disimpan sebagai argumen literal.echo
gila lagi. Jika orang hanya akan menggunakanprintf
dan tidak pernah melihat ke belakang.Jawaban:
dengan baris baru
tanpa baris baru
dengan spasi di sekitar:
menggunakan backspace (terima kasih kepada Joseph R.):
(itu memang menghasilkan SPC BS - e LF, tetapi ketika dikirim ke terminal yang diterjemahkan
-e
saat BS memindahkan kursor kembali satu kolom ke kiri menyebabkan-
menimpa SPC)Perilaku
bash
'secho
builtin mungkin tergantung pada versi bash. Itu juga tergantung pada lingkungan (POSIXLY_CORRECT
,SHELLOPTS
danBASHOPTS
variabel), opsi (posix
,xpg_echo
), opsi membangun danargv[0]
(sh
vsbash
). Di sini diuji denganGNU bash 4.2.53(1)
, build default, opsi default, lingkungan kosong, dipanggil sebagaibash
. Bekerja denganzsh 5.0.5
.sumber
echo -e 'x\b-e'
echo
perintah. Sikap tidak perlu.echo -e ' \b-e'
output space-backspace-dash-e. Hanya ditampilkan di terminal yang akan memberi Anda ilusi bahwa itu adalah dash-e.echo -e "\0-e"
apakah outputNUL-dash-e
. Hanya saja terminal mengabaikan karakter NUL (NUL bahkan digunakan untuk dikirim ke beberapa terminal (yang tidak mendukung kontrol aliran) untuk memberi mereka waktu untuk melakukan hal-hal panjang lainnya seperti carriage return. Lihat bagian di bawah Delay and Padding interminfo(5)
.)Solusi terbaik bukanlah menggunakan
echo
, melainkan menggunakanprintf
.Ini berfungsi dengan variabel arbitrer:
... artinya Anda tidak perlu melakukan persiapan / modifikasi khusus di tempat lain dalam kode Anda berdasarkan pengetahuan bahwa nilainya akan menjadi
echo
d.Secara kebetulan, spesifikasi perintah POSIX shell untuk
echo
menyatakan bahwa ia tidak dapat diport sebagaimana diimplementasikan, dan berisi catatan tentang subjek itu:(Penekanan ditambahkan).
Yang mengatakan, pada sistem GNU, ada alternatif: Meminta perilaku yang memenuhi standar.
sumber
echo -e
itu portabel. Dikatakan-n
harus dihindari, dan urutan melarikan diri harus dihindari.echo -e
menghindari keduanya. Tetapi seperti yang Anda sebutkan di bagian terakhir dari jawaban Anda, pada sistem GNU,echo
tidak repot untuk menyesuaikan dengan POSIX sama sekali secara default, dan POSIX hanya mencatat portabilitas di seluruh sistem POSIX.-e
tercakup dalam bagian spesifikasi yang saya tautkan . Bisakah Anda memberikan tautan atau kutipan yang menutupnya?-e
tidak disebutkan, begitu-e
juga portabel (sekali lagi, di seluruh sistem POSIX). Agar adil, apa yang Anda kutip adalah informatif, tetapi teks normatif mengatakan hal yang sama: "Jika operan pertama adalah -n, atau jika salah satu operan berisi karakter <backslash>, hasilnya ditentukan-implementasi."echo
perlu memancarkan semua argumen tanpa perilaku yang ditentukan oleh standar. Jadi - tidak seperti hampir semua alat baris perintah lainnya yang dicakup oleh spesifikasi POSIX -echo
sebenarnya menentukan perilaku untuk argumen yang tidak diberikan: Mencetaknya. Tidak ada ruang untuk menambahkan bendera baru tanpa melanggar spesifikasi.OPTIONS
bagian, di mana itu ditetapkan dalam hitam dan putih:Implementations shall not support any options
.Dengan GNU
echo
's-e
dengan kode ASCII untuk karakter:055
adalah nomor ASCII oktal untuk-
(lihatman ascii
untuk referensi cepat).sumber
/bin/echo
memang ditentukan POSIX. Namun, interpretasinya tentang urutan pelepasan oktal adalah ekstensi XSI ke spesifikasi dasar.-e
merupakan perpanjangan, namun, apakah ada cara untuk memaksa perilaku POSIX murniecho
? Itu akan menghilangkan semua ketidakpastian atas ini, saya pikir.POSIXLY_CORRECT=1
akan menghasilkan perilaku yang sesuai dengan POSIX untuk GNU/bin/echo
.Sementara solusi yang jelas, standar, dan yang direkomendasikan adalah menggunakan
printf
, melakukannya denganecho
bisa sangat rumit tergantung pada implementasinya (tidak sesulit seperti-n
saat ini).Sesuai POSIX.2017
echo
sPOSIX membutuhkan
echo -e
output-e<newline>
. Jadi itu adilsana. Sesuai dengan POSIX
echo
dalam hal itu (kebanyakan dari mereka tidak sesuai dengan POSIX dalam hal lain, spesifikasi POSIX hampir tidak berguna ketika menyangkutecho
) meliputi:echo
builtin daribash
ketika keduaxpg_echo
danposix
pilihan telah diaktifkan (pada saat runtime atau membangun waktu seperti untuk/bin/sh
Apple MacOS).set -o posix; shopt -s xpg_echo
(posix
opsi ini juga dapat diaktifkan jika dipanggil saatsh
atau ketikaPOSIXLY_CORRECT
atauSHELLOPTS=posix
di lingkungan)./bin/echo
sistem bersertifikat UNIX (AIX, MacOS, Solaris setidaknya) dan paling BSDecho
builtin daridash
,ksh88
, Bourne shell, csh, tcsh, mewah, rc, es, akangaecho
(/bin/echo
pada sistem GNU) saatPOSIXLY_CORRECT
berada di lingkungan.echo
builtin darimksh
dan beberapa pdksh-atau diperoleh lain ketika merekaposix
pilihan diaktifkan.echo
builtin dariyash
saat$ECHO_STYLE
ini baik disetel atau salahSYSV
,XSI
,BSD
,DASH
,RAW
implementasi yang mendukung
-e
Termasuk
echo
penelitian Unix V8 (dari mana asalnya), GNU, busybox, yangecho
builtin daribash
,zsh
,pdksh
dan turunannya,fish
, beberapaash
kerang berbasis seperti busyboxsh
ataush
beberapa BSD, versi terbaruksh93
(pada beberapa sistem, dan dengan beberapa nilai$PATH
) dengan pengaturan default mereka,yash
dengan$ECHO_STYLE
salah satuGNU
atauZSH
:Implementasi yang mendukung
-e
selalu mendukung-n
, jadi:akan bekerja juga.
zsh
zsh
Iniecho
adalah satu-satunya implementasi yang saya tahu bahwa mendukung end-of-opsi penanda (-
).Menjadikannya satu-satunya shell mirip Bourne
echo
yang dapat menampilkan data sewenang-wenang (juga karena itu satu-satunya yang mendukung byte NUL dalam variabel dan argumen bawaannya) denganecho -E - "$data"
)Kecuali untuk masalah NUL-byte, implementasi lain yang dapat menampilkan data sewenang-wenang adalah FreeBSD atau macOS di
/bin/echo
mana Anda dapat melakukan:(dalam implementasi itu,
\c
hanya dikenali pada akhirnya, dan tidak ada urutan escape lainnya yang didukung).Dan ini
yash
:(meskipun perhatikan bahwa
yash
variabel hanya dapat menampung teks, jadi bukan urutan byte acak di lokal di mana tidak semua urutan byte dapat membentuk karakter yang valid seperti pada mereka yang menggunakan UTF-8 sebagai charmap mereka).sumber
Gunakan
-n
untuk menghindari baris baru:sumber
zsh
mana-
akhir pembatas opsi atau pada semuaecho
implementasi yang tidak mendukung-n
(yang mendukung-e
juga mendukung-n
)