Copy & append using a Bash Script

looking to extend the Automating Initial Server Setup with Ubuntu 18.04 script with copying whole files and appending other files.
for example the /bash.rc file, if I wanted to customize the PS1 variable, I know how to do that manually, but how would I append it to the end of the file by using this script?

and is appending to the end my only option? What if I wanted to insert in the middle of a file instead of the end, would I be better off replacing the whole file? Or is there to say add it after a particular line even if it’s not the end of the file?

#!/bin/bash
set -euo pipefail

########################
### SCRIPT VARIABLES ###
########################

# Name of the user to create and grant sudo privileges
USERNAME=sammy

# Whether to copy over the root user's `authorized_keys` file to the new sudo
# user.
COPY_AUTHORIZED_KEYS_FROM_ROOT=true

# Additional public keys to add to the new sudo user
# OTHER_PUBLIC_KEYS_TO_ADD=(
#     "ssh-rsa AAAAB..."
#     "ssh-rsa AAAAB..."
# )
OTHER_PUBLIC_KEYS_TO_ADD=(
)

####################
### SCRIPT LOGIC ###
####################

# Add sudo user and grant privileges
useradd --create-home --shell "/bin/bash" --groups sudo "${USERNAME}"

# Check whether the root account has a real password set
encrypted_root_pw="$(grep root /etc/shadow | cut --delimiter=: --fields=2)"

if [ "${encrypted_root_pw}" != "*" ]; then
    # Transfer auto-generated root password to user if present
    # and lock the root account to password-based access
    echo "${USERNAME}:${encrypted_root_pw}" | chpasswd --encrypted
    passwd --lock root
else
    # Delete invalid password for user if using keys so that a new password
    # can be set without providing a previous value
    passwd --delete "${USERNAME}"
fi

# Expire the sudo user's password immediately to force a change
chage --lastday 0 "${USERNAME}"

# Create SSH directory for sudo user
home_directory="$(eval echo ~${USERNAME})"
mkdir --parents "${home_directory}/.ssh"

# Copy `authorized_keys` file from root if requested
if [ "${COPY_AUTHORIZED_KEYS_FROM_ROOT}" = true ]; then
    cp /root/.ssh/authorized_keys "${home_directory}/.ssh"
fi

# Add additional provided public keys
for pub_key in "${OTHER_PUBLIC_KEYS_TO_ADD[@]}"; do
    echo "${pub_key}" >> "${home_directory}/.ssh/authorized_keys"
done

# Adjust SSH configuration ownership and permissions
chmod 0700 "${home_directory}/.ssh"
chmod 0600 "${home_directory}/.ssh/authorized_keys"
chown --recursive "${USERNAME}":"${USERNAME}" "${home_directory}/.ssh"

# Disable root SSH login with password
sed --in-place 's/^PermitRootLogin.*/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config
if sshd -t -q; then
    systemctl restart sshd
fi

# Add an exception for SSH and then enable UFW firewall
ufw allow OpenSSH
ufw --force enable

# customize (append) /bash.rc PS1

# copy a file from to the new server

echo 'line to add' >> filename.txt

no.

No.

Depends on how complex you want to make it. There are multiple ways to do it, and multiple tools that can do so. If you know the line number you want to insert at,
sed -i 'linenoitext to add' filename.txt
which may look like
sed -i '3iLine 3 Goes Here' filename.txt

or with a text search:
sed -i '/texttofind/a texttoadd' filename.txt

1 Like

thank you

What about quotes in quotes, Would this work?

# customize TTY prompt
echo 'PS1='${debian_chroot:+($debian_chroot)}\n\@ \[\e[32;40m\]\u\[\e[m\] \[\e[32;40m\]@\[\e[m\]\n \[\e[32;40m\]\H\[\e[m\] \[\e[36;40m\]\w\[\e[m\] \[\e[33m\]\\$\[\e[m\] '' >> etc/skel.bashrc

would I just use a backslah to escape the quotes?

# customize TTY prompt
echo 'PS1=\'${debian_chroot:+($debian_chroot)}\n\@ \[\e[32;40m\]\u\[\e[m\] \[\e[32;40m\]@\[\e[m\]\n \[\e[32;40m\]\H\[\e[m\] \[\e[36;40m\]\w\[\e[m\] \[\e[33m\]\\$\[\e[m\] \'' >> etc/skel.bashrc

put double quotes around the outside?

I’m working on wording it as a new question now…
but I need to replace line 59 or it may be it’s 60, which is not the end of the file…
so would it be?

sed -i "59 PS1='${debian_chroot:+($debian_chroot)}\n\@ \[\e[32;40m\]\u\[\e[m\] \[\e[32;40m\]@\[\e[m\]\n \[\e[32;40m\]\H\[\e[m\] \[\e[36;40m\]\w\[\e[m\] \[\e[33m\]\\$\[\e[m\]' etc/skel.bashrc"

I’m guessing the -i flag is an insert, would it be an -r to replace?

-i flags it as “in-place”, so you dont have to specify output or pipe to cat or anything like that.

The string is making my eyes do weird things.

You’d probably have a better time of it replacing based on a search…

sed -i 's/stringtoreplace/stringtoreplaceitwith/' filename.txt

\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$

the main problem seems to be the [ brackets ]
because sed would see this as a range.
Is there an option for escaping the range brackets or you’d mentioned other options… would I have the same problem with awk?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.