shell编程就是对一堆Linux命令的逻辑化处理!
基于Shell语言的语法规则编写而成,支持Linux/UNIX下的命令的调用。
Shell语言是一种解释型语言
不需要经过编译、汇编等过程。
Shell脚本扩展名为 “*.sh”。
本身是一个文本文件
Bash是Ubuntu下默认的Shell解释程序。
进入Linux根目录,使用touch hello.sh
创建一个名为hello.sh的shell脚本
使用vi
命令打开该文件,输入如下代码并保存退出:
#!/bin/bash
#第一个shell小程序
echo hello world!
第一行比较特殊,#! 后面跟的是解释器的路径(shell本身就是一种解释型语言),解释器的路径是/bin/bash。一般都会以#!开始来指定使用的shell类型,除了bash shell以外,还有很多版本的shell, 例如zsh、dash等等…不过bash shell还是我们使用最多的。
第二行以#符号开始,表示本行是注释。
第三行中的echo是linux中的输出命令,该行的意思就是输出hello world!
方法1:为Shell脚本添加可执行权限
使用chmod命令赋予该脚本可执行的权限,然后再执行:
john@yu:~/shell$ chmod +x test01.sh #给脚本添加运行权限
john@yu:~/shell$ ./test01.sh #运行脚本文件,注意./不能省略
john@yu:~/shell$ /home/yu/shell/test01.sh #通过绝对路径的方式运行脚本文件
方法2:直接使用bash或sh来执行Shell脚本。
john@yu:~/shell$ bash test01.sh #使用Bash运行shell脚本
john@yu:~/shell$ sh test01.sh #使用sh运行Shell脚本
方法3:使用source 命令执行Shell脚本。
john@yu:~/shell$ source test01.sh #使用source运行shell脚本
john@yu:~/shell$ . test01.sh #使用点号.运行shell脚本
变量名=变量值
注意,等号两边不能有空格。
VariableName=VariableValue
VariableName='VariableValue'
VariableName="VariableValue"
如果VariableValue不包含任何空白符(例如空格、Tab缩进等),那么可以不使用引号;
如果 VariableValue包含了空白符,那么就必须使用引号包围起来。
要获取一个变量的值,只需在变量名前面加一个 $。
已定义的变量,可以被重新赋值。
注意,对变量重新赋值时,不能在变量名前加$。
单引号:即使单引号里面有变量和命令也会把它们原样输出。
双引号:先解析里面的变量和命令。
反引号:反引号(``)位于 Esc 键的下方。反引号主要用于命令替换。
第一种方式是把命令用反引号
第二种方式把命令用 $() 包围起来。(并不是每一种Shell解释器都支持)
shell编程中有两种变量,一种是我们自己定义的变量(自定义变量),第二种是Linux已定义的环境变量(如 PATH,HOME等等……)这类变量我们可以直接使用。
#!/bin/bash
#使用环境变量
echo $PATH
#自定义变量hello
hello="hello world"
echo $hello
定义变量的时候,“=”左右不能有空格。
printf输出
换行需要自己加“\n”
read [参数] [变量名]
read -s -p “Enter Password:” password
echo -e “\nThe password your input is:$password”
bash本身并不支持数学运算。
通过expr命令
操作数(用于计算的数)和运算符之间一定要有空格
val=`expr 100 / 2`
val=`expr 100/2` #此时输出的并不是运算结果。
echo $[100/2] #不要求有空格
test命令
test 逻辑表达式
左方括号
[ 逻辑表达式 ] # 逻辑表达式两边必须有空格
Condition中需要包含的逻辑表达式指定运算命令。实践中,一般可以使用 “(())”或者“[]” 来计算逻辑表达式的值。
while 语句
until 语句
return与其他语言中的用法不一样,详见“9.5.3函数的返回值”
其一,不传递参数:
函数名
其二,传递参数。函数名字后接参数列表,参数之间以空格分隔。
函数名 参数1 参数2 …… 参数n
$1 表示第一个参数,
$2 表示第二个参数
$#获取传递的参数的个数;
通过 @ 或 者 @或者 @或者*一次性获取所有的参数。
其一,直接从函数内部输出数据。
例如,前两节的例子中,我们都是使用echo命令直接从函数内部输出结果。
其二,使用全局变量。
首先定义全局变量,在函数中将计算结果赋给全局变量,然后脚本中其他位置,通过访问全局变量,可以获得相应的计算结果。Shell函数中定义的变量默认是全局变量,函数与其所在脚本共享该全局变量。可使用local关键词定义局部变量。
其三,使用内置变量。
通过 ? 这 一 个 特 殊 的 内 置 变 量 , 可 用 于 获 取 上 一 个 命 令 执 行 后 的 返 回 结 果 。 因 而 在 函 数 调 用 后 , 可 以 使 用 ?这一个特殊的内置变量,可用于获取上一个命令执行后的返回结果。因而在函数调用后,可以使用 ?这一个特殊的内置变量,可用于获取上一个命令执行后的返回结果。因而在函数调用后,可以使用?来接收函数函数返回结果。
1.新建组class1,然后添加属于该组的30个用户,用户形式为stu01~30
#!/bin/sh
i=1
sudo groupadd class1
while [ $i -le 30 ]
do
if [ $i -le 9 ];then
USERNAME=stu0$i
else
USERNAME=stu$i
fi
sudo useradd $USERNAME
sudo gpasswd -a $USERNAME class1
i=$(($i+1))
done
2.输入10个数,计算最大值
#!/bin/sh
max=0
count=1
while [ $count -le 10 ]
do
echo -n "Enter number $count:"
read value
if [ $max -lt $value ]
then
max=$value
fi
count=$(($count+1))
done
echo "max = $max"
3.判断是否为回文字符串
#!/bin/bash
echo "Enter string"
read str
len=`echo $str | wc -c`
len=`expr $len - 1`
l=`expr $len / 2`
ctr=1
flag=0
while test $ctr -le $l
do
a=`echo $str | cut -c$ctr`
b=`echo $str | cut -c$len`
if test $a -ne $b
then flag=1
break
fi
ctr=`expr $ctr + 1`
len=`expr $len - 1`
done
if test $flag -eq 0
then echo "String is palindrome"
else echo "String not a palindrome"
fi
4.计算n!
#!/bin/sh
read n
result=$n
while [ $n -ne 1 ]
do
n=$(($n-1))
result=$(($result * n))
done
echo "result = $result"
5.批量删除用户组
#!/bin/bash
i=1
while [ $i -le 50 ]
do
USERNAME=std$i
sudo userdel $USERNAME
i=$(($i+1))
done
echo "remove sucessfully!"
6.九九乘法表
#!/bin/sh
for i in 1 2 3 4 5 6 7 8 9
do
for j in 1 2 3 4 5 6 7 8 9
do
if test $j -le $i
then
echo -ne `expr $i \* $j` "\t"
else
echo ""
break
fi
done
done