什么是shell
有没有想过你在linux上输入的命令回车之后为何能被执行?
回车之后,你的命令其实会被shell去解释这条命令,所以核心是shell
shell 是一个用 C 语言编写的软件(也称之为脚本解释器),它是用户使用 Linux 的桥梁。
shell脚本,是一种为 shell软件 编写的脚本。
学习好shell脚本,才能更好的使用linux。
shell 环境
跟 js、php 编程一样,只要有一个能解释执行shell脚本解释器就可以了。linux 的 shell解释器种类众多,常见的有:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
zsh
……
由于易用和免费,bash(也就是 Bourne Again Shell) 在日常工作中被广泛使用,也是大多数linux 系统默认的 shell。
查看你的linux系统自带哪些shell
查看当前使用的shell类型
指定shell
#! 用来指定用何解释 来此脚本文件的 Shell程序,如指定使用Bash
运行 Shell 脚本
运行 Shell 脚本有两种方法,分别如下:
方式1:作为可执行程序, 将代码保存到test.sh
方式2:运行解释器+参数(shell 脚本的文件名)
/bin/sh test.sh # 同理推导出php可以这样执行/bin/php test.php
变量
定义和使用变量
my_name="张三" # 定义变量
echo $my_name # 使用一个定义过的变量,只要在变量名前面加美元符号即可
echo 请叫我 ${my_name}GG # 变量名外面的花括号是可选的,是为了帮助解释器识别变量的边界
删除变量
只读变量
只读变量不能修改,也不能删除
readonly my_age=18 # readonly来标识这是一个只读变量
my_age=20 # 修改变量,此处会报错
unset my_age # 删除变量,此处会报错
变量类型
运行shell时,会同时存在三种变量:
- 局部变量 在脚本或命令中定义,仅在当前shell实例中有效,其它shell启动的程序不能访问局部变量。
- 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量。
- shell变量 由shell程序设置的特殊变量。
数据类型
shell是弱类型的编程语言,即便如此,我们也要了解一下它有哪些数据类型
字符串
如何定义
字符串是shell编程中最常用最有用的数据类型,可以用单引号,也可以用双引号,也可以不用引号。
one=hello
two='hello'
three="hello"
echo one,two,three # 打印输出 hello,hello,hello
拼接
单引号里无法使用转义字符,而双引号里可以有。
my_name="张三"
# 单引号里的任何字符都会原样输出,单引号字符串中的$变量是无效的,而双引号里可以。
name_1='hello, ${my_name}'
name_2="hello, ${my_name}"
echo $name_1 $name_2
# 单双引号都可以再嵌套一层表示变量。
name_3="hello, "$my_name""
name_4='hello, '$my_name''# 刚好解决了单引号不能使用$引入变量的问题
echo $name_3 $name_4
# 单引号里不能使用转义字符,双引可以
echo "Hello, I know you are \"$my_name\"!" # √
echo 'Hello, I know you are \'$my_name\'!' # ×
长度、提取和查找
my_name="abcde"
echo ${#my_name} # 获取字符串长度,输出 5
echo ${my_name:1:3} # 提取子字符串,从第2位截取3个字符,输出 bcd
echo `expr index "$my_name" b` # 查找子字符串,b出现在第2位置上,所以输出输出 2
数组
bash仅支持一维数组,不限制数组的大小,下标由 0 开始编号。获取数组中的元素要利用下标。
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。
my_arr=(茄子 土豆 西红柿 辣椒 豆角) # 定义数组
echo ${my_arr[1]} # 获取第2个元素,打印:土豆
echo ${my_arr[*]} # 使用@ 或 * 可以获取数组中的所有元素,打印:茄子 土豆 西红柿 辣椒 豆角
echo ${#my_arr[*]} # 数组元素个数,打印:5
运算符
Shell 和其他编程语言一样,支持多种运算符。
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
算数运算符(用于数字)
加减乘除和取余(+、-、*、/、%)。
echo "两数之和为 : `expr 2 + 2`"
关系运算符 (用于数字)
关系运算符用于数字(或者字符串类型的数字)比较
a=10
b=20
if [ $a -eq $b ]
then
echo "a 等于 b"
else
echo "a 不等于 b"
fi
字符串运算符(用于字符串)
逻辑运算符
- &&: 逻辑的 AND,并且的意思, 如 条件1 && 条件2
- ||:逻辑的 OR,或者的意思,如 条件1 && 条件2
a=10
b=20
# 如果a等于10 并且 b等于30则输出哈哈哈
if [[ $a -eq 10 && $b -eq 30 ]]
then
echo "哈哈哈"
else
echo "嘿嘿嘿"
fi
还有个布尔运算符跟这个很相似,为避免混淆,先不学
赋值和通用关系运算符
1、赋值运算符
=。用于字符串和数字 ,比如
a='hello'
b=123
c=$a # 将a的值赋给c
d=$b # 将b的值赋给d
2、通用的关系运算符
== 或!=。用于字符串和数字,很多书本把他列为术运算符运算符,提示只支持数字比较,其实不然,现在的shell已经可以用于用这个运算符来比较字符串和数字了,比如
echo `expr 10 == 9` # 打印0,即不相等
echo `expr ""张三 == "李四"` # 打印0,即不相等
文件测试运算符
文件测试运算符,以下列出3个,点击这里查看更多
如判断文件是否存在,例子如下:
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
echo
echo 指令,用于字符串的输出。
将内容输出到文件
上面这个命令执行command1然后将输出的内容存入file1。如果要将新内容添加在文件末尾,请使用>>操作符。
流程控制
if 判断
if语句用来判定所给定的条件是否满足,根据判定的结果真或假 决定后续执行。
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
for 循环
for str in 你 好 啊
do
echo $str
done
输出结果:
while 循环
如下,当age大于18的时候,循环就会终止
age=1
while(( $age<18 ))
do
echo "你${age}岁,还未成年"
let "age++"
done
until 循环与 while 循环在处理方式上刚好相反,这里就不在介绍
case ... esac
与其他语言中的 switch ... case 语句类似,是一种多分支选择结构
site="google"
case "$site" in
"baidu") echo "百度搜索"
;;
"google") echo "Google 搜索"
;;
"taobao") echo "淘宝网"
;;
esac
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环。
Shell使用两个命令来实现该功能:break和continue。
break命令允许跳出所有循环,终止执行后面的所有循环 而continue仅仅会跳出当前循环。
函数
sayHi(){ # 定义函数
echo "嗨,我被执行了!"
}
echo "-----函数开始执行-----"
sayHi # 执行函数
echo "-----函数执行完毕-----"
输出类似下面:
-----函数开始执行-----
嗨,我被执行了!
-----函数执行完毕-----
另外函数还可以传入参数
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "参数个数 $# 个!"
echo "输出所有参数 $* !"
}
funWithParam 1 2
输出类似下面:
第一个参数为 1 !
第二个参数为 2 !
参数个数 2 个!
输出所有参数 1 2 !
输入/输出重定向
重定向一般通过在命令间插入特定的符号来实现,如>、>>
输出重定向
下面这个命令执行command1然后将输出的内容存入file。
举个具体的例子
who > file1 # 将who执行的结果写入到file1
echo "菜鸟教程:www.runoob.com" > file2 # 将echo执行的结果写入到file2
输入重定向
本来从键盘获取输入的命令会转移到文件读取内容。
举个具体的例子, 统计 users 文件的行数:
wc -l < users # 将user的输出作为参数 传给wc -l命令
# wc统计文件里面有多少单词
# -l :仅列出行;
# -w :仅列出多少字(英文单字);
# -m :多少字符;