Saya punya satu pertanyaan singkat.
Apakah normal bahwa bash (saya menggunakan 4.4.11) tidak menampilkan baris / teks yang dipisahkan / diakhiri dengan polos \r
?
Saya sedikit terkejut melihat perilaku ini:
$ a=$(printf "hello\ragain\rgeorge\r\n")
$ echo "$a"
george
Tapi teks "halo lagi" masih ada, entah bagaimana "tersembunyi":
$ echo "$a" |od -w32 -t x1c
0000000 68 65 6c 6c 6f 0d 61 67 61 69 6e 0d 67 65 6f 72 67 65 0d 0a
h e l l o \r a g a i n \r g e o r g e \r \n
Dan segera setelah kami bermain dengan bash baik-baik saja .... Tapi apakah ini risiko keamanan potensial? Bagaimana jika isi variabel "a" berasal dari dunia luar dan termasuk "perintah buruk" dan bukan hanya halo?
Tes lain, kali ini agak tidak aman:
$ a=$(printf "ls;\rGeorge\n")
$ echo "$a"
George
$ eval "$a"
0 awkprof.out event-tester.log helloworld.c oneshot.sh rightclick-tester.py tmp uinput-simple.py
<directory listing appears with an error message at the end for command George>
Bayangkan yang tersembunyi, rm
bukan yang disembunyikan ls
.
Perilaku yang sama saat menggunakan echo -e:
$ a=$(echo -e "ls;\rGeorge\r\n"); echo "$a"
George
Apakah saya yang melakukan sesuatu yang salah ...?
sumber
bash
; sepenuhnya ke terminal cara "menampilkan" carriage return, atau cara menampilkan karakter yang ditimpa. Sebagai contoh, itu akan sangat valid untuk terminal untuk ditampilkan-\r|
sebagai sesuatu yang menyerupai tanda plus, bukan hanya pipa.bash
hanya menulis byte ke file; terserah siapa pun yang membaca byte tersebut untuk menafsirkannya.printf
, yang merupakan bash built-in command (meskipun juga ada sebagai executable mandiri), menafsirkan yang\r
(urutan dua byte:0x5c
dan0x72
dan menghasilkan kembali kereta (satu byte:0x0d
.) Lalu, ya, terminal menafsirkan byte0x0d
dengan cara yang khusus, tetapi tidak menafsirkan string asli\r
.Di dunia Unix, carriage return (umumnya disandikan seperti
\r
dalam bahasa pemrograman) adalah karakter kontrol yang tidak biasa. Anda dapat memiliki carriage return di dalam baris teks, seperti karakter lain selain dari feed baris (juga disebut baris baru ), yang menandai akhir baris.Secara khusus, dalam skrip bash, carriage return adalah kata biasa karakter penyusunnya, seperti huruf dan angka. Setiap efek khusus dari carriage return berasal dari terminal, bukan dari shell.
Pengembalian carriage adalah karakter kontrol . Ketika Anda mencetaknya ke terminal, alih-alih menampilkan mesin terbang , terminal melakukan beberapa efek khusus. Untuk carriage return, efek khusus adalah memindahkan kursor ke awal baris saat ini. Jadi, jika Anda mencetak garis yang berisi carriage return di tengah, maka efeknya adalah bahwa paruh kedua ditulis di atas setengah pertama.
Beberapa karakter kontrol lainnya memiliki efek khusus: karakter backspace menggerakkan kursor ke kiri dengan satu posisi. Karakter bel menyebabkan terminal mengeluarkan suara atau menarik perhatian pengguna. Karakter pelarian memulai urutan pelarian yang dapat memiliki semua jenis efek khusus.
Jika Anda menampilkan output yang tidak dipercaya, Anda perlu menggosok atau melarikan diri karakter kontrol. Tidak hanya carriage return, tetapi juga beberapa lainnya, khususnya karakter escape, yang dapat menyebabkan semua jenis efek buruk. Lihat Bisakah “memelihara” file menjadi risiko keamanan potensial? dan Bagaimana cara menghindari serangan berurutan di terminal? untuk lebih lanjut tentang topik ini.
sumber
Anda dapat melihat carriage return dalam variabel bash menggunakan
printf
fungsi dengan%q
format.Sumber dan bacaan lebih lanjut:
sumber