Shell
就是一个命令行的解释器,接收用户命令,调用系统内核
查看所有支持的 shell
:
cat /etc/shells
Ubuntu默认的shell解释器是 dash
,centos默认的shell解释器是 bash
查看当前shell解释器:
echo $SEHLL
格式
第一行以:
#!/bin/bash
开头,代表指定解释器为bash
hello world
#!/bin/bash
echo "hello world"
执行方式
无需执行权限
source 文件.sh
sh 文件.sh
bash 文件.sh
需要权限
./文件.sh
区别: sh
、 bash
都会开启一个子shell,而 source
将会直接在当前shell中执行,有时候更改了系统环境变量不会立即生效,而需要使用source继续更新一下
在子shell中设置的环境变量父shell是不可见
如果想要在一行中执行多个命令,可以用 ;
进行隔开:
➜ shell echo "aaaa" echo "bbbb"
aaaa echo bbbb
➜ shell echo "aaaa";echo "bbbb"
aaaa
bbbb
变量
定义的局部、全局变量 set
分为全局变量和局部变量
- 全局变量:父子shell都可见的变量
- 局部变量:只对当前shell有效的变量
- 默认情况下所有的变量都是字符串类型
系统与定义的环境变量都是以 $
开头的
查看所有全局环境变量 env
变量名=值,等号前后不能够有空格,如果值中有空格,需要加引号,单双引号都可以
unset
取消变量
➜ shell a=222
➜ shell echo $a
222
➜ shell unset a
➜ shell a="hello world"
➜ shell echo $a
hello world
可以将其设置为一个全局变量,全局变量在子shell中也可以访问到,但其他shell中访问不到,需要先有局部变量才能定义全局变量,以下方式可以定义全局变量j
export 局部变量名
子shell修改了全局变量后,不影响父shell,在父shell中更改了会影响子shell,就近原则
有以下脚本 hello.sh
➜ shell cat hello.sh
#!/bin/bash
echo $a
echo $a
echo $a
echo $b
执行方式:
➜ shell a="hello world....."
➜ shell export a
➜ shell b="hello shell"
➜ shell source hello.sh
hello world.....
hello world.....
hello world.....
hello shell
➜ shell ./hello.sh
hello world.....
hello world.....
hello world.....
➜ shell bash hello.sh
hello world.....
hello world.....
hello world.....
➜ shell sh hello.sh
hello world.....
hello world.....
hello world.....
数学运算:
➜ shell echo $((1+5))
6
➜ shell echo $[1+5]
6
常量(只读变量)
定义方式,只读变量也不能撤销
readonly 变量=值
如果再尝试赋值,将会报错:
➜ shell b=565656
zsh: read-only variable: b
➜ shell unset b
zsh: read-only variable: b
特殊变量
$n(功能描述:n 为数字,$0 代表该脚本名称,$1-{10})
使用echo输出内容时,单引号中会将 $内容
当成字符串处理,而双引号会将 $内容
当成变量处理
$#获取所有的参数个数
*把所有的参数看成一个整体)
@把每个参数区分对待)
#!/bin/bash
echo "你好,文件名为:${0},参数个数为${#}"
echo "参数1为:${1}"
echo "参数2为:${2}"
echo "所有的参数信息为:${*}"
echo "所有的参数信息数组为:${@}"
echo "返回值:$?"
运算
需要使用 expr
例如
expr 1 + 2
运算符两侧需要有空格,加减除正常运算即可,乘号需要转义: expr 2 \* 3
echo "$1 + $2 = $(($1+$2))"
#!/bin/bash
a=$(($1*$2))
echo "$1 + $2 = $a"
条件
0代表true,1代表false
基本语法
(1)test condition
(2)[ condition ](注意 condition 前后要有空格)
注意:条件非空即为 true
2)常用判断条件
(1)两个整数之间比较
-eq 等于(equal)-ne 不等于(not equal)
-lt 小于(less than)-le 小于等于(less equal)
-gt 大于(greater than)-ge 大于等于(greater equal)
注:如果是字符串之间的比较 ,用等号“=”判断相等;用“!=”判断不等。
(2)按照文件权限进行判断
-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)
(3)按照文件类型进行判断
-e 文件存在(existence)
-f 文件存在并且是一个常规的文件(file)
-d 文件存在并且是一个目录(directory)
➜ shell test 0 = 0
➜ shell echo $?
0
➜ shell test 0 = 1
➜ shell echo $?
1
➜ shell [ 0 = 0 ]
➜ shell echo $?
0
➜ shell [ 0 = 1 ]
➜ shell echo $?
1
➜ shell [ $a -eq 1000000 ]
➜ shell echo $?
0
➜ shell [ $a -eq 0 ]
➜ shell echo $?
➜ shell [ $a -eq 0 ]
➜ shell echo $?
1
➜ shell [ a != 10 ]
➜ shell echo $?
0
➜ shell [ 2 -le 2 ]
➜ shell echo $?
0
➜ shell [ 2 -ge 2 ]
➜ shell echo $?
0
➜ shell [ 2 -lt 5 ]
➜ shell echo $?
0
➜ shell [ 2 -gt 1 ]
➜ shell echo $?
0
判断权限
➜ shell touch b.sh
➜ shell ll
总计 4.0K
-rw-rw-r-- 1 songxiaoxu songxiaoxu 0 5月 6 22:20 b.sh
-rwxr--r-- 1 songxiaoxu songxiaoxu 44 5月 6 21:58 hello.sh
➜ shell [ -r b.sh ]
➜ shell echo $?
0
➜ shell [ -x b.sh ]
➜ shell echo $?
1
➜ shell [ -w b.sh ]
➜ shell echo $?
判断类型
➜ shell [ -e b.sh ]
➜ shell echo $?
0
➜ shell [ -e c.sh ]
➜ shell echo $?
1
➜ shell [ -f b.sh ]
➜ shell echo $?
0
➜ shell mkdir abc
➜ shell ls
abc b.sh hello.sh
➜ shell [ -f abc ]
➜ shell echo $?
1
➜ shell [ -d abc ]
➜ shell echo $?
0
➜ shell [ -d b.sh ]
➜ shell echo $?
1
多条件
&& 前一条成功,后一条才执行
|| 前一条失败,后一条才执行
➜ shell [ 1 = 1 ] && [ 2 = 2 ]
➜ shell echo $?
0
➜ shell [ 1 = 1 ] && [ 2 = 3 ]
➜ shell echo $?
1
➜ shell [ 1 = 1 ] || [ 2 = 3 ]
➜ shell echo $?
0
➜ shell [ 2 = 5 ] || [ 6 = 7 ]
➜ shell echo $?
1
➜ shell [ 2 = 2 ] && echo 第一个条件成立
第一个条件成立
➜ shell [ 2 = 22 ] && echo 第一个条件成立
➜ shell [ 2 = 2 ] && echo 第一个条件成立 && [ 3 = 3 ] && echo 第二
个条件成立
第一个条件成立
第二个条件成立
➜ shell [ 2 = 2 ] && echo 第一个条件成立 || [ 3 = 3 ] && echo 第二个条件成立
第一个条件成立
第二个条件成立
➜ shell [ 2 = 2 ] && echo 第一个条件成立 || [ 3 -ne 3 ] && echo 第二个条件成立
第一个条件成立
第二个条件成立
➜ shell [ 2 = 3 ] || echo 第一条失败
第一条失败
➜ shell [ 2 != 3 ] || echo 第一条失败
➜ shell [ 2 != 3 ] || echo 第一条失败
➜ shell echo $?
0
➜ shell echo $?
0
➜ shell a=100
➜ shell [ $a = 100 ] && echo $a=100 || echo $a!=100
100=100
➜ shell [ $a = 200 ] && echo $a=100 || echo $a!=200
100!=200
流程控制
单分支
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
①[ 条件判断式 ],中括号和条件判断式之间必须有空格
②if 后要有空格
可能出现传入的值为空的情况,如果值为空将会报错,这时候需要:
if [ "$1"x = "5"x ]
then
echo "$1 == 5"
else
echo "$1 != 5"
fi
多个条件可以合并到一块:
-a
and-o
or
if [ $1 = 5 ] || [ $1 = 10 ]
then
echo "$1 为5或者10"
else
echo "$1 不为5或者10"
fi
可以表示为
if [ $1 = 5 -o $1 = 10 ]
then
echo "$1 为5或者10"
else
echo "$1 不为5或者10"
fi
if [ $1 -gt 5 -a $1 -lt 10 ]
then
echo "$1 大于5或者小于10"
else
echo "$1"
fi
switch
语法
case 变量名 in
case $变量名 in
"值 1")
如果变量的值等于值 1,则执行程序 1
;;
"值 2")
如果变量的值等于值 2,则执行程序 2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
(1)case 行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
(2)双分号“;;”表示命令序列结束,相当于 java 中的 break。
(3)最后的“*)”表示默认模式,相当于 java 中的 default。
for循环
格式
for ((初值;条件;表达式))
do
语句
done
求和
sum=0;
for ((i=0;i<101;i++))
do
sum=$((sum+i))
done
echo $sum
sum=0
for ((i = 0; i < 101; i++)); do
sum=$((sum + i))
done
echo $sum
for in格式
for 变量 in 值1 值2 值3; do
语句
done
for 变量 in 值1 值2 值3
do
语句
done
例如打印所有的参数
#!/bin/bash
for i in "$@"; do
echo "参数:$i"
done
for i in aa bb cc dd ee
do
echo $i
done
可以通过 {开始..结束}
来生成字符序列
➜ shell echo {1..100}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
求和
#!/bin/bash
sum=0
for i in {1..100}; do
sum=$(($sum+$i))
done
echo $sum
while循环
格式
while [ 条件 ]; do
语句
done
while [ 条件 ]
do
语句
done
求和
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]; do
sum=$(($sum + $i))
i=$(($i + 1))
done
echo $sum
可以用let实现其他编程语言的写法,运算符左右依旧不能有空格
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]; do
let sum+=i
let i++
done
echo $sum
读取控制台
格式
read 选项 参数
例如:
#!/bin/bash
read -p "输入内容:" content
echo "你输入的内容为:$content"
例如5秒内读取内容
read -t 5 -p "输入内容:" content
echo "你输入的内容为:$content"
函数
linux系统中也提供了一些函数
例如 basename
函数,可以获取一个路径中的文件名,例如:
➜ shell basename /home/songxiaoxu/program/shell.txt
shell.txt
➜ shell basename /home/songxiaoxu/program/shell.txt .txt
shell
dirname
函数,可以获取路径
➜ shell dirname /home/songxiaoxu/program/shell.txt
/home/songxiaoxu/program
格式:
# 完整格式
[ function ] funname[()]
{
Action;
[return int;]
}
# 省略格式
函数名() {
}
- 调用之前先声明
- 返回值可以通过
$?
获取,可以不写return,不写相当于最后一条命令结果,值只能是0-255
例如求和:
#!/bin/bash
sum() {
s=$(($1+$2))
echo "和为$s"
}
read -p "请输入第一个整数:" a
read -p "请输入第二个整数:" b
sum $a $b
返回的值不能过大,过大将会溢出,可以使用 echo
模拟返回的效果
#!/bin/bash
sum() {
s=$(($1+$2))
echo $s
}
read -p "请输入第一个整数:" a
read -p "请输入第二个整数:" b
result=$(sum $a $b)
echo "两数之和为:$result"
exit
代表退出,后边跟着一个返回值,依旧是0-255:
#!/bin/bash
sum() {
s=$(($1+$2))
echo $s
}
if [ $# -ne 2 ]
then
echo "需要两个参数,已提供:$#个"
exit 1
fi
result=$(sum $1 $2)
echo "两数之和为:$result"
cut
可以用来分割字符,可以用在文件和管道
cat /etc/passwd | cut -d "单个分隔符" -f 第几列
例如
➜ shell cat cut.txt
小红:女
小航:男
小那:女
小工:男
小路:女
小明:男
➜ shell cut -d ':' -f 1 cut.txt
小红
小航
小那
小工
小路
小明
➜ shell
➜ shell cat cut.txt | cut -d ':' -f 1
小红
小航
小那
小工
小路
小明
Q.E.D.