Bash write to file without echo?
As an exercise, does a method exist to redirect a string to a file without echo? Currently I am using
echo "Hello world" > test.txt
I know about cat
and printf
. I was thinking something like
> test.txt <<<"Hello world"
Of course this doesnt work, but maybe a similar command?
Solution 1:
You can do this with "cat" and a here-document.
cat <<EOF > test.txt
some text
EOF
One reason for doing this would be to avoid any possibility of a password being visible in the output of ps. However, in bash and most modern shells, "echo" is a built-in command and it won't show up in ps output, so using something like this is safe (ignoring any issues with storing passwords in files, of course):
echo "$password" > test.txt
Solution 2:
I had the problem not being able to send ">" and ended up with echo!
echo "Hello world" | dd of=test.txt
Solution 3:
There are multiple ways to do it, let's run this script called exercise.sh
#!/usr/bin/env bash
> file1.txt cat <<< "This is a here-string with random value $RANDOM"
# Or if you prefer to see what is happening and write to file as well
tee file2.txt <<< "Here is another here-string I can see and write to file"
# if you want to work multiline easily
cat <<EOF > file3.txt
You don't need to escape any quotes here, $ marks start of variables, unless escaped.
This is random value from variable $RANDOM
This is literal \$RANDOM
EOF
# Let's say you have a variable with multiline text and you want to manipulate it
a="
1
2
3
33
"
# Assume I want to have lines containing "3". Instead of grep it can even be another script
a=$(echo "$a" | grep 3)
# Then you want to write this to a file, although here-string is fine,
# if you don't need single-liner command, prefer heredoc
# Herestring. (If it's single liner, variable needs to be quoted to preserve newlines)
> file4.txt cat <<< "$a"
# Heredoc
cat <<EOF > file5.txt
$a
EOF
This is the output you should see:
$ bash exercise.sh
Here is another here-string I can see and write to file
And files should contain these:
$ ls
exercise.sh file1.txt file2.txt file3.txt file4.txt file5.txt
$ cat file1.txt
This is a here-string with random value 20914
$ cat file2.txt
Here is another here-string I can see and write to file
$ cat file3.txt
You don't need to escape any quotes here, $ marks start of variables, unless escaped.
This is random value from variable 15899
This is literal $RANDOM
$ cat file4.txt
3
33
$ cat file5.txt
3
33
Solution 4:
There are way too many ways to possibly discuss that you probably don't care about. You can hack of course - strace bash, or do all sorts of black magic running Bash in gdb.
You actually have two completely different examples there. <<<'string'
is already writing a string to a file. If anything is acceptable other than printf
, echo
, and cat
, you can use many other commands to behave like cat (sed, awk, tee, etc).
$ cp /dev/stdin ./tmpfooblah <<<'hello world'; cat tmpfooblah
hello world
Or hell, depending on how you've compiled Bash.
$ enable -f /usr/lib/bash/print print; print 'hello world' >tmpfile
If you want to use only bash strings and redirection, in pure bash, with no hacking, and no loadables, it is not possible. In ksh93 however, it is possible.
$ rm tmpfooblah; <<<'hello world' >tmpfooblah <##@(&!()); cat tmpfooblah
hello world
Solution 5:
The way to do this in bash is
zsh <<< '> test <<< "Hello World!"'
This is one of the interesting differences between zsh and bash: given an unchained >
or >>
, zsh has the good sense to hook it up to stdin, while bash does not. It would be downright useful - if it were only standard.
I tried to use this to send & append my ssh key over ssh to a remote authorized_keys
file, but the remote host was bash, of course, and quietly did nothing.
And that's why you should just use cat
.