bash编程之:字符测试,一般加引号
双目:
> : 大于
< :小于
==:等于,等值比较
=~:左侧是字符串,右侧是一个模式,判断左侧的字符串能否被右侧的模式所匹配:通常只在[[]]中使用
模式中可以使用行首、行尾锚定符,但是模式不要加引号
!=,<>: 不等于
单目:
-n 字符串: 字符串是否不空,不空为真,空则为假
-z 字符串:字符串是否为空,空则为真,不空则假:
#!/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
练习:写一个脚本
mem) show memory info;
quit) quit
Enter your option: cpu cpu,cpu
2、如果用户选择cpu,则显示文件/proc/cpuinfo的信息;
3、如果用户选择mem,则显示文件/proc/meminfo的信息;
5、如果用户键入其它字符,则显示未知选项,请重新执行脚本;退出码为6;
#!/bin/bash
#
returnValue=0
cat << EOF
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 ...
分割窗口打开多个文件: vim -o|O file1 file2 ...
-o 水平分割 先按Ctrl+w再按上下箭头键,可以在各文件间来回切换
-O 垂直分割 先按Ctrl+w再按左右箭头键,可以在各文件间来回切换
光标移动:
行间移动:
1G 第一行
G 最后一行
行内移动:
0 绝对行首
^ 第一个非空白字符
$ 绝对行尾
单词间移动:
w 下个单词的词首
e 当前或下一个词的词尾
b 当前或前一个词的词首
单字符移到:
h 左
l 右
j 下
k 上
句子间移动:
)
(
段落间移动:
}
{
编辑操作:
x 删除光标所在处的字符
#x 删除光标所在处开始向后的#个字符;
r 替换光标所在处的字符
dd 删除一行
#dd 删除光标所在行其后面的行,共#行
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 向文件首部翻半屏
查找:
/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
练习:写一个脚本
mem) show memory info;
quit) quit
Enter your option: cpu cpu,cpu
2、如果用户选择cpu,则显示文件/proc/cpuinfo的信息;
3、如果用户选择mem,则显示文件/proc/meminfo的信息;
5、如果用户键入其它字符,则显示未知选项,请重新执行脚本;退出码为6;
#!/bin/bash
#
returnValue=0
cat << EOF
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 开启语法高亮
:set hlsearch 开启搜索高亮
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 测试是否为字符设备文件
-p file 测试是否为管道文件
双目测试:
file1 -nt file2 测试file1是否为file2更 新一些
写一个脚本,完成如下任务:
1、分别复制/var/log下的文件至/tmp/logs/目录中;
2、复制目录时,才使用cp -r
3、复制文件时,使用cp
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}]
如果同时使用了-v选项:
-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