Shell
- shell是一个命令行解释器,它接收应用程序或命令,然后调用操作系统内核
- shell还是一个功能强大的编程语言,易于编写调试,灵活性强
cat /etc/shells
ls -la /bin |grep bash
echo $SHELL
shell入门
#!/bin/bash
# shell脚本以此开头,指定解析器
echo "Hello World!"
sh helloworld.sh # 执行shell脚本
chmod u+x helloworld.sh
./helloworld.sh # 自己调自己
shell中的变量
常用系统变量
- $HOME: 家目录
- $PWD: 当前目录
- $SHELL: /bin/bash
- $USER: 当前用户名
自定义变量
A=0 # 无需变量类型, 要求没有空格, 变量名建议大写
echo $A
unset A # 撤销变量
readonly B=1 # 定义一个静态变量
unset B # 无法撤销
# export 变量名
export B # 将B提升为全局变量,可供其他shell程序使用
- 无需变量类型
- shell中的变量默认都是字符串类型,无法直接进行数值运算
- 等号左右两侧没有空格
- 变量名建议大写
- 值中如果有空格,需要用双引号或单引号括起来
特殊变量
变量 | 含义 |
---|---|
$n | n为数字,$0 代表该脚本名称,$1 -$9 代表第一到第9个参数,十以上的参数,需要用大括号包含,如${11} |
$# | 获取所有输入参数的个数,常用于循环 |
$* | 代表命令行中的所有参数,把所有的参数当成一个整体 |
$@ | 代表了命令行中的所有参数,把每个参数区分对待 |
$? | 判断上一条命令是否正常执行。如果返回0,则正常执行;非0(具体值由命令自己定),则没有正常执行 |
运算符
$((运算式))
或 $[运算式]
expr + - \* / %
注意要有空格
# (3 + 2) * 4
expr `expr 3 + 2` \* 4
s=$[(3+2)*4]
echo $s
条件判断
[ condition ]
- 注意condition前后有空格
- 注意:条件非空即为true,
[]
返回false
整数间比较运算符:
-lt
, -le
, -eq
, -gt
, -ge
, -ne
注意:=
为字符串比较
$[ 23 -ge 22 ]
$?
# 结果为0.说明正确执行
$[ 23 lt 22 ]
$?
# 结果非0,上一条语句错误
文件权限判断符:
-r
: 有读权限-w
: 有写权限-x
: 有执行权限
$[ -r hello.sh ]
文件类型判断:
-f
: 文件存在,并且是一个常规文件-e
: 文件存在-d
: 文件存在并且是一个目录
$[ -e a.txt ]
逻辑判断:
&&
: 逻辑与||
: 逻辑或
遵循短路逻辑
[ condition1 ] && [ condition2 ] || [ condition3 ]
if语句
if [ condition ];then
code
fi
if [ condition ]
then
code
elif [ condition ]
then
code
else
then
code
fi
case语句
case $变量名 in
"值1")
如果变量值等于值1,则执行程序1
;; # 相当于break
"值2")
如果变量的值等于值2,则执行程序2
;;
*) # 相当于default
如果变量的值都不是以上的值,则执行此程序
;;
esac
for语句
for(( 初始值;循环控制条件;变量变化 ))
do
程序
done
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
s=$[$s+$i]
done
echo $s
for 变量 in 值1 值2 值3 ...
do
程序
done
下面脚本 $*
和$@
没有区别
#!/bin/bash
for i in $*
do
echo "$i"
done
for j in $@
do
echo "$j"
done
下面脚本 $*
和$@
有区别,前者会当成一个整体给i,后者会一个一个给j
#!/bin/bash
for i in "$*"
do
echo "$i"
done
for j in "$@"
do
echo "$j"
done
while语句
while [ condition ]
do
code stub
done
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
s=$[$s+$i]
i=$[$i+1]
done
echo $s
read读取控制台输入
read(选项)(参数)
选项:
- -p: 指定读取值时的提示符
- -t: 指定读取值时等待的时间(秒)
参数: 读取值得变量名
read -t 5 -p "Enter your name in 5 seconds:" NAME
echo $NAME
系统函数
basename
basename [string/path] [suffix]
basename命令会删掉所有的前缀,包括最后一个/
,然后将字符串显示出来
选项 suffix
,如果suffix被指定了,basename会将path或string的suffix也去掉
basename /home/test.txt
# 结果为 test.txt
basename /home/test.txt .txt
# 结果为 test
dirname
dirname 文件绝对路径
从给定的包含绝对路径的文件名中去除文件名,返回剩下的路径部分
自定义函数
[ function ] funcname[()]
{
code stub
[return int;]
}
- 先定义后调用
- 函数返回值,只能通过
$?
系统变量活的 - 可以显示添加return;如果不加return语句,将以最后一条命令运行结果,作为返回值,return后面接树枝n(0~255)
#!/bin/bash
function sum()
{
s=0
s=$[$1+$2]
echo $s
}
read -p "inpute a number" n1
read -p "inpute a number" n2
sum $n1 $n2
cut
cut命令从文件的每一行剪切字节、字符和字段,并将这些字节、字符和字段输出.
cut [选项参数] filename
选项:
-f
: 列号,提取第几列-d
: 分隔符,按照指定分隔符分割列,默认分隔符是制表符
cut -d " " -f 1,4 test.txt
cut text.txt |grep Java|cut -d " " -f 1
echo $PATH |cut -d : -f 3- # 第三列及以后
grep -r "www" /home |cut -d ":" -f 1
# 从ifconfig中切出ip
ifconfig eth0|grep "inet addr"|cut -d : -f 2|cut -d " " -f 1
sed
sed是一种流编辑器。它一次处理一行内容,处理时,把当前行存储在临时缓存区,称为模式空间,接着用sed命令处理缓冲区中的内容,处理完后,把缓冲区的内容送往屏幕,接着处理下一回,知道文件结束。文件内容没有改变,除非使用重定向输出
sed [选项参数] 'command' filename
选项:
-e
: 直接在指令模式上进行sed动作编辑
命令:
a
: 新增,a的后面可以接字符串,在下一行出现d
: 删除s
: 查找并替换
sed "2a Python" test.txt # 在第二行下面添加python
sed "/C/d" test.txt # 删除带C的行
sed "s/C/C++/g" test.txt # 将所有的C都替换为C++,不加g表示只替换第一个
sed -e "2d" -e "s/C/C++/g" test.txt # 删除第二行并替换,需要用到-e
awk
强大的文本分析工具,把文件逐行读入,以空格为默认分隔符将每行进行切片,切片的部分再进行分析处理
awk [options] 'pattern1{action1} pattern2{action2} ...' filename
pattern: 表示awk在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所指向的一系列命令
选项 | 说明 |
---|---|
-F | 指定分隔符 |
-v | 赋值一个用户定义变量 |
内置变量:
FILENAME
: 文件名NR
: 已读的记录数NF
: 浏览记录的域的个数(切割后,列的个数)
awk -F : '/^root/ {print $7}' passwd # 搜素passwd文件中以root开头的,用:分隔的第7列
awk -F : '/^root/ {print $1","$7}' passwd # 打印第1列和第7列,并以,分隔
awk -F : 'BEGIN{print "user,shell"} {print $1","$7} END{print "cm,/bin/shell"}' passwd # 打印第1列和第7列,在前面和后面添加相应内容
awk -F : -v i=1 '{print $3+i}' passwd # 将第三列值加1
awk '/^$/ {print NR}' test.txt # 查找空行行号
cat test.txt | awk -F " " '{sum+=$2}|END {print sum}' # 计算第二列的和
ifconfig eth0|grep "inet addr"|awk -F : '{print $2}'|awk -F " " '{print $1}'
sort
将文件进行排序,并将排序结果标准输出
sort(选项)(参数)
选项 | 参数 |
---|---|
-n | 依照数组大学排序 |
-r | 以相反的顺序排序 |
-t | 设置排序时所用的分隔符 |
-k | 指定需要排序的列 |
sort -t : -nrk 3 passwd
sort -n test.txt|awk '{a+=$0;print $0}|END{print "SUM="a}' # 第一列排序并求和