How to create a file with pre-inserted text inside with bash?

I want to make small bash scripts that will automate some stuff for me in new machines.

The only thing I still do manual is creating files with vi and pasting the text on the file.

How can I generate file X with “text i need here” inside it on bash? Without having to press enter, overwrite files if necessary and also create directories as needed?

Thanks

Example : Replacing a default sshd_config file with my version and creating a file with my public SSH key inside it. Generating another .sh file on-the-fly. Stuff like that.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

For text content, the easiest, especially if the text contains multiple lines is to use a here-document. Add these lines to your script for instance for your script to create a file.txt with this text:

cat << 'EOF' > file.txt
Here is some text
or other
EOF

(you can use anything in place of EOF above as the end of file marker provided it doesn’t occur in the text to insert. The first EOF has to be quoted to prevent any expansion inside the here-document).

For files with arbitrary content, you can use uudecode. It also lets you specify the permissions for the file being created. For instance for a script to create a foo file with the content and permissions of /bin/ls, do:

(echo 'uudecode << "_EOF_"'
uuencode -m /bin/ls foo
echo _EOF_) >> your-script

Which will add the correspond code to your script. Something like:

uudecode << "_EOF_"
begin-base64 755 foo
f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAMFQAAAAAAABAAAAAAAAAADD3AQAA
[...]
AAAAAAAAAAAAAAA=
====
_EOF_

With the content of /bin/ls encoded in base64.

That assumes the uudecode is available on the machine you’re going to run that command in. But that should generally be the case as uudecode is a POSIX command.

You can extend that to create several files by encoding a compressed tar archive:

(echo 'uudecode << "_EOF_" | gunzip | tar xpf -'
tar cf - file1 file2 file3 dir/file4 | uuencode -m -
echo '_EOF_') >> your-script

(assuming the target system has gunzip and tar (not POSIX commands but quite common)).

That also has the benefit of letting you encode additional file metadata like ownership or access and modification time (and more like ACLs and extended attributes, and hard link relationship with some tar implementations). It also allows you to easily create non-regular files like directories, symlinks, devices…

See also the shar utility which can help you create portable self-extractable archives.

Method 2

A script could do

sudo mv /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
sudo cp "$HOME/my_configs/sshd_config" /etc/ssh/
sudo chmod go-w /etc/ssh/sshd_config

or

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
cat "$HOME/my_configs/sshd_config" | sudo tee /etc/ssh/sshd_config >/dev/null

to back up any old sshd_config and then install a new one.

I mean, it’s just a matter of having a collection of files somewhere and then copy them to the correct locations and making sure that the installed files have the correct permissions. This could be automated with a script.

There are however specialized software for doing automatic provisioning and configuration management, such as Ansible and Puppet.

These types of software may become more interesting as soon as you need to set up more than a couple of machines. We, for example, use Ansible to set up private Docker containers for our customers on our compute-cluster.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x