Jak uciec apostrofowi w pojedynczym cudzysłowie w bash?

16

Nie rozumiem, jak bash ocenia ucieczkę znaków apostrofu w ciągach pojedynczych cudzysłowów.

Oto przykład:

$ echo ''\''Hello World'\'''
'Hello World' # works

$ echo '\'Hello World\''
 > # expects you to continue input

Próbowałem szukać wyjaśnień na ten temat, ale nic nie mogłem uzyskać. Co tu robi bash?

Kibet
źródło
echo \''Hello World'\'
matematyka

Odpowiedzi:

17

W pojedynczych cudzysłowach nie ma możliwości ucieczki. Nie ma sposobu, aby dołączyć pojedynczy cytat do pojedynczych cytatów. Zobacz Cytowanie w bashu .

choroba
źródło
1
Masz rację. Sztuczka polega na tym, że „pojedynczy cytat może nie wystąpić między pojedynczymi cudzysłowami, nawet jeśli poprzedzony jest odwrotnym ukośnikiem”, więc prawdopodobnie podzieli go na różne części.
Kibet
@ Colin Gdy tylko jeden cytat znajdzie się w dwóch innych pojedynczych cytatach (ale z odwróconym ukośnikiem), cytowany cytat nie jest już prawdziwym cytatem. Jest to po prostu char bez specjalnych cech parowania.
zero2cx
1
@ zero2cx: Nieprawda:echo '\''
choroba
@ zero2cx: Powiedziałbym „na zewnątrz” zamiast „wewnątrz”.
choroba
3
@choroba nie „całkowicie” prawda, w bash można zrobićecho $'\'hello world\''
bufh
8

Oprócz obsługiwanego przez POSIX jedno- i podwójnego cudzysłowu, bashzapewnia dodatkowy typ cytowania, aby umożliwić małej klasie znaków zmiany znaczenia (w tym pojedynczego cudzysłowu) w ciągu cytowanego:

$ echo $'\'Hello World\''
'Hello World'

Zobacz sekcję CYTOWANIE na bashstronie podręcznika, pod koniec sekcji. (Wyszukaj „ANSI C”.)

chepner
źródło
3

Aby wyjaśnić, co się dzieje z twoimi apostrofami, które przeanalizowaliśmy, przeanalizujemy Twój drugi przykład (zobacz także pojedyncze cytaty lub mocne cytaty ):

$ echo '\'Hello World\''
>     # expects you to continue input

Tutaj pozostawiłeś cytat wiszący, jak już powiedziałeś. Teraz przytnij koniec i zmień go na:

                     v                                v           v
$ echo '\'Hello World     # Echo two strings: '\' and 'Hello World'.
\Hello World         ^

Podciąg „Hello World” nie był tutaj cytowany, ale zachowywał się tak, jakby był mocno cytowany. Korzystając z twojego przykładu, przyciąć koniec inaczej inaczej:

                     vv                                    v (plain apostrophe)
$ echo '\'Hello World\'   # Will echo: '\' and 'Hello World''
\Hello World'        ^^   # Note that the trailing ' char is backslash escaped. 

Podciąg „Hello World” znów zachowuje się tak, jakby był mocnym cytatem, z tylko dodanym apostrofem (uciekł, więc nie jest już pojedynczym cytatem) na końcu.

Kiedy na końcu dodawany jest kolejny pojedynczy cytat (twój oryginalny przykład), łańcuch pozostaje zawieszony i czeka na dokładny cytat.

zero2cx
źródło
3

Prosty przykład ucieczki cytatów w powłoce:

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

Odbywa się to poprzez zamknięcie już otwartego ( '), umieszczenie klawisza Esc ( \') w celu wydrukowania, a następnie otwarcie kolejnego ( ').

Alternatywnie:

$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc

Odbywa się to poprzez ukończenie już otwartego jednego ( '), umieszczenie cytatu w innym cytacie ( "'"), a następnie otwarcie kolejnego ( ').

To, co zrobiłeś ( '\'Hello World\''), to:

  1. Otwarty 1st apostrofu: '.
  2. Zamknięte zaraz po nim \', więc ciąg ma postać: '\'.
  3. Hello World to nie cytaty.
  4. Umieszczono autonomiczny apostrof ( \') bez otwierania go.
  5. Ostatni apostrof ( ') jest łańcuchem otwierającym, ale nie ma oczekiwanego zamknięcia.

Prawidłowy przykład to:

$ echo \'Hello World\'
'Hello World'

Powiązane: Jak uniknąć pojedynczych cudzysłowów w ciągach pojedynczych?

kenorb
źródło