Shell: scrive il contenuto delle variabili in un file


95

Vorrei copiare il contenuto di una variabile (qui chiamata var ) in un file.

Il nome del file è memorizzato in un'altra variabile destfile .

Ho problemi a farlo. Ecco cosa ho provato:

cp $var $destfile

Ho anche provato la stessa cosa con il comando dd ... Ovviamente la shell ha pensato che $varsi riferisse a una directory e quindi mi ha detto che la directory non poteva essere trovata.

Come posso aggirare questo problema?


2
Migliora la tua domanda pubblicando del codice correttamente formattato che mostri come stai popolando le tue variabili e tutti i messaggi di errore pertinenti esattamente come appaiono.
Todd A. Jacobs

2
Cosa intendi per "copiare il contenuto di una variabile" in una directory? Non $varspecificare un nome di file o un testo che dovrebbe essere scritta in un file? Se specifica del testo, qual è il nome del file in cui desideri scrivere questo contenuto?
jahroy

$ var contiene il testo che voglio essere copiato e il file in cui dovrebbe essere scritto è definito dall'utente, da qui il motivo per cui sto usando una variabile in primo luogo.
user1546083

1
Forse $destdirdovrebbe essere chiamato $destfilecosì non è fuorviante ... Il nome $destdirsuggerisce che specifica una directory piuttosto che un file. Ciò renderebbe l'intera tua domanda semplice e di facile comprensione.
jahroy

Risposte:


145

Usa il echocomando:

var="text to append";
destdir=/some/directory/path/filename

if [ -f "$destdir" ]
then 
    echo "$var" > "$destdir"
fi

I iftest che $destdirrappresentano un file.

Il >aggiunge il testo dopo troncare il file. Se desideri solo aggiungere il testo $varal contenuto del file esistente, usa >>invece:

echo "$var" >> "$destdir"

Il cpcomando viene utilizzato per copiare file (su file), non per scrivere testo in un file.


4
Ha bisogno di più virgolette - in questo momento, qualsiasi sequenza di spazi all'interno del valore della variabile verrà convertita in un singolo spazio, le espressioni glob verranno espanse, ecc.
Charles Duffy

2
Un'altra cosa: hai bisogno di uno spazio tra la citazione di chiusura e l' ]in "$destdir"].
Charles Duffy

3
echoaggiunge anche una nuova riga finale alla tua variabile.
Ben Dilts,

6
Questo fallisce se $varè -e text to append, e in realtà non scrive-e
Eric

1
Poiché echo $varsi basa sulla shell per espandere la variabile, non funziona molto con cose come spazi bianchi e caratteri speciali. Puoi perl -e 'print($ENV{var})'invece usare e restituirà esattamente il valore della variabile.
Blake Mitchell

38

echoha il problema che se varcontiene qualcosa di simile -e, verrà interpretato come una bandiera. Un'altra opzione è printf, ma printf "$var" > "$destdir"espanderà tutti i caratteri di escape nella variabile, quindi se la variabile contiene barre rovesciate il contenuto del file non corrisponderà. Tuttavia, poiché printfinterpreta solo i backslash come escape nella stringa di formato, è possibile utilizzare l' %sidentificatore di formato per memorizzare il contenuto esatto della variabile nel file di destinazione:

printf "%s" "$var" > "$destdir"


1
printf è utile anche se hai delle nuove righe nella stringa variabile, come da virgolette triple o heredoc. echo non gestisce bene le nuove righe.
beeflobill

@beeflobill puoi spiegare come "echo non gestisce bene le nuove righe". L'unica cosa che ho visto è che l'eco aggiunge una nuova riga. Il che fa echo "$var" > destfilemale.
SensorSmith

@SensorSmith Nei miei esperimenti, vedo che quando la stringa ha "\ n" quell'eco stamperà un carattere di nuova riga. Ma, se la stringa ha un carattere di nuova riga effettivo, echo non lo stamperà. Non so perché
beeflobill

1
Fondamentalmente un problema di portabilità (e affidabilità). unix.stackexchange.com/a/65819… o per i mortali tra noi: printfè meglio, vai avanti.
user3342816

29

Nessuna delle risposte precedenti funziona se la tua variabile:

  • inizia con -e
  • inizia con -n
  • inizia con -E
  • contiene un file \ seguito da unn
  • non dovrebbe avere una nuova riga in più aggiunta dopo

e quindi non si può fare affidamento su di essi per contenuti di stringhe arbitrarie.

In bash, puoi usare "here strings" come:

cat <<< "$var" > "$destdir"

Come notato nel commento qui sotto, la risposta di @ Trebawa (formulata nella stessa stanza della mia!) L'uso printfè un approccio migliore.


5
Da quello che posso dire, cat inserirà sempre una nuova riga alla fine del file, indipendentemente dal fatto che non ci sia una nuova riga alla fine della variabile (anche se probabilmente questa è una buona cosa nella maggior parte dei casi). La risposta usando printf sembra evitare di inserire una nuova riga finale.
Ash

@ Ash un altro vantaggio di printfover catè che il primo è un builtin di shell che verrà sempre eseguito più velocemente di un binario esterno.
Géza Török

7

Se ho capito bene, vuoi copiare $varin un file (se è una stringa).

echo $var > $destdir

Ecco come si fa. L'uso del cpcomando farà in modo che la shell interpreti il ​​primo argomento come il nome di un file o di una directory.
jahroy

5
Se non si racchiude $vartra virgolette, in alcuni casi il contenuto del file non è uguale al 100% al contenuto di $ var. Ad esempio, quando "echo" vars che contiene chiavi RSA, ottieni una chiave non valida nel file.
srigi

6
Non riesce se $varcontiene spazi o-e
Eric

1

Quando dici "copia il contenuto di una variabile", quella variabile contiene un nome di file o contiene il nome di un file?

Suppongo che la tua domanda $varcontenga i contenuti che desideri copiare nel file:

$ echo "$var" > "$destdir"

Questo riporterà il valore di $ var in un file chiamato $ destdir. Nota le virgolette. Molto importante avere "$ var" racchiuso tra virgolette. Anche per "$ destdir" se c'è uno spazio nel nome. Per aggiungerlo:

$ echo "$var" >> "$destdir"

3
Non riesce se varcontiene-e
Eric

1
Passare un doppio trattino come primo argomento per echo terminare il suo elenco di opzioni, risolvendo così il problema sollevato da @Eric:echo -- "$var" >> "$destfile"
Géza Török

1

Tutto quanto sopra funziona, ma deve anche aggirare un problema (escape e caratteri speciali) che non deve necessariamente verificarsi in primo luogo: caratteri speciali quando la variabile viene espansa dalla shell. Basta non farlo (espansione variabile) in primo luogo. Usa la variabile direttamente, senza espansione.

Inoltre, se la tua variabile contiene un segreto e desideri copiare quel segreto in un file, potresti non desiderare l'espansione nella riga di comando poiché l'eco di traccia / comando dei comandi della shell potrebbe rivelare il segreto. Significa, tutte le risposte che usano$var nella riga di comando possono avere un potenziale rischio per la sicurezza esponendo il contenuto della variabile alla traccia e alla registrazione della shell.

Usa questo:

printenv var >file

Ciò significa che, in caso di domanda OP:

printenv var >"$destfile"
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.