L’escape dei caratteri speciali in bash variabili

Sto cercando di leggere un file contenente i percorsi di linea per linea, scp, il file su un altro server, ma a causa di alcuni caratteri nei nomi di file come ‘(‘, ‘)’, ‘&’, etc. Ho bisogno di fuggire ingresso:

input.txt:

/folder1/folderA/filename+(oh+how+nice,+parantheses)

script.sh:

#!/bin/sh

promote_to=random.server.com
dev_catalog=/folderX/
uat_catalog=/folderY/

while read line
do
uat_path=$(echo "$uat_catalog$line" | sed -e "s/(/\\\(/g" | sed -e "s/)/\\\)/g")
dev_path=$(echo "$dev_catalog$line" | sed -e "s/(/\\\(/g" | sed -e "s/)/\\\)/g")

scp $dev_path [email protected]$promote_to:$uat_path
scp $dev_path".atr" [email protected]$promote_to:$uat_path".atr"
done < "input.txt"

Uscita:

-bash: /folder1/folderA/filename+(oh+how+nice,+parantheses): No such file or directory
-bash: /folder1/folderA/filename+(oh+how+nice,+parantheses): No such file or directory
usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
               [-l limit] [-o ssh_option] [-P port] [-S program]
               [[[email protected]]host1:]file1 [...] [[[email protected]]host2:]file2
ssh: random.server.com: Name or service not known
lost connection

Qualsiasi tipo di aiuto è apprezzato.

OriginaleL’autore Andrei Ionita | 2012-02-28

2 Replies
  1. 9

    Parte del problema qui è che il locale e remoto nomi di file vengono analizzati in modo diverso: il nome del file locale è utilizzato direttamente, quindi l’unica cosa che devi fare è necessario racchiuderlo tra virgolette doppie (come in @Ignacio risposta), ma il nome del file remoto viene passata ad una shell remota, che corre attraverso un altro livello di analisi (la citazione e la fuga di rimozione, ecc). Così, si desidera aggiungere scappa il percorso remoto solo. Ho anche preso la libertà di semplificare la sed comando un po’:

    #!/bin/sh
    
    promote_to=random.server.com
    dev_catalog=/folderX/
    uat_catalog=/folderY/
    
    while read line
    do
    uat_path="$(echo "$uat_catalog$line" | sed -e 's/[()&]/\\&/g')"
    dev_path="$dev_catalog$line"
    
    scp "$dev_path" "[email protected]$promote_to:$uat_path"
    scp "$dev_path.atr" "[email protected]$promote_to:$uat_path.atr"
    done < "input.txt"

    Di notare che la sed schema che ho utilizzato, 's/[()&]/\\&/g', solo sfugge parentesi e commerciali; se i nomi dei file contengono altri metacaratteri della shell, essere sicuri di aggiungere alla lista di caratteri in [].

    Grazie mille per la risposta dettagliata!
    Per coloro che chiedono su come escape degli apici singoli, vedi qui: unix.stackexchange.com/questions/9746/…

    OriginaleL’autore Gordon Davisson

  2. 0

    Che si sta tentando di eseguire /folder1/folderA/filename+(oh+how+nice,+parantheses) come un comando. Probabilmente intendeva fare echo /folder1/folderA/filename+(oh+how+nice,+parantheses) | ... invece.

    Edit: cosa @Ignacio detto.

    che è di destra… perso l’eco, ma non funziona ancora: “/cartella1/folderA/filename+\(oh+come+bello,+parantheses\): No such file or directory”
    la rimozione di una barra rovesciata da ogni sed genera questa però: “bash: -c: riga 0: errore di sintassi vicino al token imprevisto (' bash: -c: line 0: scp -t bash: -c: riga 0: errore di sintassi vicino al token imprevisto (' bash: -c: line 0: scp -t /cartella1/folderA/filename+(oh+come+bello,+parantheses)’ perso la connessione”

    OriginaleL’autore Eduardo Ivanec

Lascia un commento