BASH ve Satır Başı Davranışı


11

Kısa bir sorum var.
Bash'ın (4.4.11 kullanıyorum) düz / ayrılmış / sonlu satır / metin görüntülememesi normal \rmi?

Bu davranışı görmek biraz şaşırdı:

$ a=$(printf "hello\ragain\rgeorge\r\n")
$ echo "$a"
george

Ama "tekrar merhaba" metni hala orada, bir şekilde "gizli":

$ 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

Ve bash ile oynadığımızda sorun yok ... Ama bu potansiyel bir güvenlik riski midir? "A" değişkeninin içeriği dış dünyadan geliyorsa ve sadece merhaba yerine "kötü komutlar" içeriyorsa ne olur?

Başka bir test, bu sefer biraz güvensiz:

$ 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>

Bir gizli rmyerine bir gizli düşünün ls.

Echo -e kullanırken aynı davranış:

$ a=$(echo -e "ls;\rGeorge\r\n"); echo "$a"
George

Yanlış bir şey yapan ben miyim ...?

Yanıtlar:


20

Sizin echo "$a"baskılar "Merhaba", sonra tekrar (nedir satırın başına gider \r, tekrar geri gider, "Tekrar" "George" baskılar yapar) tekrar gider ve sonraki satıra geçer ( \n). Her şey gayet normaldir, ancak chepner'ın işaret ettiği gibi, Bash ile ilgisi yoktur: \rve \nterminal tarafından yorumlanır, Bash tarafından değil (bu yüzden komutu verdiğinizde tam çıktıyı alırsınız od).

Bunu daha iyi görebilirsiniz

$ a=$(printf "hellooooo\r  again,\rgeorge\r\n")
$ echo "$a"

çünkü bu üzerine yazılan metnin sonunu bırakacaktır:

georgen,o

Bunu, komutları gizlemek için gerçekten kullanamazsınız, yalnızca çıktıları (ve yalnızca yeterli karakterle üzerine yazacağınızdan emin olursanız), evalgösterdiğiniz gibi kullanmazsanız (ancak evalgenellikle kullanılması önerilmez). Daha tehlikeli bir hile, web sitelerinden kopyalanması ve yapıştırılması amaçlanan komutları maskelemek için CSS kullanmaktır .


Yeterince açık, teşekkürler. Testimde son iki kelimeyi tamamen yazabilecek kadar şanssız / şanssızım.
George Vasiliou

2
Ancak bunun gerçekten bir ilgisi olmadığını unutmayın bash; taşıyıcıya geri dönüşün nasıl görüntüleneceği veya üzerine yazılan karakterlerin nasıl görüntüleneceği tamamen terminale bağlıdır . Örneğin, bir terminalin -\r|sadece bir borudan ziyade artı işaretine benzeyen bir şey olarak gösterilmesi mükemmel bir şekilde geçerli olacaktır .
chepner

@chepner Bilmek güzel! Paylaşım için teşekkürler. Bunun sadece bir bash davranışı olduğunu düşündüm.
George Vasiliou

@GeorgeVasiliou Hayır, bashsadece baytları bir dosyaya yazar; o kim kalmış okur , onları yorumlamak için bu bayt.
chepner

Nitpick: printf(bu aynı zamanda tek başına çalıştırılabilir olarak var olmasına rağmen), yorumlar Dahili komut bir yumruk olan \riki bayt (bir sekans 0x5cve 0x72ve satır başı (tek bir bayt üretir: 0x0d.) Daha sonra, evet terminali byte, yorumlanması 0x0dözel bir şekilde, ancak orijinal dize yorumlayamaz \r.
Suzanne Dupéron

6

Unix dünyasında, bir satırbaşı (genellikle \rprogramlama dillerinde olduğu gibi kodlanır ) dikkat çekici bir kontrol karakteridir. Satır sonunu işaretleyen satır besleme ( satırsonu olarak da adlandırılır ) dışındaki herhangi bir karakter gibi, bir metin satırının içinde satır başlarına sahip olabilirsiniz.

Özellikle, bir bash komut dosyasında, satır başı, harfler ve rakamlar gibi sıradan bir sözcük oluşturucu karakterdir. Taşıyıcı dönüşünün herhangi bir özel etkisi, kabuktan değil terminalden gelir.

Satır başı bir kontrol karakteridir . Bir terminale yazdırdığınızda, bir glif görüntülemek yerine , terminal bazı özel efektler gerçekleştirir. Bir satır başı için, özel efekt imleci geçerli satırın başına götürmektir. Bu nedenle, ortasında bir satır başı içeren bir satır yazdırırsanız, sonuç, ikinci yarının ilk yarının üzerine yazılmasıdır.

Diğer bazı kontrol karakterlerinin özel efektleri vardır: geri silme karakteri imleci bir konum sola taşır. Zil karakteri terminalin ses çıkarmasına veya kullanıcının dikkatini çekmesine neden olur. Kaçış karakteri , her türlü özel etkiye sahip olabilen bir kaçış dizisi başlatır .

Güvenilmeyen çıktı görüntülerseniz denetim karakterlerini fırçalamanız veya bu karakterlerden kaçmanız gerekir. Sadece taşıma değil, diğerleri de, özellikle de her türlü kötü etkiye neden olabilecek kaçış karakteri. Bkz. Bir dosyayı “katlamak” potansiyel bir güvenlik riski olabilir mi? ve Terminallerde kaçış sırası saldırılarını nasıl önleyebilirim? konuyla ilgili daha fazla bilgi için.


0

Biçim printfişlevini kullanarak, satır başlarını bir bash değişkeninde görüntüleyebilirsiniz %q.

$ TESTVAR="$(printf ' Version: 1 \r Build: 20180712 \r Test: 1324')"

$ printf %q $TESTVAR
Version:1$'\r'Build:20180712$'\r'Test:1324

Kaynaklar ve ek okuma:

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.