Reputation: 1927
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
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
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
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
Reputation: 97571
None of the answers above work if your variable:
-e
-n
-E
\
followed by an n
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
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
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
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
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