Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash write to file without echo?

People also ask

How do you write inside a file in Linux?

In Linux, to write text to a file, use the > and >> redirection operators or the tee command.


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

I had the problem not being able to send ">" and ended up with echo!

echo "Hello world" | dd of=test.txt

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.


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

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

awk ' BEGIN { print "Hello, world" } ' > test.txt

would do it