Solo una nota in aggiunta alla bella risposta di @ Kusalananda .
echo run after_bundle
va bene perché nessuno dei caratteri in questi 3 argomenti¹ è passato a echocontenere caratteri speciali per la shell.
E (il punto in più che voglio sottolineare qui) non esiste alcuna locale di sistema in cui quei byte possano essere tradotti in caratteri speciali della shell.
Tutti quei personaggi sono in ciò che POSIX chiama il set di caratteri portatile . Questi caratteri dovrebbero essere presenti e codificati allo stesso modo in tutti i set di caratteri su un sistema POSIX².
In tal modo la riga di comando verrà interpretata allo stesso modo indipendentemente dalla locale.
Ora, se iniziamo a usare caratteri al di fuori di quel set di caratteri portatile, è una buona idea citarli anche se non sono speciali per la shell, perché in un'altra locale, i byte che li costituiscono possono essere interpretati come caratteri diversi che potrebbero diventare speciale per la shell. Nota che è se stai usando echoo qualsiasi altro comando, il problema non è con echoma con come la shell analizza il suo codice.
Ad esempio in un UTF-8:
echo voilà | iconv -f UTF-8 -t //TRANSLIT
Questo àè codificato come 0xc3 0xa0. Ora, se hai quella riga di codice in uno script di shell e lo script di shell viene invocato da un utente che utilizza una locale il cui set di caratteri non è UTF-8, quei due byte potrebbero creare caratteri molto diversi.
Ad esempio, in una fr_FR.ISO8859-15locale, una tipica locale francese che utilizza il set di caratteri a byte singolo standard che copre la lingua francese (la stessa utilizzata per la maggior parte delle lingue dell'Europa occidentale incluso l'inglese), che 0xc3 byte viene interpretato come Ãcarattere e 0xa0 come non- carattere spazio di rottura.
E su alcuni sistemi come NetBSD³, quello spazio non-break viene considerato come un carattere vuoto ( isblank()su esso ritorna vero, è abbinato da [[:blank:]]) e shell come bashquindi lo trattano come un delimitatore di token nella loro sintassi.
Ciò significa che invece di funzionare echocon $'voil\xc3\xa0'come argomento, lo eseguono $'voil\xc3'come argomento, il che significa che non verrà stampato voilàcorrettamente.
Si ottiene molto peggio con i set di caratteri cinesi come BIG5, BIG5-HKSCS, GB18030, GBK che hanno molti personaggi le cui codifica contiene la stessa codifica come |, `, \(per citare il peggiore) (anche che SJIS ridicola, aka Microsoft Kanji, ad eccezione che è ¥invece di \, ma è ancora trattato \dalla maggior parte degli strumenti in quanto è codificato come 0x5c lì).
Ad esempio, se in una lingua zh_CN.gb18030cinese, scrivi uno script come:
echo 詜 reboot
Lo script verrà generato 詜 rebootin una locale usando GB18030 o GBK, 唰 rebootin una locale usando BIG5 o BIG5-HKSCS, ma in una locale C usando ASCII o una locale usando ISO8859-15 o UTF-8, verrà rebooteseguito perché la codifica GB18030 di 詜è 0xd4 0x7c e 0x7c è la codifica di |in ASCII quindi finiamo per eseguire:
echo �| reboot
(che rappresenta comunque il byte 0xd4 è reso nella locale). Esempio usando il meno dannoso unameinvece di reboot:
$ echo $'echo \u8a5c uname' | iconv -t gb18030 > myscript
$ LC_ALL=zh_CN.gb18030 bash ./myscript | sed -n l
\324| uname$
$ LC_ALL=C bash ./myscript | sed -n l
Linux$
(è unamestato eseguito).
Quindi il mio consiglio sarebbe di citare tutte le stringhe che contengono caratteri al di fuori del set di caratteri portatile.
Tuttavia notare che, poiché la codifica dei \e `si trovano nella codifica di alcuni di questi personaggi, non è meglio usare \o "..."o $'...'(al cui interno `e / o \sono ancora speciale), ma il '...'posto per citare personaggi al di fuori del set di caratteri portatile.
Non sono a conoscenza di alcun sistema che abbia una localizzazione in cui il set di caratteri ha un carattere (diverso da 'se stesso ovviamente) la cui codifica contiene la codifica di ', quindi quelli '...'dovrebbero sicuramente essere i più sicuri.
Notare che diverse shell supportano anche una $'\uXXXX'notazione per esprimere caratteri basati sul loro punto di codice Unicode. In shell come zshe bash, il carattere viene inserito codificato nel set di caratteri della locale (anche se può causare comportamenti imprevisti se quel set di caratteri non ha quel carattere). Ciò consente di evitare di inserire caratteri non ASCII nel codice della shell.
Quindi sopra:
echo 'voilà' | iconv -f UTF-8 -t //TRANSLIT
echo '詜 reboot'
O:
echo $'voil\u00e0'
echo $'\u8a5c reboot'
(con l'avvertenza che potrebbe rompere la sceneggiatura quando eseguito in locali che non hanno quei caratteri).
O meglio, poiché \è anche speciale per echo(o almeno alcune echo implementazioni, almeno quelle conformi a Unix):
printf '%s\n' 'voilà' | iconv -f UTF-8 -t //TRANSLIT
printf '%s\n' '詜 reboot'
(nota che \è speciale anche nel primo argomento di printf, quindi è meglio evitare anche caratteri non ASCII nel caso in cui possano contenere la codifica di \).
Nota che potresti anche fare:
'echo' 'voilà' | 'iconv' '-f' 'UTF-8' '-t' '//TRANSLIT'
(sarebbe eccessivo ma potrebbe darti un po 'di tranquillità se non sei sicuro di quali personaggi siano nel set portatile)
Assicurati anche di non usare mai l'antica `...`forma di sostituzione dei comandi (che introduce un altro livello di elaborazione della barra rovesciata), ma usa $(...)invece.
¹ tecnicamente, echoviene anche passato come argomento echoall'utilità (per dirlo come è stato invocato), è il argv[0]e argcè 3, anche se nella maggior parte delle shell al giorno d'oggi echoè incorporato, quindi quello exec()di un /bin/echofile con un elenco di 3 argomenti è simulato dal conchiglia. È anche comune considerare l'elenco di argomenti come a partire dal secondo ( argv[1]a argv[argc - 1]) in quanto sono quelli sui quali agiscono principalmente i comandi.
² una notevole eccezione a quella che è la ridicola ja_JP.SJISlocalizzazione dei sistemi FreeBSD il cui set di caratteri non ha \né ~carattere!
³ nota che mentre molti sistemi (FreeBSD, Solaris, non quelli GNU) considerano U + 00A0 come [[:blank:]]in locali UTF-8, pochi lo fanno in altri locali come quelli che usano ISO8859-15, forse per evitare questo tipo di problema.