Quali personaggi devono essere salvati nei file senza virgolette?


12

Ho una shell / terminale basato su browser che esegue i comandi bash e sto sfuggendo agli spazi, ma risulta che anche la parentesi deve essere salvata. Quali altri caratteri devono essere salvati per i nomi di file che non sono tra virgolette?


Non è affatto chiaro cosa stai cercando di fare. E cosa ha a che fare il completamento automatico con qualcosa?
Michael Vehrs,

@MichaelVehrs Ho il comando mv filename filename-fooin bash, di quali personaggi ho bisogno per scappare, oltre agli spazi e alle parentesi?
jcubic,

@MichaelVehrs ha rimosso la menzione del completamento automatico.
jcubic,

Fondamentalmente, tutti i metacaratteri della shell, come spazi bianchi, globi di shell, eventi storici. Per questo motivo, è necessario citare l'intero nome del file, piuttosto che fuggire singoli caratteri: mv "$filename" "$newname".
Michael Vehrs,

@MichaelVehrs So che la citazione risolverà il problema con l'escaping ma devo usare il nome del file senza virgolette. Ho un emulatore di terminale e dovrebbe funzionare quando l'utente non usa le virgolette.
jcubic,

Risposte:


22

La soluzione semplice è inserire una virgoletta singola ( ') all'inizio e un'altra virgoletta alla fine e sostituire ogni 'carattere all'interno del nome del file con la sequenza di 4 caratteri '\''. Tutti i caratteri perdono il loro significato speciale all'interno di una stringa a virgoletta singola, tranne se 'stesso che segna la fine della stringa. La sequenza '\''termina il letterale a virgoletta singola, segue immediatamente una virgoletta singola quotata e apre un nuovo letterale a virgoletta singola. Da qui il nome del file

This file's name has some weird characters!
Will you manage to escape them?

può essere citato come segue:

somecommand 'This file'\''s name has some weird characters!
Will you manage to escape them?'

Le virgolette doppie hanno regole di escape più complesse e non ti consentono di includere un punto esclamativo !se la sostituzione della cronologia è attivata, quindi non le prenderò in considerazione ulteriormente.

Un approccio alternativo è quello di proteggere i personaggi con barre rovesciate. Funziona con tutti i personaggi tranne i newline; per una nuova riga, inserirla tra virgolette singole (o doppie virgolette) è l'unica soluzione. Se si desidera ridurre al minimo il numero di barre rovesciate per presentare all'utente il nome tra virgolette, è possibile limitarlo ai luoghi in cui è necessaria la barra rovesciata; tuttavia, più barre retroverse si omettono, più si rischia di dimenticare quella necessaria. Lettere, cifre e caratteri non ASCII sono sempre ok¹. Cita spazi bianchi e punteggiatura ogni volta che non sei sicuro.

Con una shell tipica (ksh, bash o zsh), è necessario citare i seguenti caratteri in almeno alcune circostanze.

  • Spazio bianco (spazio, tabulazione, nuova riga - ricordando che le nuove righe non possono essere quotate con una barra rovesciata).
  • ! - espansione della storia.
  • " - sintassi della shell.
  • #- commento inizia quando preceduto da spazi bianchi; caratteri jolly zsh.
  • $ - sintassi della shell.
  • & - sintassi della shell.
  • ' - sintassi della shell.
  • (- anche nel mezzo di una parola: globi estesi ksh (disponibile anche in bash e zsh); caratteri jolly zsh.
  • )(vedi ()
  • * - sh carattere jolly.
  • , - solo all'interno dell'espansione del tutore.
  • ; - sintassi della shell.
  • < - sintassi della shell.
  • = - in zsh, quando si trova all'inizio del nome di un file (espansione del nome file con ricerca PATH).
  • > - sintassi della shell.
  • ? - sh carattere jolly.
  • [ - sh carattere jolly.
  • \ - sintassi della shell.
  • ] - potresti cavartela lasciandola non quotata.
  • ^- espansione della storia; jolly zsh.
  • ` - sintassi della shell.
  • { - espansione parentesi graffa.
  • | - sintassi della shell.
  • } - deve essere evaso in zsh, altre shell sono più indulgenti quando non c'è parentesi graffa di apertura corrispondente.
  • ~- espansione della home directory quando è all'inizio del nome di un file; carattere jolly zsh; sempre al sicuro quando è l'ultimo personaggio.

Qualche altro personaggio può richiedere una gestione speciale a volte:

  • -non è speciale per la shell, ma quando è all'inizio di un argomento di comando, indica un'opzione. Non può essere protetto con virgolette poiché la gestione speciale è nel comando, non nella shell. Per proteggere un nome di file che inizia con -, puoi metterlo ./prima - in questo modo è ancora lo stesso file, ma l'argomento non inizia -più.
  • .non è speciale in sé, ma i file dot sono esclusi dai *globs per impostazione predefinita.
  • :non è speciale per la shell, ma alcuni comandi lo analizzano in modo particolare, ad esempio per indicare un file remoto ( hostname:filename). Consultare la documentazione del comando per vedere come far fronte a file infetti contenenti due punti.

¹ A meno che l'utente non abbia configurato caratteri di espansione della cronologia alternativi. Alcune shell lo consentono. Questo è un altro motivo per usare le virgolette singole anziché le barre rovesciate.


I newline, almeno LF, possono essere citati con una barra rovesciata in alcune shell.
iBug

@iBug No. In qualsiasi shell sh-like, backslash + newline si espande in una stringa vuota, non in una nuova riga.
Gilles 'SO- smetti di essere malvagio' il

Questa è una buona risposta, grazie. Esiste un collegamento a dove queste informazioni sono "ufficialmente" disponibili?
Slashmais,

1
@slashmais Quali informazioni? La sintassi del linguaggio shell è "ufficialmente" disponibile in vari manuali e specifiche, ma va da lì a scoprire esattamente quali caratteri devono essere citati dove non è del tutto semplice.
Gilles 'SO- smetti di essere malvagio' il

1
Ho anche trovato questo: tecmint.com/manage-linux-filenames-with-special-characters - non è compatto come il tuo elenco, ma ha molti esempi. (a
proposito
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.