2016-11-13 11 views
7

Chciałbym wydrukować rozszerzenia funkcji do pliku. powiedziano mi polecenia printf „% q”, którego nauczanie jest następujący,Jak korzystać z printf "% q" w bash?

# man printf 
%q  ARGUMENT is printed in a format that can be reused as shell input, escaping non-print‐ 
      able characters with the proposed POSIX $'' syntax. 

Na podstawie instrukcji powyżej, próbowałem następujący kod.

#!/bin/bash 
# file name : print_out_function_augs.sh 

output_file='output.txt' 

function print_augs() { 
    printf "%q " "[email protected]" >> "${output_file}" 
    echo >> "${output_file}" 
} 

print_augs a 'b c' 

cat "${output_file}" 
rm "${output_file}" 

i uruchomić

bash print_out_function_augs.sh 

Wyniki są następujące,

a b\ c 

że spodziewane wyniki jak

a 'b c' 

co zwiększa do oryginalnych funkcji print_augs.

Dlaczego dane wyjściowe i oryginalne rozszerzenia są różne? Czy mogę wydrukować oryginalne rozszerzenia tak jak są?

Dziękuję bardzo.

Odpowiedz

6

tym pamiętać podczas korzystania %q:

argument jest drukowany w formacie, który może być ponownie wykorzystany jako wejście powłoki, uciekając niedrukowalne znaki z proponowanym POSIX $ „” składni.

Podkreślam moją. printf może dowolnie formatować argumenty tak, jak lubi , o ile dane wejściowe mogą być ponownie użyte w powłoce. Jednak nie jest to powód, dla którego twoje wejście wygląda tak, jak to robi.

W Bashu znak ' jest ogranicznikiem łańcucha znaków, tak jak mówisz bash "poniższy ciąg zawiera znaki specjalne, takie jak spacje, a te znaki specjalne nie powinny być analizowane przez Bash". Cytaty nie są przekazywane do wywoływanych komend. Jakie polecenie widzi coś takiego:

Command: 
    printf "%q" a 'b c' 

Received args: 
    printf::arg0: printf 
    printf::arg1: %q 
    printf::arg2: a 
    printf::arg3: b c 

Zauważ, że arg3 nie ma ofert otaczających go. Bash nie przekazuje ich dalej.

Kiedy printf drukuje args pomieszczenia ona nie wie, że tam były cytaty wokółb c, więc ich nie drukować. Ale wiadomo, że przestrzeń między literami "b" i "c" jest specjalną postacią powłoki i umieszcza ją na pierwszym planie, aby uciec przed nią.

Dotyczy to wszystkich funkcji/poleceń basha, więc należy pamiętać, że dzieje się tak samo, gdy zadzwonisz pod numer print_augs.

Jeśli chcesz zachować cytaty wokół strun, trzeba podwoić zacytować je tak, atakujących ich nie analizować:

function print_augs2() { 
    echo "[email protected]" >> "${output_file}" 
} 

print_augs2 a "'b c'" 

# Output: a 'b c' 
+0

dziękuję za szczegółowe wyjaśnienie i rozwiązań. Nie mogłem sobie wyobrazić "\" w "b \ c". jest postacią ucieczki. – mora

Powiązane problemy