Mam jedno szybkie pytanie.
Czy to normalne, że bash (używam 4.4.11) nie wyświetla linii / tekstu oddzielonego / zakończonego zwykłym \r
?
Byłem trochę zaskoczony tym zachowaniem:
$ a=$(printf "hello\ragain\rgeorge\r\n")
$ echo "$a"
george
Ale tekst „witaj ponownie” wciąż tam jest, w jakiś sposób „ukryty”:
$ 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
A gdy tylko gramy w bash, wszystko jest w porządku .... Ale czy to potencjalne zagrożenie bezpieczeństwa? Co jeśli zawartość zmiennej „a” pochodzi ze świata zewnętrznego i zawiera „złe polecenia” zamiast po prostu cześć?
Kolejny test, tym razem trochę niepewny:
$ 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>
Wyobraź sobie ukryty rm
zamiast ukrytego ls
.
To samo zachowanie przy użyciu echa -e:
$ a=$(echo -e "ls;\rGeorge\r\n"); echo "$a"
George
Czy to ja robi coś złego ...?
źródło
bash
; od terminala zależy „wyświetlanie” znaku powrotu karetki lub wyświetlanie znaków zastąpionych. Na przykład idealnie byłoby, gdyby terminal wyświetlał się-\r|
jako coś przypominającego znak plus, a nie tylko potok.bash
po prostu zapisuje bajty do pliku; to kto czyta te bajty, je interpretuje.printf
który jest wbudowanym poleceniem bash (chociaż istnieje również jako samodzielny plik wykonywalny), interpretuje\r
(sekwencję dwóch bajtów:0x5c
i0x72
zwraca zwrot karetki (pojedynczy bajt:)0x0d
. Następnie tak, terminal interpretuje bajt0x0d
w szczególny sposób, ale to nie interpretuje oryginalny łańcuch\r
.W świecie uniksowym powrót karetki (powszechnie kodowany jak
\r
w językach programowania) jest niczym niezwykłym znakiem kontrolnym. Znaki powrotu karetki mogą znajdować się w wierszu tekstu, podobnie jak każdy inny znak oprócz przejścia do nowego wiersza (zwanego także nowym wierszem ), który oznacza koniec wiersza.W szczególności, w skrypcie bash, znak powrotu karetki jest zwykłym składnikiem słowa, takim jak litery i cyfry. Jakikolwiek efekt specjalny powrotu karetki pochodzi z terminala, a nie z powłoki.
Zwrot karetki jest znakiem kontrolnym . Gdy drukujesz go na terminalu, zamiast wyświetlać glif , terminal wykonuje jakiś efekt specjalny. W przypadku powrotu karetki efektem specjalnym jest przesunięcie kursora na początek bieżącej linii. Zatem jeśli wydrukujesz linię, która zawiera znak powrotu karetki na środku, efekt jest taki, że druga połowa zostanie zapisana na pierwszej połowie.
Kilka innych znaków kontrolnych ma efekty specjalne: znak cofania przesuwa kursor w lewo o jedną pozycję. Dzwonek powoduje, że terminal emituje dźwięk lub w inny sposób przyciąga uwagę użytkownika. Znak ucieczki rozpoczyna sekwencję ucieczki, która może mieć różnego rodzaju efekty specjalne.
Jeśli wyświetlasz niezaufane dane wyjściowe, musisz wyszorować lub usunąć znaki kontrolne. Powraca nie tylko karetka, ale także kilka innych, w szczególności postać ucieczki, która może powodować różnego rodzaju złe efekty. Zobacz Czy „przechwytywanie” pliku może stanowić potencjalne zagrożenie bezpieczeństwa? i Jak uniknąć ataków sekwencji ucieczki na terminalach? po więcej na ten temat.
źródło
Możesz wyświetlić powroty karetki w zmiennej bash, używając
printf
funkcji z%q
formatem.Źródła i dalsze czytanie:
źródło