GNU/Linux >> Znalost Linux >  >> Linux

Jak použít speciální znak jako normální v unixových shellech?

Mnoho otázek, jako je „Jak napsat znak dvojitých uvozovek (“)?‘, se ptáme, a my nechceme zahlcovat naši komunitu stejnou odpovědí (Zadejte to jako " pokud není uzavřeno v ' s, " pokud je uzavřen v ' s.) Takže otázka je zde.

Do terminálu nemůžete zadávat speciální znaky jako normální, např. tento příkaz selže:

echo Updates (11)

Jak tedy zadat tyto znaky do terminálu, jako by to byly normální?

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

Přijatá odpověď:

To hodně záleží na skořápce. Podrobnosti najdete v příručce k shellu.

Všimněte si také, že některé znaky jsou speciální pouze v některých kontextech. Například ve většině shellů * a ? jsou speciální pouze v kontextech seznamu,
v shellech POSIX nebo csh, ~ je speciální pouze na začátku slova nebo po některých znacích jako : . Totéž pro = v zsh . V některých prostředích [ je speciální pouze tehdy, když je (s určitými omezeními) shodný s ] .

V některých shellech, jako je bash nebo yash , speciální znaky, jako jsou prázdné oddělovače tokenů, se také liší podle národního prostředí.

Operátory uvozovek (k odstranění speciálního významu těchto znaků) se také mezi shelly velmi liší.

Skořápky podobné Bourne

Shrnutí pro shelly podobné Bourneovi (to jsou shelly, o kterých je známo, že se nazývají sh na nějakém systému nebo jiném od 80. let):

Bourne shell

Speciální znaky:

  • "'&|;()^`<>$ , mezera, nový řádek a tabulátor jsou speciální v jednoduchých příkazových řádcích, pokud nejsou v uvozovkách.
  • # (kromě dřívější verze) je speciální na začátku řádku nebo za mezerou bez uvozovek, tabulátorem nebo &|()^<>;` .
  • { a } jsou speciální pouze v tom, že se jedná o klíčová slova shellu (tedy pouze slova na pozici příkazu).
  • *?[ jsou speciální jako globbing operátory, takže pouze v kontextu seznamu. V případě [ , je to [...] to je globbing operátor, buď [ nebo ] stačí pouze citovat, aby se odstranil zvláštní význam.
  • = je speciální v kontextech, kde se s ním zachází jako s operátorem přiřazení. Tedy v jednoduchém příkazu pro všechna slova, která nenásledují argument (kromě po set -k ).

Citování operátorů

  • { uvozuje všechny speciální znaky kromě nového řádku (<newline> je způsob, jak pokračovat v dlouhém logickém řádek na další fyzický řádek, takže sekvence je odstraněna). Všimněte si, že backticks přidávají další složitost jako v nich, { se používá jako první k opuštění uzavíracího zpětného znaménka a pomáhá analyzátoru. Uvnitř dvojitých uvozovek { lze použít pouze k escapování samotného, ​​" , $ a ` (<newline> je stále pokračováním linky). Uvnitř dokumentu zde, stejné kromě " . { je jediný způsob, jak uniknout znakům v těchto dokumentech.
  • "..." dvojité uvozovky uvozují všechny znaky kromě samotného { , $ a ` .
  • '...' jednoduché uvozovky unikají všem znakům kromě něj samotného.

Skořápky POSIX

Shelly POSIX se chovají většinou jako Bourne shell, kromě toho:

  • ^ již není speciální znak
  • ~ je v některých kontextech zvláštní
  • { je povoleno být speciální, takže by mělo být citováno.

ksh

jako POSIX kromě toho:

  • {string} je speciální, pokud řetězec obsahuje , bez uvozovek (nebo .. v některých případech au některých verzí).
  • ksh93 má další speciální operátor uvozovek:$'...' se složitými pravidly. Tento operátor se také nachází (s určitými obměnami) v bash , zsh , mksh a FreeBSD a busybox sh .
  • ksh93 má také $"..." operátor citací, který funguje jako "..." kromě toho, že řetězec podléhá lokalizaci (lze nakonfigurovat tak, aby se překládal do jazyka uživatele). mksh ignoruje $ v $"..." .
  • od ksh93r , ksh93 podporuje styl csh (ve výchozím nastavení není povoleno) s -H / -o histexpand v interaktivních shellech), což vytváří ^ na začátku příkazů a ! speciální. ! je pak v některých kontextech zvláštní (nikoli, když následuje mezera nebo TAB, ani v těchto dokumentech) a není uvozován dvojitými uvozovkami. Uniknou pouze zpětné lomítko (nikoli v uvozovkách) a jednoduché uvozovky.

bash

jako ksh93 ale:

  • v jednobajtových znakových národních prostředích, vše prázdné (podle národního prostředí) znaky jsou považovány za oddělovače (jako mezera nebo tabulátor). Ve skutečnosti to znamená, že byste měli citovat všechny bajty s nastaveným 8. bitem pro případ, že by v některém národním prostředí mohl být prázdný znak.
  • Rozšíření historie csh je v interaktivních instancích ve výchozím nastavení povoleno, se stejnými poznámkami jako u ksh93 výše kromě toho, že v novějších verzích bash , ! také někdy není zvláštní, když následuje " .

zsh

jako ksh93 ale:

  • stejná poznámka jako pro bash pro rozšíření historie csh
  • = je speciální jako první znak slova (=ls expanduje na /bin/ls ).
  • { a } může také otevírat a zavírat skupiny příkazů, pokud nejsou odděleny (jako v {echo text} funguje jako Bourneův { echo text;} ).
  • kromě [ sám, [ potřeby jsou uvedeny, i když nejsou uzavřeny ] .
  • S extendedglob možnost povolena, # , ^ a ~ jsou globální operátoři.
  • Pomocí braceccl možnost, {non-empty-string} je speciální.
  • $"..." není podporováno.
  • jako zvláštní vtip, ? není zvláštní při sledování % (i v uvozovkách nebo rozšířených) na začátku slova (aby byl povolen %?name specifikace práce)
  • a rcquotes možnost (ve výchozím nastavení není povolena) umožňuje zadat jednoduché uvozovky jako '' uvnitř jednoduchých uvozovek à la rc (viz níže).
Související:Má LVM vliv na výkon?

yash

jako POSIX kromě toho.

  • všechny prázdné znaky jsou považovány za oddělovače.
  • Pomocí brace-expand implementuje rozšíření složené závorky ve stylu zsh.

Pro všechny shelly existují některé speciální kontexty, kde citace fungují odlišně. Již jsme zde zmínili dokumenty a zpětná označení, ale je zde také [[...]] v ksh a několika dalších shellech, POSIX $((...)) , case konstrukce…

Všimněte si také, že citace mohou mít další vedlejší účinky, pokud jde o rozšíření (s dvojitými uvozovkami) nebo při použití zde oddělovačů dokumentu. Také zakáže vyhrazená slova a ovlivní rozšíření aliasů.

Shrnutí

Ve skořápkách podobných Bourneovi !#$^&*?[(){}<>~;'"`|= , SPC, TAB, NEWLINE a některé bajty s nastaveným 8. bitem jsou nebo mohou být speciální (alespoň v některých kontextech).

Chcete-li odstranit zvláštní význam, aby se s nimi zacházelo doslovně, použijte uvozovky.

Použijte:

  • '...' pro odstranění speciálního významu každého znaku:

    printf '%sn' '// Those $quoted$ strings are passed literally as
    single arguments (without the enclosing quotes) to `printf`'
    
  • { pro odstranění speciálního významu pouze jednoho znaku:

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

    Výše pouze znak mezery, kterému předchází { je předán doslova printf . S těmi ostatními zachází shell jako s oddělovači tokenů.

  • použijte "..." citovat znaky a přitom stále povolit rozšíření parametrů ($var , $# , ${foo#bar} …), aritmetické rozšíření ($((1+1)) , také $[1+1] v některých shellech) a záměna příkazů ($(...) nebo starý tvar `...` . Ve skutečnosti většinu času v každém případě chcete umístit tato rozšíření do dvojitých uvozovek. Můžete použít { v rámci "..." k odstranění speciálního významu znaků, které jsou stále speciální (ale pouze ony).

  • pokud řetězec obsahuje ' znak, stále můžete použít '...' pro zbytek a použijte jiné citační mechanismy, které umí citovat ' jako "'" nebo ' nebo (je-li k dispozici) $''' :

    echo 'This is "tricky", isn'''t it?'
    
  • Použijte moderní $(...) forma substituce příkazů. Používejte pouze staré `...` kvůli kompatibilitě s Bourne shellem, tedy velmi starým systémem, a pouze v přiřazení proměnných, jako v případě nepoužívejte:

    echo "`echo "foo bar"`"
    

    Což nebude fungovat s Bourne shell nebo AT&T verzemi ksh. Nebo:

    echo "`echo "foo bar"`"
    

    Což bude fungovat s Bourne a AT&T ksh, ale ne s yash (Úprava 2020: pouze ve verzi 2.41 a dřívějších, od té doby bylo změněno ve 2.42 / hlášení o chybě / odevzdání), ale použijte:

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

    který bude fungovat se všemi.

    Vnořit je přenosně s dvojitými uvozovkami je také nemožné, takže znovu použijte proměnné. Pozor také na speciální zpracování zpětného lomítka:

    var=`printf '%sn' '\'`
    

    Uloží pouze jedno zpětné lomítko do $var , protože existuje další úroveň zpracování zpětného lomítka (pro { , ` a $ (a také " v uvozovkách kromě yash )) v rámci backticks, takže potřebujete buď

    var=`printf '%sn' '\\'`
    

    nebo

    var=`printf '%sn' '\'
    

    místo toho.

Rodina Csh

csh a tcsh mají výrazně odlišnou syntaxi, i když s Bourne shellem mají stále mnoho společného, ​​protože sdílejí společné dědictví.

Speciální znaky:

  • "'&|;()^`<>$ , mezera, nový řádek a tabulátor jsou speciální všude, když nejsou v uvozovkách.
  • # (csh je shell, který zavedl # jako hlavní komentář) je zvláštní na začátku skriptu nebo po mezerě, tabulátoru nebo novém řádku bez uvozovek.
  • *?[ jsou speciální jako globbing operátory, takže v kontextu seznamu
  • {non-empty-string} je speciální (csh je shell, který zavedl expanzi rovnátka).
  • ! a ^ jsou speciální jako součást expanze historie (opět vynález csh) a pravidla pro citování jsou speciální.
  • ~ (expanze tildy také vynález csh) je v některých kontextech zvláštní.

Citování operátorů

Jsou stejné jako u Bourne shellu, ale chování se liší. tcsh se z hlediska syntaxe chová jako csh, zjistíte, že mnoho verzí csh má ošklivé chyby. Získejte nejnovější verzi tcsh a získejte zhruba funkční verzi csh.

  • { escapuje jeden znak kromě nového řádku (stejné jako u Bourne shellu). Je to jediný operátor uvozovek, který může uniknout ! . <newline> neunikne, ale převede jej z oddělovače příkazů na oddělovač tokenů (jako mezera)
  • "..." escapuje všechny znaky kromě sebe sama, $ , ` , nový řádek a ! . Na rozdíl od Bourne shellu nemůžete použít { pro únik $ a ` uvnitř "..." , ale můžete použít { uniknout ! nebo nový řádek (ale ne sám, kromě případů, kdy je před ! nebo nový řádek). Doslovné ! je "!" a doslovný ! je "\!" .
  • '...' escapuje všechny znaky kromě sebe sama, ! a nový řádek. Podobně jako u dvojitých uvozovek ! a nový řádek lze escapovat zpětným lomítkem.
  • Náhrada příkazu je pouze prostřednictvím `...` syntaxe a nelze je spolehlivě používat.
  • variabilní substituce je také dost špatně navržená a náchylná k chybám. A $var:q operátor pomáhá psát spolehlivější kód zahrnující proměnné.
Související:Kde jsou speciální operace vkládání Excelu v Tabulkách Google?

Shrnutí

Pokud můžete, držte se dál od csh. Pokud nemůžete použít:

  • jednoduché uvozovky pro citaci většiny znaků. ! a nový řádek stále potřebují { .
  • { může uniknout většině postav
  • "..." mohou v něm povolit některá rozšíření, ale to je docela bug, pokud vkládají znaky nového řádku a/nebo zpětného lomítka, nejlepší může být použít pouze jednoduché uvozovky a $var:q pro variabilní expanzi. Pokud chcete spolehlivě spojovat prvky pole, budete muset používat smyčky.

rc rodina

rc je plan9 shell a jako jeho potomci es a akanga byl portován na Unix a unixové systémy. To je shell s mnohem čistší a lepší syntaxí, který by každý používal, kdybychom nezůstali u Bourneových shellů kvůli zpětné kompatibilitě.

rc /akanga

Speciální znaky

  • #;&|^$=`'{}()<> , SPC, TAB a NEWLINE jsou vždy speciální, pokud nejsou uvedeny.
  • *?[ jsou globální operátoři.

Citující operátor

'...' je jediným citujícím operátorem. Doslovný ' se zapisuje pomocí '' v jednoduchých uvozovkách jako v:

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

es

es lze považovat za experimentální shell založený na rc .

Má to však několik rozdílů. Jedna zajímavá pro tuto Q/A je { je také operátor uvozovek (který uvádí všechny speciální znaky kromě nového řádku) a lze jej také použít k zavedení escape sekvencí jako n pro nový řádek b pro zpětné lomítko…

ryby

fish je relativní novinkou (kolem roku 2005), je primárně určena pro interaktivní použití a má také výrazně odlišnou syntaxi od ostatních skořápek.

zvláštní znaky

  • "'()$%{}^<>;&| vždy zvláštní, když není v uvozovkách (všimněte si % (pro expanzi pid) jako významný rozdíl od ostatních shellů a ` není zvláštní)
  • # (komentář) speciální, pokud následuje mezera bez uvozovek, tabulátor, nový řádek nebo ;&|^<>
  • *? (ale ne [...] ) globbing operátory

Citování operátorů

  • { uvozuje jeden speciální znak kromě nového řádku, ale dejte si pozor, funguje také jako sekvence C escape (n , b …) uvaděč. IOW, n není n v uvozovkách ale nový řádek.
  • "..." cituje vše kromě sebe, $ a zpětné lomítko a zpětné lomítko lze použít k tomu, aby jim uniklo. <newline> je pokračováním řádku (odstraněno) uvnitř "..." .
  • '...' cituje vše kromě sebe sama a { a můžete je použít zpětné lomítko.

Linux
  1. Jak používat Nginx k přesměrování

  2. Jak používat Su Command v Linuxu

  3. Jak používat příkaz Coproc v různých skořápkách?

  1. UNIX / Linux:Jak používat Sticky Bit na adresář a soubor

  2. jak používat pylint ve vim

  3. Jak používat dopředné vyhledávání k vyloučení speciálních znaků v regulárním výrazu

  1. Jak používat BusyBox na Linuxu

  2. Jak používám cron v Linuxu

  3. Co jsou speciální znaky a speciální soubory bloků v systému Unix?