Linux Shell基线配置相关操作
Posted 诸子流
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux Shell基线配置相关操作相关的知识,希望对你有一定的参考价值。
一、输入解析类
1.1 echo解析tab和换行
问题描述:echo默认是原样输出字符串,并不解析\\t和\\n等反斜杠字符,如下图所示。我们希望echo能解析\\t和\\n等字符。
处理办法:可以使用-e指示echo识别反斜杠。
1.2 获取给定路径中的上级目录名和文件名
# 给定路径名称。以/etc/passwd为例 path="/etc/passwd" # 路径对应的上级文件夹名。这里结果为/etc dir_name=`dirname ${path}` # 最终目录/文件名。这里结果为passwd base_name=`basename ${path}`
1.3 cat将变量写入文件
问题描述:我们经常需要将变量写到配置文件,比如将java相关的几个变量写到~/.profile,追加多行cat是最方便的但cat默认会在插入时解析变量,如下图所示。我们希望就是原样写入而不自动解析变量。
处理办法:可通过给EOF加上单引号来指示cat不要解析变量。
参考:https://blog.csdn.net/u010154760/article/details/45955797
1.4 sed使用变量
我们知道sed的基本格式如下:
# 将test.txt中,匹配matchReg的位置,替换成string sed -i \'s/matchReg/string/g\' test.txt
如果matchReg和string部分是确定的那没什么问题,但如果在该部分中我们想使用变量,该如何写呢。答案是将单引号改成双引号:
# 我们以matchReg部分用变量代替作为演示 # sed使用变量的关键就在于将单引号改成双引号 matchReg="anythig" sed -i "s/${matchReg}/string/g" test.txt
1.5 while语句中修改变量值
问题描述:我们知道shell中的变量是全局的,但如果注意会发现有时在while语句内修改变量值并不生效。如下所示,我们想用while语句统计/etc/passwd中的用户数量,但user_count最后依然是0。
user_count=0 cat /etc/passwd | while read line do user_count=`expr $user_count + 1` done echo $user_count
处理办法:造成这种情况的原因是while针对数据从管道传输过来这种方式,会启动一个子shell去处理,在子shell中修改参数并不能影响当前shell中的参数的值(相当于函数中的传值)。解决办法是换一种while就在当前shell中处理的写法。
user_count=0 while read line do user_count=`expr $user_count + 1` done <<< "$(cat /etc/passwd)" echo $user_count
1.6 Windows换行转Linux换行
问题描述:Windows换行是“\\r\\n”,而Linux换行是“\\n”;Windows上的编写shell文件直接传到Linux系统上运行会报错“$\'\\r\': command not found”(用vim打开文件会看到行尾是^M),此时需要将“\\r”删除。
处理办法:
shell脚本文件已传到Linux上使用sed删除----sed -i -r \'s/\\r$//g\' file_name
shell脚本文件还在Windows上使用Notepad++编缉器转换----菜单----编缉----文档格式转换----转换为Unix格式
sehll脚本由python3动态生成----打开文件时使用newline指定生成文件的换行符,如file_obj = open("test.sh","w+",encoding="utf-8",newline="\\n")
参考:https://www.zhihu.com/question/19751023
另附pycharm指定行分格符的方法----与上边说的shell脚本换行无关,即便pycharm指定换行符为“LF”不通过newline指定动态生成的文件换行符依然是“\\r\\n”----分以下三类情况讨论
修改单个文件换行符----pycharm打开文件并切换到该文件----右下角有当前页面的换行符,在其上点击切换为“LF - Unix and OS X (\\n)”
修改文件夹下所有文件换行符----pycharm打开项目----在工程窗口使用光标选中要修改换行符的文件夹----菜单----File----Line Separators----“LF - Unix and OS X (\\n)”
指定后续新建文件换行符(不影响已有文件)----菜单----File----Setting----Code Style----Line separator----设置为“Unix and OS X (\\n)”
参考:https://www.jetbrains.com/help/pycharm/configuring-line-endings-and-line-separators.html
二、输出查找类
2.1 tail读取指定行后内容
问题描述:我们可以用tail配合-n指定读取文件最后多少行,但如果文件是不定长的而我想读取第1行以后的所有行,这个场景该怎么实现呢。
处理办法:其实-n除了直接接数字还,可以在数字前使用“+”号表示从第几行开始读取。(head的-n有类似的操作head -n -2即表示读取到倒数第二行)
2.2 grep查找进程并过滤查找命令本身
问题描述:我们经常使用ps -ef | grep something的语句去查找进程(以便进一步获取pid等),但此时grep本身也会被打印出来,如下图所示。我们希望grep语句本身也被过滤掉。
处理办法:使用grep -v grep将grep语句去掉
2.3 grep打印匹配行的前后几行
问题描述:我们使用grep查找时默认只打印匹配行,这种实现是合理的,但有时候匹配行与前后部份是强关联的我们也想获取。
处理办法:我们可以使用-A num指示打印匹配行的后几行,使用-B num指示打印匹配行的前几行。
2.4 sed去除块注释
问题描述:在读取tomcat等配置文件时,如果只是直接grep那查找出的内容可能其实是在块注释之中,该项配置其实并不生效。我们希望能先将配置文件中先将所有注释先去除掉。
处理办法:此时可以使用sed \'/regex/d\'删除单行注释,使用sed \'/star_line_regex/,/end_line_regex/d\'来删除掉块注释(d换成p就可用作查找块)。具体到tomcat如下
cat tomcat-users.xml |sed \'/<!--.*-->/d\' | sed \'/<!--/,/-->/d\'
参考:https://askubuntu.com/questions/525974/how-to-remove-comments-from-an-xml-file
2.5 将字符串作为命令执行
问题描述:在shell脚本中我们有时希望使用一个变量保存要执行的命令,再用一个变量保存命令执行后得到的结果。在如下形式中我们需要写两遍命令,这是不符合复用思想的。
# 变量command保存要执行的命令pwd;第一次写pwd command="pwd" # 变量result保存要执行的命令pwd的结果;再次写pwd result=`pwd`
处理办法:我们可以使用eval命令,将command变量中保存的字符串作为命令执行,代码如下。
# 变量command保存要执行的命令pwd;第一次写pwd command="pwd" # 变量result保存要执行的命令pwd的结果;使用eval $command代替再次敲写命令pwd result=`eval $command`
2.6 想将字符串作为命令执行时命令中同时有单引号和元字符
# awk必须使用单引号,但同时其内部有元字符$ result=`cat /etc/passwd | awk -F: \'$3==0{print $1}\'| wc -l` # 如果直接不管三七二十一直接写成 # command="cat /etc/passwd | awk -F: \'$3==0{print $1}\'| wc -l" # result=`eval $command` # 那此时双引号,一方面会使其内的单引号的“所见即所得”功能失效 # 另一方面会根据其特性双引号内元字符会被解析 # 所以此时$command值为cat /etc/passwd | awk -F: \'==0{print }\'| wc -l # 这样eval肯定会报错
处理办法:此时需要使用反斜框对双引号内的元字符进行转义。
command="cat /etc/passwd | awk -F: \'\\$3==0{print \\$1}\'| wc -l" result=`eval $command`
2.7 输出base64编码
有时候有些字符串有特殊字符,此时我们可能会想要一种简单的方法对这些特殊字符进行处理,base64显然就是一种很方便的处理方法。
# 使用方法一:直接对文件进行base64 base64 /etc/passwd # 使用方法二:对字符串进行base64 echo "test str" | base64 # 避免自动换行。base64默认每76字节换行,如果我们原本的目录就是去掉特殊字符,自动换行会引入\\n # 我们可使用-w 0参数关闭自动换行 cat /etc/passwd | base64 -w 0
三、其他问题
3.1 获取nginx版本号
问题描述:我们知道nginx可以通过-v/-V来获取版本信息,但如果直接将查询赋给变量就会发现不能成功,如下图所示。(另外要获取which命令的输出可同样处理。)
处理办法:变量没有承接成功的原因是nginx将信息输出来了stderr而不是stdout,要承接我们需要将stderr重定向到stdout。
nginx_version=`nginx -v 2>&1`
参考:https://serverfault.com/questions/794873/cant-store-nginx-version-to-variable
3.2 获取tomcat版本号
问题描述:tomcat的版本号并不在响应的Server头中,只显示在默认的index.jsp和默认的错误页面中,此时可以通过curl获取其版本号(判断tomcat有没有设置隐藏版本号)。但如果默认index.jsp被删除且自定义了错误页面我们该如何通过shell获取到tomcat的版本号呢。
处理办法:此时我们还有三种办法可以获取到版本号。
第一种,解压$CATALINA_HOME/lib/catalina.jar,到org\\apache\\catalina\\util\\ServerInfo.properties文件中查看版本号。这理论上对服务没有影响,但动服务器文件的做法并不是很好。
第二种,使用java -cp $CATALINA_HOME/lib/catalina.jar org.apache.catalina.util.ServerInfo使用查看版本号。不过注意查找版本号的服务并不一定是运行tomcat的前户,其环境变量中并不一定有java。
第三种,运行$CATALINA_HOME/bin/version.sh获取版本信息。这个本质上还是执行第二种中的语句,一样需要有java命令才能获取结果。
参考:https://community.rsa.com/docs/DOC-81702
3.3 crontab中文乱码甚至使程序终止
问题描述:手动在控制台运行脚本时程序运行无误,但使用crontab运行时当处理到中文程序直接终止退出(我的场景是python3将中文写入txt文件)。
问题原因:此问题是crontab环境与控制台环境不一致所致,更本质讲是crontab环境没有中文相应编码所致。
处理办法:在执行python的shell脚本中,在执行python脚本前加入声明:export LANG="en_US.UTF-8"
https://blog.csdn.net/qq_33792843/article/details/77749661
https://blog.51cto.com/kaifly/2358278
3.4 yum任何命令都卡死、无输出、Ctrl+C无法中断问题排查
yum卡死一般都是因为先前某个yum或rpm占用了锁没释放,可借助strace命令查看yum执行到哪出的问题。
strace yum search python3
yum卡死一般可以通过删除以下文件处理:
rm /var/lib/rpm/__db* rm /var/lib/rpm/.rpm.lock rm /var/lib/rpm/.dbenv.lock
参考:https://serverfault.com/questions/392589/yum-clean-hangs-what-to-try-next
以上是关于Linux Shell基线配置相关操作的主要内容,如果未能解决你的问题,请参考以下文章