4、文件测试、字符测试、if、vim 学习笔记
bash编程之:字符测试,一般加引号 双目: > : 大于 < :小于 ==:等于,等值比较 =~:左侧是字符串,右侧是一个模式,判断左侧的字符串能否被右侧的模式所匹配:通常只在[[]]中使用 模式中可以使用行首、行尾锚定符,但是模式不要加引号 !=,<>: 不等于 单目: -n 字符串: 字符串是否不空,不空为真,空则为假 -z 字符串:字符串是否为空,空则为真,不空则假:
判定所有用户是否拥有可登录shell #!/bin/bash for userName in `cut -d: -f1 /etc/passwd`; do if [[ `grep "^$userName&;" /etc/passwd | cut -d: -f7` =~ sh$ ]]; then echo "login user: $userName" else echo "nologin user: $userName" fi done
练习:写一个脚本 1、让用户交互式输入一个用户名,先判定用户是否存在;不存在,则以7为退出码; 2、判断用户的shell是否为/bin/bash;如果是,则显示为“Bash User.”,退出码为0; 否则,则显示为“Not Bash User.”,退出码为1; #!/bin/bash # read -p "Enter a user name: " userName if ! id $userName &> /dev/null; then echo "No such user." exit 7 fi userShell=`grep "^$userName&;" /etc/passwd | cut -d: -f7` if [[ "$userShell" == "/bin/bash" ]]; then echo "bash user." returnValue=0 else echo "Not bash user." returnValue=1 fi exit $returnValue 练习:写一个脚本 1、显示如下菜单: cpu) show cpu info; mem) show memory info; quit) quit Enter your option: CPU Cpu,CpU 2、如果用户选择cpu,则显示文件/proc/cpuinfo的信息; 3、如果用户选择mem,则显示文件/proc/meminfo的信息; 4、如果用户选择quit,则退出,且退出码为5; 5、如果用户键入其它字符,则显示未知选项,请重新执行脚本;退出码为6; #!/bin/bash # returnValue=0 cat << EOF cpu) print cpu infomation mem) print meory infomation quit) Quit EOF read -p "Enter your option: " userOption userOption=`echo $userOption | tr 'A-Z' 'a-z'` if [[ "$userOption" == "cpu" ]]; then cat /proc/cpuinfo elif [[ "$userOption" == "mem" ]]; then cat /proc/meminfo elif [[ "$userOption" == "quit" ]]; then echo "quit" returnValue=6 else echo "unkown option" returnValue=7 fi exit $returnValue vi编辑器 vim: vi improved vi的模式: 编辑模式:键盘操作通常被解析为编辑命令; 输入模式:文本输入; 末行模式:vim的内置的命令行接口,执行vim内置命令 编辑模式-->输入模式 i 在当前光标所在处输入; I 在当前光标所在行的行首输入;
a 在当前光标所在处后面输入; A 在当前光标所在行的行尾输入;
o 在光标所在行的下方新增一个空白行输入; O 在光标所在行的上方新增一个空白行输入; 输入模式-->编辑模式: ESC 编辑模式-->末行模式: : 末行模式-->编辑模式: ESC,ESC vim命令的使用格式: vim [options] file... +[#]: 打开文件后直接让光标处于第#行的行首; vim +8 /etc/fstab 将定位到/etc/fastab第八行的行首 退出 :q! 不保存并退出 :wq 保存并退出 :x 保存并退出 编辑模式:ZZ,保存退出 打开:vim file1 file2 ... :next 跳转到下一个文件 :prev 跳转到上一个文件 :first 跳转到第一个文件 :last 跳转到最后一个文件 :qall 全部文件不保存退出 :wqall 全部文件保存退出 分割窗口打开多个文件: vim -o|O file1 file2 ... -o 水平分割 先按Ctrl+w再按上下箭头键,可以在各文件间来回切换 -O 垂直分割 先按Ctrl+w再按左右箭头键,可以在各文件间来回切换
光标移动: 行间移动: 1G 第一行 G 最后一行 行内移动: 0 绝对行首 ^ 第一个非空白字符 $ 绝对行尾
单词间移动: w 下个单词的词首 e 当前或下一个词的词尾 b 当前或前一个词的词首 单字符移到: h 左 l 右 j 下 k 上
句子间移动: ) (
段落间移动: } {
编辑操作: x 删除光标所在处的字符 #x 删除光标所在处开始向后的#个字符; r 替换光标所在处的字符 d 删除命令,可以结合各光标跳转命令使用 dd 删除一行 #dd 删除光标所在行其后面的行,共#行
c 删除命令,可以结合各光标跳转命令使用 cc 删除光标所在行,并进入输入模式 #cc 删除光标所在行开始的行,总共#行,并进入输入模式
y 复制,可以结合各光标跳转命令使用 yy 复制光标所在行 #yy 复制光标所在行其后面的行,共#行
p 粘贴 复制或删除的是整行 p 粘贴在光标所在行的下方 P 粘贴在光标所在行的上方
复制或删除的为非整行 p 粘贴在光标所在字符的后面 P 粘贴在光标所在字符的前面
u 撤消编辑 Ctrl+r 撤消此前的撤消 . 重复执行此前的命令
末行模式:范围定界 10,19 第10行到第19行 10,+9 第10行开始的后9行 . 表当前行 $ 最后一行 .,$-2 当前行到倒数第三行 % 全部文本 /pat1/,/pat2/ 从光标所在行开始,第一次被pat1匹配和第一次被pat2匹配到之间的所有行 翻屏: Ctrl+f 向文件尾部翻一屏 Ctrl+b 向文件首部翻一屏 Ctrl+d 向文件尾部翻半屏 Ctrl+u 向文件首部翻半屏 Enter 向文件首部上移一行 k 向文件尾部下移一行 查找: /keyword ?keyword n: N: 支持正则表达式 :set nohlsearch 关闭高亮显示,对当前shell有效 练习:写一个脚本 1、让用户交互式输入一个用户名,先判定用户是否存在;不存在,则以7为退出码; 2、判断用户的shell是否为/bin/bash;如果是,则显示为“Bash User.”,退出码为0; 否则,则显示为“Not Bash User.”,退出码为1; #!/bin/bash # read -p "Enter a user name: " userName if ! id $userName &> /dev/null; then echo "No such user." exit 7 fi userShell=`grep "^$userName&;" /etc/passwd | cut -d: -f7` if [[ "$userShell" == "/bin/bash" ]]; then echo "bash user." returnValue=0 else echo "Not bash user." returnValue=1 fi exit $returnValue 练习:写一个脚本 1、显示如下菜单: cpu) show cpu info; mem) show memory info; quit) quit Enter your option: CPU Cpu,CpU 2、如果用户选择cpu,则显示文件/proc/cpuinfo的信息; 3、如果用户选择mem,则显示文件/proc/meminfo的信息; 4、如果用户选择quit,则退出,且退出码为5; 5、如果用户键入其它字符,则显示未知选项,请重新执行脚本;退出码为6; #!/bin/bash # returnValue=0 cat << EOF cpu) print cpu infomation mem) print meory infomation quit) Quit EOF read -p "Enter your option: " userOption userOption=`echo $userOption | tr 'A-Z' 'a-z'` if [[ "$userOption" == "cpu" ]]; then cat /proc/cpuinfo elif [[ "$userOption" == "mem" ]]; then cat /proc/meminfo elif [[ "$userOption" == "quit" ]]; then echo "quit" returnValue=6 else echo "unkown option" returnValue=7 fi exit $returnValue vim可视化模式: v 按光标走过的区域选择 V 选择矩形块,按光标走过的行选择
分割当前窗口: Ctrl+w,s 水平分割当前窗口 Ctrl+w,v 垂直分割当前串口 窗口属性的定义: :set nu 显示行号 :set nonu 取消显示行号 :set ai 设置自动缩进 :set noai 取消自动缩进 :set ic 忽略大小写 :set noic 区分大小写 :set sm 显示对应的括号 :set nosm 不显示对应的括号 :syntax on 开启语法高亮 :syntax off 关闭语法高亮 :set hlsearch 开启搜索高亮 :set nohlsearch 关闭搜索高亮
vim的配置文件: 全局:/etc/vimrc 个人:~/.vimrc 查找替换: :地址定界s/查找模式/替换为的内容/gi g: global 全局替换 i: ignore-case 忽略大小写 :地址定界s@查找模式@替换为的内容@gi &: 用于在替换为的内容部分中引用前面匹配到的所有内容; 练习: 1、复制/etc/grub.conf至/tmp目录,删除/tmp/grub.conf文件中行首的空白符; %s@^[[:space:]]{1,}@@g 2、复制/etc/rc.d/rc.sysinit至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的行,行首加#号 :%s@^[[:space:]]{1,}.*@#&@ 3、删除/tmp/rc.sysinit文件中以#开头且后面跟了至少一个空白字符的行的行首的#号和空白符; :%s@^#[[:space:]]{1,}@@g 4、为/tmp/grub.conf文件中前三行的行首加#号; 1,3s@^@#@g 5、将/etc/yum.repos.d/CentOS-Media.repo中enable=0一行最后的0改为1; %s@(enabled=)[0-9]@11@g bash知识点:文件测试 单目测试: -e file 测试文件是否存在 -s file 测试文件是否存在并且不空 -f file 测试是否为普通文件 -d file 测试是否为目录文件 -b file 测试是否为块设备文件 -c file 测试是否为字符设备文件 -h|-L file 测试是否为符号链接文件 -p file 测试是否为管道文件 -S file 测试是否为套接字文件 -r file 测试其有效用户是否对此文件有读权限 -w file 测试其有效用户是否对此文件有写权限 -x file 测试其有效用户是否对此文件有执行权限 双目测试: file1 -nt file2 测试file1是否为file2更 新一些 写一个脚本,完成如下任务: 1、分别复制/var/log下的文件至/tmp/logs/目录中; 2、复制目录时,才使用cp -r 3、复制文件时,使用cp 4、复制链接文件,使用cp -d 5、余下的类型,使用cp -a #!/bin/bash # targetDir='/tmp/logs' [ -e $targetDir ] || mkdir $targetDir for fileName in /var/log/*; do if [ -d $fileName ]; then copyCommand='cp -r' elif [ -f $fileName ]; then copyCommand='cp' elif [ -h $fileName ]; then copyCommand='cp -d' else copyCommand='cp -a' fi $copyCommand $fileName $targetDir done 写一个脚本,完成如下任务,其使用形式如下所示: script.sh {start|stop|restart|status} 其中: 如果参数为空,则显示帮助信息,并退出脚本; 如果参数为start,则创建空文件/var/lock/subsys/script,并显示“starting script successfully.” 如果参数为stop,则删除文件/var/lock/subsys/script,并显示“Stop script successfully.” 如果参数为restart,则删除文件/var/locksubsys/script并重新创建,而后显示“Restarting script successfully.” 如果参数为status,那么: 如果文件/var/lock/subsys/script存在,则显示“Script is running...”,否则,则显示“Script is stopped.” bash的知识点:位置参数轮替(shift) #!/bin/bash # declare -i sum=0 for i in `seq 1 $#`; do let sum+=$1 shift done echo $sum 写一个脚本:使用形式如下 userinfo.sh -u username [-v {1|2}] -u选项用于指定用户;而后脚本显示用户的UID和GID; 如果同时使用了-v选项: -v后面的值如果是1,则额外显示用户的家目录路径; -v后面的值如果是2,则额外显示用户的家目录路径和shell; #!/bin/bash # [ $# -lt 2 ] && echo "Too less argements,quit" && exit 3 if [[ "$1" == "-u" ]];then userName="$2" shift 2 fi if [ $# -ge 2 ] && [ "$1" == "-v" ]; then verFlag=$2 fi verFlag=${verFlag:-0} if [ -n $verFlag ];then if ! [[ $verFlag =~ [012] ]];then echo "Wrong parameter." echo "Usage: `basename $0` -u UserName -v {1|2}" exit 4 fi fi # echo $userName $verFlag if [ $verFlag -eq 1 ]; then grep "^$userName" /etc/passwd | cut -d: -f1,3,4,6 elif [ $verFlag -eq 2 ];then grep "^$userName" /etc/passwd | cut -d: -f1,6,7 else grep "^$userName" /etc/passwd | cut -d: -f1,4 fi (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |