Jak używać znaku specjalnego jako normalnego?


13

Wiele pytań, takich jak „Jak wpisać znak podwójnego cudzysłowu („)? ” są zadawane, a my nie chcemy zaśmiecać naszej społeczności tą samą odpowiedzią (wpisz ją tak, \"jakby nie była ujęta w 's, "jeśli ujęta w 's.) Więc pytanie jest tutaj.

Nie możesz wpisywać specjalnych znaków w terminalu jak normalne, np. To polecenie się nie powiedzie:

echo Updates (11)

Jak więc wpisać te znaki w terminalu, jakby były normalne?

!#$^&*?[](){}<>~;'"\|<space><tab><newline>

Nie znam powłoki uniksowej, w której powrót karetki jest wyjątkowy. =, @I %są wyjątkowe w niektórych muszli w niektórych kontekstach.
Stéphane Chazelas,

@ StéphaneChazelas Umm ... powrót karetki ( ^M) działa jak ^Jdla mnie line feed ( ) (Ubuntu 14.04, sh).
EKons,

Nie, sterownik terminala przekształca ^Msię ^Jna wejście, ale ^Mnie jest specjalny dla powłoki i nie wymaga cytowania. Wpisz, echo ^V^M | hda zobaczysz znak 0d (i 0a dołączone przez echo).
Stéphane Chazelas

@ StéphaneChazelas Umm ... Nie wiem co hd, być może xxdjest lepszy jako przeglądarka heksadecymalna.
EKons,

Którykolwiek. Użyj POSIX od -tx1lub sed -n lvim's xxd, jeśli nie masz hd. Niektóre systemy mają cat -vtelubcat -A
Stéphane Chazelas

Odpowiedzi:


27

To bardzo zależy od powłoki. Sprawdź szczegóły w instrukcji obsługi powłoki.

Pamiętaj też, że niektóre postacie są wyjątkowe tylko w niektórych kontekstach. Na przykład w większości powłok *i ?są one wyjątkowe tylko w kontekście list, w powłokach POSIX lub podobnych do csh, ~są wyjątkowe tylko na początku słowa lub po niektórych znakach, takich jak :. To samo dotyczy =w zsh. W niektórych powłokach [jest wyjątkowy tylko wtedy, gdy jest dopasowany (z pewnymi ograniczeniami) przez ].

W niektórych powłokach, takich jak bashlub yash, znaki specjalne, takie jak puste ograniczniki tokenów, również różnią się w zależności od regionu.

Operatory cytowania (w celu usunięcia specjalnego znaczenia tych znaków) również różnią się znacznie między powłokami.

Muszle Bourne'a

Podsumowanie dla powłok podobnych do Bourne'a (tj. Powłok, o których wiadomo, że są wywoływane shw tym lub innym systemie od lat 80.):

Skorupa Bourne'a

Znaki specjalne:

  • "\'&|;()^`<>$, spacja, nowa linia i tabulator są wyjątkowe w prostych wierszach poleceń, gdy nie są cytowane.
  • #(z wyjątkiem wczesnej wersji) jest wyjątkowy na początku wiersza lub po cudzysłowie, tabulacji lub &|()^<>;`.
  • {i }są wyjątkowe tylko dlatego, że są słowami kluczowymi powłoki (więc tylko słowa w pozycji poleceń).
  • *?[są wyjątkowe jako operatory globowania, więc tylko w kontekście listowym. W przypadku [, [...]jest to operator globowania, albo należy [albo ]cytować, aby usunąć specjalne znaczenie.
  • =jest wyjątkowy, gdy jest traktowany jako operator przypisania. To jest, w prostym poleceniu, dla wszystkich słów, które nie następują po argumencie (oprócz po set -k).

Cytowanie operatorów

  • \cytuje wszystkie znaki specjalne oprócz nowej linii ( \<newline>jest to sposób na kontynuację długiej linii logicznej do następnej linii fizycznej , dzięki czemu sekwencja jest usuwana). Zauważ, że backticks dodają dodatkowej złożoności, ponieważ w nich \są używane, aby uciec przed zamykającym backtick i pomóc parserowi. Wewnątrz cudzysłowach, \mogą być stosowane tylko uciec się, ", $oraz `( \<newline>wciąż line-kontynuacja). Wewnątrz dokumentu tutaj, to samo z wyjątkiem ". \to jedyny sposób na ucieczkę znaków w dokumentach tutaj.
  • "..."podwójne cudzysłowy unikają wszystkich znaków oprócz siebie \, $oraz `.
  • '...' pojedyncze cudzysłowy unikają wszystkich znaków oprócz siebie.

Pociski POSIX

Pociski POSIX zachowują się głównie jak powłoka Bourne'a, z tym wyjątkiem, że:

ksh

jak POSIX poza tym, że:

  • {string}jest wyjątkowy, jeśli ciąg znaków zawiera cudzysłowy ,(lub ..w niektórych przypadkach i przy niektórych wersjach).
  • ksh93 ma dodatkowy specjalny operator cytowania: $'...'ze złożonymi regułami. Operator, który znajduje się również (z), w pewnych odmianach bash, zsh, mkshi FreeBSD Busybox sh.
  • ksh93ma również $"..."operator cytowania, który działa podobnie, "..."z tym że łańcuch podlega lokalizacji (można go skonfigurować tak, aby tłumaczył na język użytkownika). mkshignoruje $w $"...".

bash

jak ksh93ale:

  • w ustawieniach jednobajtowych znaków wszystkie puste (zgodnie z ustawieniami narodowymi) znaki są traktowane jako ograniczniki (takie jak spacja lub tabulator). W efekcie oznacza to, że powinieneś zacytować wszystkie bajty z ustawionym 8-tym bitem, na wypadek, gdyby w niektórych lokalizacjach mogły być one pustymi znakami.
  • Gdy rozszerzenie historii csh jest włączone, jak w instancjach interaktywnych, !jest wyjątkowe w niektórych kontekstach i podwójne cudzysłowy nie zawsze przed nim uciekają. I ^jest wyjątkowy na początku polecenia.

zsh

jak ksh93ale:

  • ta sama uwaga, jak w bashprzypadku rozszerzania historii csh
  • =jest wyjątkowy jako pierwszy znak słowa ( =lsrozwija się do /bin/ls).
  • {i }może również otwierać i zamykać grupy poleceń, gdy nie są rozdzielane (jak w {echo text}pracach takich jak Bourne'a { echo text;}).
  • z wyjątkiem [samego, [potrzeby cytowane, nawet jeśli nie są zamknięte za pomocą ].
  • Po włączeniu extendedglobopcji #, ^i ~są operatory globowania.
  • Dzięki tej bracecclopcji {non-empty-string}jest wyjątkowy.
  • $"..." nie jest wspierany.
  • jako specjalne dziwactwo, ?nie jest wyjątkowe, gdy podąża za %(nawet cytowanym lub rozwiniętym) na początku słowa (aby umożliwić %?namespecyfikację zadania)
  • rcquotesopcja (nie domyślnie włączona) pozwala na wpisanie apostrofów jak ''wewnątrz apostrofów à la rc(patrz niżej).

yash

jak POSIXtą różnicą, że.

  • wszystkie puste znaki są traktowane jako ograniczniki.
  • Dzięki tej brace-expandopcji implementuje rozszerzenie nawiasów w stylu zsh.

Dla wszystkich powłok istnieją specjalne konteksty, w których cytowanie działa inaczej. Wspominaliśmy już o dokumentach i backtickach, ale jest też [[...]]w ksh i kilku innych powłokach, POSIX $((...)), casekonstrukcjach ...

Należy również pamiętać, że cytowanie może mieć inne skutki uboczne, jeśli chodzi o rozwinięcia (z podwójnymi cudzysłowami) lub w przypadku zastosowania tutaj ograniczników dokumentów. Wyłącza także słowa zastrzeżone i wpływa na rozszerzenie aliasu.

streszczenie

W powłokach podobnych do Bourne'a !#$^&*?[(){}<>~;'"`\|=SPC, TAB, NEWLINE i niektóre bajty z 8-bitowym zestawem są lub mogą być specjalne (przynajmniej w niektórych kontekstach).

Aby usunąć specjalne znaczenie, aby traktować je dosłownie, użyj cytowania.

Posługiwać się:

  • '...' aby usunąć specjalne znaczenie każdej postaci:

    printf '%s\n' '\/\/ Those $quoted$ strings are passed literally as
    single arguments (without the enclosing quotes) to `printf`'
    
  • \ aby usunąć specjalne znaczenie tylko jednego znaku:

    printf '<%s>\n' foo bar\ baz #comment

    Powyżej tylko znak spacji poprzedzony a \jest dosłownie przekazywany do printf. Pozostałe są traktowane przez powłokę jako ograniczniki tokenów.

  • używać "..."zacytować znaki jednocześnie umożliwiając rozszerzenie parametr ( $var, $#, ${foo#bar}...), wyrażeń arytmetycznych ( $((1+1))także $[1+1]w niektórych muszli) i podstawiania poleceń ( $(...)lub starej formy `...`. Faktycznie, większość czasu, ty chcesz umieścić te rozszerzenia wewnątrz podwójne cudzysłowy w każdym przypadku . Możesz użyć \wewnątrz, "..."aby usunąć specjalne znaczenie znaków, które są nadal wyjątkowe (ale tylko je).
  • jeśli ciąg zawiera 'znak, nadal możesz użyć '...'do reszty i użyć innych mechanizmów cytowania, które mogą cytować 'jak "'"lub \'lub (jeśli są dostępne) $'\'':

    echo 'This is "tricky", isn'\''t it?'
  • Użyj nowoczesnej $(...)formy zastępowania poleceń. Używaj starego tylko `...`do kompatybilności z powłoką Bourne'a, to jest do bardzo starego systemu i tylko w przypisaniach zmiennych, ponieważ nie używaj:

    echo "`echo "foo bar"`"

    Co nie będzie działać z wersją powłoki ksh Bourne'a lub AT&T. Lub:

    echo "`echo \"foo bar\"`"

    Które będą działać z Bourne i AT&T ksh, ale nie z yash, ale użyj:

    var=`echo "foo bar"`; echo "$var"

    które będą działać ze wszystkimi.

    Niemożliwe jest również zagnieżdżanie ich z użyciem podwójnych cudzysłowów, więc ponownie użyj zmiennych. Uważaj również na specjalne przetwarzanie odwrotnego ukośnika:

    var=`printf '%s\n' '\\'`

    Będzie przechowywać w środku tylko jeden ukośnik odwrotny $var, ponieważ istnieje dodatkowy poziom przetwarzania ukośnika odwrotnego (dla \, `i $(a także "gdy jest cytowany, z wyjątkiem in yash)) w obrębie odwrotnych znaków, więc potrzebujesz albo

    var=`printf '%s\n' '\\\\'`

    lub

    var=`printf '%s\n' '\\\'

    zamiast.

Rodzina Csh

csh i tcsh mają znacząco różną składnię, choć nadal ma wiele wspólnego z powłoką Bourne'a, ponieważ mają one wspólne dziedzictwo.

Znaki specjalne:

  • "\'&|;()^`<>$, spacje, znaki nowej linii i tabulatory są wyjątkowe wszędzie, gdy nie są cytowane.
  • #(csh to powłoka wprowadzona #jako lider komentarza) jest wyjątkowa na początku skryptu lub po cytowanym spacji, tabulacji lub nowym wierszu.
  • *?[ są wyjątkowe jako operatory globowania, więc w kontekście list
  • {non-empty-string} jest wyjątkowy (csh jest powłoką, która wprowadziła rozszerzenie nawiasu klamrowego).
  • !i ^są wyjątkowe w ramach ekspansji historii (znowu wynalazek csh), a reguły cytowania są wyjątkowe.
  • ~ (rozszerzenie tyldy również wynalazek csh) jest wyjątkowe w niektórych kontekstach.

Cytowanie operatorów

Są takie same jak w przypadku powłoki Bourne'a, ale ich zachowanie jest inne. tcsh zachowuje się jak csh z punktu widzenia składni, przekonasz się, że wiele wersji csh ma paskudne błędy. Pobierz najnowszą wersję tcsh, aby uzyskać z grubsza działającą wersję csh.

  • \ucieka przed pojedynczym znakiem z wyjątkiem znaku nowej linii (taki sam jak w przypadku powłoki Bourne'a). Jest to jedyny operator cytowania, który może uciec !. \<newline>nie ucieka, ale przekształca go z separatora poleceń w separator tokenów (jak spacja)
  • "..."ucieka wszystkie znaki oprócz samego, $, `, nowej linii i !. W przeciwieństwie do powłoki Bourne'a, nie możesz użyć \do ucieczki $i `wewnątrz "...", ale możesz użyć \do ucieczki !lub nowej linii (ale nie samo, z wyjątkiem sytuacji, gdy znajdował się przed nową !lub nową linią). Dosłowność !jest "\!"i dosłowność \!jest "\\!".
  • '...' unika wszystkich znaków oprócz siebie !i nowej linii. Podobnie jak w przypadku podwójnych cudzysłowów, !znak nowej linii można usunąć za pomocą odwrotnego ukośnika.
  • podstawianie komend odbywa się tylko za pomocą `...`składni i nie może być używane niezawodnie.
  • podstawianie zmiennych jest również dość źle zaprojektowane i podatne na błędy. $var:qOperator pomaga pisać kod udziałem bardziej wiarygodne zmienne.

streszczenie

Trzymaj się z dala od csh, jeśli możesz. Jeśli nie możesz użyć:

  • pojedyncze cudzysłowy, aby zacytować większość znaków. !i nowa linia nadal potrzebuje \.
  • \ może uciec większości postaci
  • "..."może zezwalać na niektóre rozszerzenia w nim zawarte, ale jest to dość mylące, jeśli osadzają znaki nowej linii i / lub odwrotny ukośnik, najlepiej używać tylko pojedynczych cudzysłowów i $var:qdo rozszerzania zmiennych. Musisz użyć pętli, jeśli chcesz niezawodnie łączyć elementy tablicy.

rc rodzina

rcjest plan9powłoką i podobnie jak jej potomkowie esi akangazostał przeniesiony do Uniksa i uniks-like. Jest to powłoka o znacznie bardziej przejrzystej i lepszej składni i ta, której wszyscy używaliby, gdybyśmy nie utknęli z powłokami podobnymi do Bourne'a w celu zapewnienia kompatybilności wstecznej.

rc/akanga

Znaki specjalne

  • #;&|^$=`'{}()<>, SPC, TAB i NEWLINE są zawsze wyjątkowe, gdy nie są cytowane.
  • *?[ to operatorzy globujący.

Operator cytowania

'...'jest jedynym operatorem kwotowania. Literatura 'jest zapisywana ''w pojedynczych cudzysłowach, jak w:

 echo 'it''s so simple isn''t it?'

es

esmoże być postrzegany jako eksperymentalna powłoka oparta na rc.

Ma jednak kilka różnic. Interesujące dla tego Q / A jest to, że \jest także operatorem cytowania (który cytuje wszystkie znaki specjalne oprócz nowej linii) i może być również używany do wprowadzania sekwencji specjalnych, takich jak \ndla nowej linii, \bdla odwrotnego ukośnika ...

ryba

fish jest względnym nowicjuszem (około 2005 r.), jest przeznaczony głównie do użytku interaktywnego, a także ma znacznie inną składnię niż inne muszle.

znaki specjalne

  • "'\()$%{}^<>;&|zawsze wyjątkowy, gdy nie jest cytowany (zauważ %(dla rozszerzenia pid) jako istotną różnicę w stosunku do innych powłok i `nie jest on specjalny)
  • # (komentarz) specjalne, gdy podąża za cudzysłowem, tabulatorem, znakiem nowej linii lub ;&|^<>
  • *?(ale nie [...]) operatory globowania

Cytowanie operatorów

  • \cytuje pojedynczy znak specjalny oprócz znaku nowej linii, ale uwaga: podwaja się również jako wprowadzający sekwencję zmiany znaczenia C ( \n, \b...). IOW, \nto nie cytowany, nale nowy wiersz.
  • "..."cytuje wszystko oprócz siebie, $a odwrotnego ukośnika i odwrotnego ukośnika można użyć do ich ucieczki. \<newline>jest kontynuacją linii (usuniętą) wewnątrz "...".
  • '...'cytuje wszystko oprócz siebie \, i możesz użyć ukośnika odwrotnego, aby uciec przed nimi.

Dołączyłem tylko te specjalne we wszystkich kontekstach (tak, że cdziała tak samo \c, cjak nie wyświetla c: command not foundna STDERR itp.) I mówię shtutaj. Pamiętaj też, że jest to pytanie „oczyszczające”, tzn. Ma ono obejmować wszystkie takie postacie, więc nie trzeba będzie zadawać ponad 19 pytań. Pytanie zostało opublikowane dzięki incydentowi, w którym różne pytania są zadawane dla różnych takich postaci, z pewnością chcemy tutaj wyczyścić!
EKons,

Cóż, ?[są operatorami globowania, ale nie są wyjątkowe we wszystkich kontekstach, ale *wydaje się, że tak, ponieważ echo *źle echooceniają zawartość bieżącego katalogu (niczego nie uciekając). echo ?echo literału ?i echo [echo literału [. Ponadto, ]jest globbing oberator też.
EKons,

1
@ ΈρικΚωνσταντόπουλος, *ponieważ glob rozszerza się na wszystkie nie ukryte pliki, ?na nie ukryte pliki jednoznakowe, na pliki, [a-z]których nazwa jest pojedynczym znakiem od a do z i tak dalej. Kiedy nie pasują do żadnego pliku (jak w twoim przypadku ?), w zależności od powłoki, pojawia się błąd braku dopasowania lub wzorzec rozwija się do siebie. W każdym razie, nawet w skorupach, gdzie rozszerzyć do siebie, muszą cytowany w przypadku gdy może dopasować plik.
Stéphane Chazelas,

Ale nie jako glob, *wciąż się rozwija.
EKons,

@ ΈρικΚωνσταντόπουλος, *jest jak ?, jeśli się nie zgadza (w przypadku *samego, to wtedy, gdy w bieżącym katalogu są tylko ukryte pliki, a*ponieważ tam nie ma pliku, którego nazwa zaczyna się od a...), albo rozwija się do sam (najbardziej Bourne-jak muszli), lub zgłasza błąd no-match ( csh, tcsh, fish(ostrzeżenie), zsh, bash -O failglob, wczesne muszle Unix), (lub rozszerza się nic z opcją nullglob niektórych muszli lub jeśli jest inny wzór, który rozszerza się do coś w csh, tcsh, zsh -o cshnullglob, wczesne powłoki unixowe).
Stéphane Chazelas

4

1. Escape

Usuń wszystkie te znaki za pomocą znaku \, takiego jak ten (nie działa na znakach nowej linii / znakach karetki):

$ echo Use a \"\\\" symbol to escape characters.
Use a "\" symbol to escape characters.

2. Podwójny cytat

Umieść cały tekst w "s, w ten sposób:

$ var=variables;echo "Enclose text in \"s. You can also use $var in them. `echo Surprise!!!`"
Enclose text in "s. You can also use variables in them. Surprise!!!

3. Pojedynczy cytat

To samo co podwójny cudzysłów, ale nie ma specjalnego tokena.

$ proof=proveit;echo 'This should not read "proveit": $proof'
This should not read "proveit": $proof

1
Opisujesz zachowanie fishpowłoki, a nie powłoki podobne do Bourne'a, w których pojedynczy cudzysłów cytuje każdą postać (odwrotny ukośnik nie jest wyjątkowy w środku '...'). Zauważ, że w fish, %jest również znakiem specjalnym.
Stéphane Chazelas,

@ StéphaneChazelas nie wiem jak fishdziała, ale moje doświadczenie jest to, że sh, echo '\\'ech \ i echo '\''echa '.
EKons,

1
echo '\\'wyjścia \, ponieważ echorozwija sekwencje specjalne ANSI C (niektóre echoimplementacje tego wymagają echo -e '\\'). printf '%s\n' '\\'wyjścia \\.
Stéphane Chazelas

Zauważ, że shnie identyfikuje konkretnej powłoki, istnieje i istniało wiele różnych i często niekompatybilnych powłok sh.
Stéphane Chazelas

@ StéphaneChazelas No dobra, teraz to zmienię. Nawiasem mówiąc, czy \'specjalny żeton znajduje się w sekwencji pojedynczego cudzysłowu?
EKons,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.