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