- 编辑-06/08/23-原始问题基本相同**
感谢Charles Duffy在评论中提供宝贵的反馈。原来的问题出现在第1项的上下文中。但根据反馈,项目2似乎是管理系统管理任务的更好选择。当我完成对perl
和/etc/profile.d
的研究后,我可能会在这里打开另一个问题,或者在我的答案中发布一些信息。
1.原始问题:如何使用sed
、awk
或perl
搜索和替换文件中的文字字符串,例如.bashrc
文件中的PS1=<string>
?
1.更好的问题是如何使用存储在/etc/profile.d
中的脚本启用所需的提示行为,这些脚本在用户登录时自动执行?
目标是在Debian PC和DietPi(ARM)Linux系统上自动化自定义bash提示符。自定义提示符插入一个空行,将命令与终端输出分开,看起来像这样,但颜色不同:
root@dpiBox /root
#
user@dpiBox /home/user
$
其中root@dpiBox是红色; user@dpiBox为绿色;并且当前工作目录总是以蓝色显示。
当创建新的user
时,/etc/skel/.bashrc
的副本将作为/home/user/.bashrc
放置在用户的主目录中。root用户已将副本创建为/root/.bashrc
。
我最初的计划是在添加新用户之前通过脚本编辑/etc/skel/.bashrc
,并手动编辑/root/.bashrc
。但是当root或任何用户登录时,它会自动执行正确安装在/etc/profile.d
下的脚本。Charles Duffy似乎建议使用此功能来更好地管理系统管理挑战!
默认/etc/skel/.bashrc
和/root/.bashrc
和/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
第1步-取消注解行以打开颜色提示:
force_color_prompt=yes
第2步-用新的PS1(如图所示)替换旧的PS1(如图所示)以自定义bash提示符:
PS1='${debian_chroot:+($debian_chroot)}\n\[\033[01;32m\]\u@\h\[\033[00m\]\[\033[01;34m\] $(pwd -P) \[\033[00m\]\n\$ '
/home/user/.bashrc
的代码[01;32m\]
为绿色。将此代码更改为[01;31m\]
,对于/root/.bashrc
为红色。
- 步骤1-sed:**良好结果
/usr/local/bin/bashsed(编辑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
代码与用于定义on
和off
的双引号或单引号一起使用。必须在sed命令中使用双引号。
- 步骤1-perl:**结果良好
/usr/local/bin/bashperl(编辑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
i.bak
交换机将/root/bashtest
备份为/root/bashtest.bak
,然后就地编辑文件。此命令可以在命令行上使用,而无需使用i.bak
开关。
- 步骤2-sed:**
sed -i "s|$old|$new|" /root/bashtest
的错误结果
- 步骤2-sed:**
/usr/local/bin/bashsed(编辑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
第2步:当使用双引号定义old
和new
时,代码运行没有错误,但产生无结果。当使用单引号定义old
和new
时,代码抛出错误sed: -e expression #1, char 149: unterminated
s' command`。
- 编辑-06/08/23-评论**
在bash
脚本中使用perl
调用将我的解决方案发布到步骤2。
根据Charles Duffy的反馈,Step 2的perl
解决方案可以修改为使用存储为bash环境变量的文字字符串。相关信息在此链接下的页面顶部附近提供:
https://mywiki.wooledge.org/BashFAQ/021
根据CharlesDuffy的说法,当用户登录时,脚本应该从/etc/profile.d
运行,以便更好地管理系统管理员任务。我需要做更多的研究来理解这种反馈。这里有两个链接可能会有帮助:
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
- 原题链接**
我已经广泛搜索,在下面的上下文中尝试了几十个实验,我无法理解这些参考文献:
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
所以我需要检查我的"sed"!如果awk可以完成这项工作,我不介意使用它,但是在插入文字字符串之前,我需要查看简单的命令结构。否则,我总是搞砸语法。
1条答案
按热度按时间n53p2ov01#
使用
perl
而不是sed
或awk
求解。主要依赖于以下参考:https://www.perl.com/pub/2004/08/09/commandline.html/
PS1中的
old
文字字符串:perl
匹配的old
字符串转义:PS1中的
new
文字字符串perl
替换操作的new
字符串转义:在命令行上使用pattern调试文字字符串的转义序列:
带有测试输入文件
ps1old
的命令行解决方案将结果写入ps1out
此方法将结果写入文件
ps1out
,同时对占位符old
和占位符new
表示的文字字符串从左到右测试转义序列模式。当转义序列失败时,文件
ps1old
或文件ps1new
不变;文件ps1out
恢复为相应输入文件的副本;而perl
提供了有价值的调试信息。当转义序列成功时,文件
ps1out
显示虚拟字符串DummyString
,作为从左到右工作的old
或new
的部分的替换,以调试转义模式。这可以一次执行一个转义字符,以系统地隔离语法错误。调试完占位符
old
和new
的文字字符串后,使用perl
调用将工作结果传输到bash
脚本,如下所示。一种改进可能是将更改写入新文件,然后将其移动到目标
.bashrc
,并保留.bashrc.bak
用于备份。如果此脚本运行不止一次,它会用编辑过的版本覆盖备份副本!
Bash脚本调用perl