user1546083
user1546083

Reputation: 1927

Shell - Write variable contents to a file

I would like to copy the contents of a variable (here called var) into a file.

The name of the file is stored in another variable destfile.

I'm having problems doing this. Here's what I've tried:

cp $var $destfile

I've also tried the same thing with the dd command... Obviously the shell thought that $var was referring to a directory and so told me that the directory could not be found.

How do I get around this?

Upvotes: 169

Views: 452420

Answers (8)

Mattie B
Mattie B

Reputation: 21269

Building just a little bit off Eric's answer, we can use POSIX here-documents to a universally-compatible way to print the contents of a variable without it being expanded in a command line:

cat <<EOF >/path/to/file
$variable
EOF

The contents of "variable" can be anything I'm aware of (even "EOF") and it will output properly. There will be a trailing newline.

Upvotes: 0

Thykof
Thykof

Reputation: 995

you may need to edit a conf file in a build process:

echo "db-url-host=$POSTGRESQL_HOST" >> my-service.conf

You can test this solution with running before export POSTGRESQL_HOST="localhost"

Upvotes: 0

Christian Hujer
Christian Hujer

Reputation: 17945

All of the above work, but also have to work around a problem (escapes and special characters) that doesn't need to occur in the first place: Special characters when the variable is expanded by the shell. Just don't do that (variable expansion) in the first place. Use the variable directly, without expansion.

Also, if your variable contains a secret and you want to copy that secret into a file, you might want to not have expansion in the command line as tracing/command echo of the shell commands might reveal the secret. Means, all answers which use $var in the command line may have a potential security risk by exposing the variable contents to tracing and logging of the shell.

For variables that are already exported, use this:

printenv var >file

That means, in case of the OP question:

printenv var >"$destfile"

Note: variable names are case sensitive.

Warning: It is not a good idea to export a variable just for the sake of printing it with printenv. If you have a non-exported script variable that contains a secret, exporting it will expose it to all future child processes (unless unexported, for example using export -n).

Upvotes: 30

Eric
Eric

Reputation: 97571

None of the answers above work if your variable:

  • starts with -e
  • starts with -n
  • starts with -E
  • contains a \ followed by an n
  • should not have an extra newline appended after it

and so they cannot be relied upon for arbitrary string contents.

In bash, you can use "here strings" as:

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

As noted in the comment by Ash below, @Trebawa's answer (formulated in the same room as mine!) using printf is a better approach than cat.

Upvotes: 57

qwertz
qwertz

Reputation: 14792

If I understood you right, you want to copy $var in a file (if it's a string).

echo $var > $destdir

Upvotes: 8

Trebawa
Trebawa

Reputation: 959

echo has the problem that if var contains something like -e, it will be interpreted as a flag. Another option is printf, but printf "$var" > "$destdir" will expand any escaped characters in the variable, so if the variable contains backslashes the file contents won't match. However, because printf only interprets backslashes as escapes in the format string, you can use the %s format specifier to store the exact variable contents to the destination file:

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

Upvotes: 85

pb2q
pb2q

Reputation: 59617

Use the echo command:

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

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

The if tests that $destdir represents a file.

The > appends the text after truncating the file. If you only want to append the text in $var to the file existing contents, then use >> instead:

echo "$var" >> "$destdir"

The cp command is used for copying files (to files), not for writing text to a file.

Upvotes: 209

David W.
David W.

Reputation: 107040

When you say "copy the contents of a variable", does that variable contain a file name, or does it contain a name of a file?

I'm assuming by your question that $var contains the contents you want to copy into the file:

$ echo "$var" > "$destdir"

This will echo the value of $var into a file called $destdir. Note the quotes. Very important to have "$var" enclosed in quotes. Also for "$destdir" if there's a space in the name. To append it:

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

Upvotes: 0

Related Questions