Saya memiliki perilaku aneh pagi ini di terminal bash:
user@home:/home/user$ [ -f /etc/openvpn/client.conf ] && echo true
bash: [: missing «]»
user@home:/home/user$ [ -f /etc/openvpn/client.conf ] && echo true
true
- Perintah pertama disisipkan dari skrip yang diedit dengan gedit.
- Yang kedua diketik langsung di terminal.
Setelah beberapa penggalian, saya menemukan bahwa menghapus karakter ke-30 (ruang antara client.conf dan "]") dan menggantinya dengan spasi membuat perintah berfungsi lagi.
Asumsi saya benar: karakter kosong yang tidak dikenal telah menyelinap ke dalam perintah , tetapi pertanyaannya adalah:
- Bagaimana saya bisa mengungkapkan karakter-karakter itu di terminal sehingga saya bisa men-debug perintah? Dan yang lebih penting:
- Bagaimana saya bisa mencegah hal ini terjadi lagi?
BTW, saya menjalankan Ubuntu 18.04 / Bahasa Perancis, skrip yang saya tempelkan perintah dari dalam drive USB dan mungkin telah diedit pada Windows juga.
Terima kasih atas jawaban Anda yang sangat bagus. Karakter buruknya adalah karakter UTF-8 ruang bebas c2 a0 . Pertanyaan Bagaimana menghapus karakter 'M-BM-' khusus dengan sed memiliki fakta menarik tentang karakter itu.
Yang aneh adalah naskahnya bebas dari karakter ini. Jadi saya tidak tahu dari mana asalnya.
sumber
history 2|xxd
(karenahistory
perintah itu sendiri selalu yang terakhir dalam daftar), atau ketikhistory|grep "CommandWithProblem"|xxd
. Anda dapat menggunakan program tampilan hex lain, bukanxxd
, tetapi ini default ke format yang saya suka.set -x
. Ini akan menunjukkan kepada Anda perintah & bagaimana itu dibagi. Itu tidak selalu mengatakan "karakter buruk di sini", tetapi itu akan menunjukkan kepada Anda bahwa bash tidak terpecah pada karakter itu.Jawaban:
Satu opsi adalah melihat karakter yang Anda coba gunakan dengan hex viewer atau editor.
hexdump
adalah pilihan yang baik jika Anda terbatas pada terminal.Anda bisa lihat di sini bahwa
space
,close-square-brace
,space
benar -0x20
,0x5D
,0x20
.Nilai-nilai ini adalah kode ASCII, ditampilkan dalam heksadesimal . Nilai apa pun di luar rentang
0x20
-0x7E
bukan " karakter yang dapat dicetak " sejauh yang menyangkut ASCII, dan kemungkinan besar tidak akan cocok dengan antarmuka baris perintah.Catatan: Saya menyalin baris " rusak " pertama Anda untuk digunakan dalam
hexdump
contoh di atas, jadi sesuatu telah menggantikan ruang bukan-ASCII dengan ruang ASCII antara sumber asli Anda dan pertanyaan yang Anda buat.Untuk mengulangi ini, lakukan langkah-langkah berikut:
hexdump -Cv <<"EOF"
dan tekanEnterEOF
barisnya sendiri, dan tekanEnterTerminal dan Antarmuka Baris Perintah tidak menangani karakter khusus dengan baik - seperti yang telah Anda temukan. Jika Anda tidak terlalu berhati-hati dalam memformat dokumen, Anda juga akan memiliki masalah dengan Microsoft Word (dan lain-lain) menggunakan " kutipan pintar ", em-strip, daftarnya berlanjut ...
Temukan perbedaan: (bagian atas adalah " kutipan pintar ", bagian bawah adalah " kutipan langsung ")
Di sini, tanda kutip terbuka bukan ASCII kutipan sederhana (
"
), tetapi adalah Unicode / UTF-8 series -0xE2
,0x80
,0x9C
, atauU+201C
- yang terminal tidak akan menangani seperti yang Anda harapkan.Saran Kiwy
cat -A
juga melakukan pekerjaan:Catatan: saat menggunakan
echo "..." | hd
, Anda memiliki peluang bahwa bash akan mengganti bagian-bagian dari string yang Anda coba periksa. Ini khususnya menjadi perhatian ketika mencoba memeriksa komponen-komponen naskah.Misalnya, coba:
Metode ini mengganti komponen dengan teks yang relevan. Untuk menghindari ini, gunakan salah satu pendekatan berikut. Perhatikan penggunaan tanda kutip tunggal (
'
), dan " heredoc yang dikutip " ("EOF"
).sumber
echo "[ -f /etc/openvpn.ovpn ]" | hd
mengembalikan[...] c2 a0 [...]
. Kita dapat melihat ruang non-breaking karakter c2 a0 UT-8Anda bisa menggunakan
cat
dengan-A
pilihan: dari manual:Jadi
cat -A yourscrip.sh
akan menunjukkan karakter yang tidak terlihat dan aneh.sumber
echo "[ -f /etc/openvpn.ovpn ]" | cat -A
mengembalikan[ -f /etc/openvpn/client.ovpnM-BM- ]$
. Kita dapat melihat ruang bebas-pecah karakter M-BM- UT-8echo "<your command>" | hd
harus bekerja. Cari backspace (0x08) atau karakter dengan kode> = 80.echo "<your command>" | wc -b
dan memeriksa apakah hitungannya sesuai dengan yang Anda lihat juga merupakan ide bagus.Menyalin hal-hal dari file yang diproduksi oleh apa pun dengan "Office" di namanya berbahaya, karena perangkat lunak seperti itu sering mengambil kebebasan untuk mengganti karakter: dalam bahasa Prancis, cari tanda kutip ganda digantikan oleh "guillemets", dalam bahasa Inggris untuk tanda kutip polos digantikan oleh mereka buka / tutup setara. Yang paling sulit yang pernah saya temukan adalah 0-lebar ruang tanpa putus di tengah nama file (3 hari downtime server ...).
sumber
hd
pendekhexdump
yang juga disebutkan dalam jawaban Attie.hd
setara denganhexdump -C
.echo "[ -f /etc/openvpn.ovpn ]" | hd
mengembalikan[...] c2 a0 [...]
. Kita dapat melihat ruang non-breaking karakter c2 a0 UT-8Bash, dan shell lain seperti zsh, dapat membuka baris perintah saat ini di editor. Pintasan default untuk bash adalah
C-x C-e
( CtrlX CtrlE), dan terbuka di pertama tersedia$VISUAL
,$EDITOR
dan emacs. Dalam praktiknya ini sangat berharga untuk debugging dan memodifikasi perintah kompleks. Bergantung pada bagaimana Anda melihatnya, zsh lebih ramah daripada bash di sini: ketika editor keluar, bash segera menjalankan perintah, sedangkan zsh menunggu Anda untuk menekan Enter(memberi Anda lebih banyak peluang untuk mengedit perintah).Setelah membuka perintah dalam editor, Anda dapat mengonfigurasi editor Anda untuk menunjukkan karakter non-ASCII secara berbeda.
Misalnya, dengan Vim , menggunakan pengaturan ini:
Atau, mengadaptasi metode jawaban lain:
sumber