• Linux Shell基线检查高级操作


    一、输入解析类

    1.1 echo解析tab和换行

    问题描述:echo默认是原样输出字符串,并不解析 和 等反斜杠字符,如下图所示。我们希望echo能解析 和 等字符。

    处理办法:可以使用-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

    参考:https://stackoverflow.com/questions/16854280/a-variable-modified-inside-a-while-loop-is-not-remembered

    1.6 Windows换行转Linux换行

    问题描述:Windows换行是“ ”,而Linux换行是“ ”;Windows上的编写shell文件直接传到Linux系统上运行会报错“$' ': command not found”(用vim打开文件会看到行尾是^M),此时需要将“ ”删除。

    处理办法:

    shell脚本文件已传到Linux上使用sed删除----sed -i -r 's/ $//g' file_name

    shell脚本文件还在Windows上使用Notepad++编缉器转换----菜单----编缉----文档格式转换----转换为Unix格式

    sehll脚本由python3动态生成----打开文件时使用newline指定生成文件的换行符,如file_obj = open("test.sh","w+",encoding="utf-8",newline=" ")

    参考:https://www.zhihu.com/question/19751023

    另附pycharm指定行分格符的方法----与上边说的shell脚本换行无关,即便pycharm指定换行符为“LF”不通过newline指定动态生成的文件换行符依然是“ ”----分以下三类情况讨论

     修改单个文件换行符----pycharm打开文件并切换到该文件----右下角有当前页面的换行符,在其上点击切换为“LF - Unix and OS X ( )”

    修改文件夹下所有文件换行符----pycharm打开项目----在工程窗口使用光标选中要修改换行符的文件夹----菜单----File----Line Separators----“LF - Unix and OS X ( )”

    指定后续新建文件换行符(不影响已有文件)----菜单----File----Setting----Code Style----Line separator----设置为“Unix and OS X ( )”

    参考: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`

    参考:https://stackoverflow.com/questions/2005192/how-to-execute-a-bash-command-stored-as-a-string-with-quotes-and-asterisk

    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字节换行,如果我们原本的目录就是去掉特殊字符,自动换行会引入
    
    # 我们可使用-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,到orgapachecatalinautilServerInfo.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

  • 相关阅读:
    Python基础教程之第2章 列表和元组
    java最简单的方式实现httpget和httppost请求
    90后女生微信销售案例:预热和成熟
    window.onload与$.ready的差别
    在delphi下TClientSocket的使用技巧 转
    delphi安装 Tclientsocket, Tserversocket控件
    DELPHI SOKET 编程(使用TServerSocket和TClientSocket) 转
    Delphi ServerSocket,ClientSocket示例
    Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件
    delphi TServerSocket阻塞线程单元 实例
  • 原文地址:https://www.cnblogs.com/lsdb/p/10213076.html
Copyright © 2020-2023  润新知