2015-07-04 10 views
7

Poniższy skrypt przyniosły nieoczekiwany wynik:Jak uniknąć serii odwróconych ukośników w bash printf?

printf "escaped slash: \\ \n" 
printf "2 escaped slashes: \\\\ \n" 
printf "3 escaped slashes: \\\\\\ \n" 
printf "4 escaped slashes: \\\\\\\\ \n" 

Uruchom jako skryptu bash pod Ubuntu 14, widzę:

escaped slash: \ 
2 escaped slashes: \ 
3 escaped slashes: \\ 
4 escaped slashes: \\ 

Err .. co?

Odpowiedz

4

Zakładając, że printfFORMAT ciąg jest otoczony przez cudzysłów, printf trwa jeden dodatkowy poziom ekspansji, w porównaniu do np echo (oba polecenia wbudowane w powłokę).

Co można oczekiwać od printf w rzeczywistości może być osiągnięty za pomocą apostrofów:

printf '1 escaped slash: \\ \n' 
printf '2 escaped slashes: \\\\ \n' 
printf '3 escaped slashes: \\\\\\ \n' 
printf '4 escaped slashes: \\\\\\\\ \n' 

wyjścia:

1 escaped slash: \ 
2 escaped slashes: \\ 
3 escaped slashes: \\\ 
4 escaped slashes: \\\\ 
+0

Pamiętaj, że działa to, ponieważ zapobiegasz, aby 'bash' usuwał jakiekolwiek ukośniki, zanim' printf' zobaczy argument. – chepner

+0

@chepner: Zgadzam się. Wydaje się, że kolejność oceny jest następująca: 1) 'bash' rozwija ciąg' FORMAT' * (tylko jeśli jest otoczony podwójnymi cudzysłowami!) *. 2) 'printf' łączy" ARGUMENTS "i" FORMAT "w jeden ciąg znaków. 3) Ostatni łańcuch jest ponownie rozwijany (tzn. \\ staje się \). 4) Wynik zostaje ostatecznie wydrukowany. –

+0

Zamknij; 'printf' przetwarza tylko' FORMAT' przed wstawieniem argumentów; porównaj 'printf '\ n'' z' printf'% s '' \ n''. – chepner

3

printf to wbudowany bash. Spójrz na help printf:

 
printf [-v var] format [arguments] 
     Formats and prints ARGUMENTS under control of the FORMAT. 

Należy zdać format i argument. Więc dodać format "%s\n" przed argumentu:

printf "%s\n" "escaped slash: \\" 
printf "%s\n" "2 escaped slashes: \\\\" 
printf "%s\n" "3 escaped slashes: \\\\\\" 
printf "%s\n" "4 escaped slashes: \\\\\\\\" 

wyjściowa:

 
escaped slash: \ 
2 escaped slashes: \\ 
3 escaped slashes: \\\ 
4 escaped slashes: \\\\ 
+0

@Yuri G .: Dziękuję za dodatkowy opis. – Cyrus

+0

Pamiętaj, że działa to, ponieważ unikasz 'printf' stosując kolejną rundę interpretacji ukośników odwrotnych. – chepner