Edit - 06/08/23 - Original Question Kept Substantially the Same
Thanks to Charles Duffy for providing valuable feedback in comments. The original question occurs in the context of item 1. But based on the feedback it appears that item 2 is the better option for managing system administration tasks. I may open another question or perhaps post some information in my answer here when I finish my research into perl and /etc/profile.d.
- Original Question: How to search and replace literal strings in a file, such as PS1=<string>in a.bashrcfile, usingsed,awk, orperl?
- Better question: How to enable desired prompt behavior using script(s) stored in /etc/profile.dthat automatically execute whenever a user logs in?
Goal is to automate custom bash prompt on Debian PC and DietPi (ARM) Linux systems. The custom prompt inserts a blank line, to separate commands from terminal output, and looks like this but with different colors:
root@dpiBox /root
#
user@dpiBox /home/user
$
where root@dpiBox is red; user@dpiBox is green; and the present working directory is always shown in blue.
When a new user is created then a copy of /etc/skel/.bashrc is placed in the user's home directory as /home/user/.bashrc. The root user already has a copy made as /root/.bashrc.
My original plan was to edit /etc/skel/.bashrc via script before adding new users and to manually edit the /root/.bashrc. But when root or any user log in this automatically executes scripts properly installed under /etc/profile.d. Charles Duffy seems to be advising the use of this feature for better management of system administration challenges!
Relevant lines in default /etc/skel/.bashrc and /root/.bashrc and /home/user/.bashrc
# /root/bashtest (simulates default .bashrc)
# /etc/skel/.bashrc
# /root/.bashrc
# /home/user/.bashrc
#force_color_prompt=yes
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
Step 1 - Uncomment line to turn on color prompt:
force_color_prompt=yes
Step 2 - Replace old PS1 (above) with new PS1 (shown here) to customize bash prompt:
PS1='${debian_chroot:+($debian_chroot)}\n\[\033[01;32m\]\u@\h\[\033[00m\]\[\033[01;34m\] $(pwd -P) \[\033[00m\]\n\$ '
The code [01;32m\] is green for /home/user/.bashrc. Change this code to [01;31m\] which is red for /root/.bashrc.
Step 1 - sed: good result
/usr/local/bin/bashsed (development script to edit bashtest/.bashrc)
#!/bin/bash
# uncomment to force color prompt on
off="#force_color_prompt=yes"
on="force_color_prompt=yes"
sed -i "s|$off|$on|" /root/bashtest
sed code works with double quotes or single quotes used to define on and off. The double quotes must be used in the sed command.
Step 1 - perl: good result
/usr/local/bin/bashperl (development script to edit bashtest/.bashrc)
#!/bin/bash
# uncomment to force color prompt on
perl -i.bak -pe 's/#force_color_prompt=yes/force_color_prompt=yes/' /root/bashtest
The i.bak switch backs up /root/bashtest as /root/bashtest.bak then edits the file in place. This command can be used on the command line without using the i.bak switch.
Step 2 - sed: Bad result for sed -i "s|$old|$new|" /root/bashtest
/usr/local/bin/bashsed (development script to edit bashtest/.bashrc)
#!/bin/bash
# replace old PS1 with new PS1
# old                                    \[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\
# PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
old='\\[\\033\[01;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033\[01;34m\\]\\w\\[\\033\[00m\\]\\'
# new                                    \n\[\033[01;32m\]\u@\h\[\033[00m\]\[\033[01;34m\] $(pwd -P) \[\033[00m\]\n\
# PS1='${debian_chroot:+($debian_chroot)}\n\[\033[01;32m\]\u@\h\[\033[00m\]\[\033[01;34m\] $(pwd -P) \[\033[00m\]\n\$ '
new='\\n\\[\\033\[01;32m\\]\\u@\\h\\[\\033\[00m\\]\\[\\033\[01;34m\\] \$(pwd -P) \\[\\033\[00m\\]\\n\\'
sed -i "s|$old|$new|" /root/bashtest
Step 2 the code runs without error, but produces no results, when double quotes are used to define old and new. The code throws an error sed: -e expression #1, char 149: unterminated `s' command when single quotes are used to define old and new.
Edit - 06/08/23 - Comments
Posted my solution to Step 2 using perl call in a bash script.
Based on feedback from Charles Duffy the perl solution for Step 2 can be modified to use literal strings stored as bash environment variables. Relevant information is provided near the top of the page under this link:
https://mywiki.wooledge.org/BashFAQ/021
According to Charles Duffy scripts should run from /etc/profile.d when a user logs in to better manage sysadmin tasks. I need to do more research to understand this feedback. Here are two links that might be helpful:
https://serverfault.com/questions/434321/when-are-scripts-inside-etc-profile-d-executed
https://unix.stackexchange.com/questions/64258/what-do-the-scripts-in-etc-profile-d-do
Links in Original Question
I have searched extensively, tried dozens of experiments in the context below, and I cannot make sense of these references:
https://linuxhint.com/replace_string_in_file_bash/
Why would sed have trouble seeing my PS1 prompt?
Replacement of PS1 variable in .bashrc using Sed or Perl
Regarding sed expression evaluation in shell
So I need to have my "sed" examined! I would not mind using awk if it does the job, but then I need to see the simple command structure, before inserting the literal strings. Otherwise I always mess up the syntax.
