shell编程

shell基础概念

Shell是一个命令解释器,它为用户提供一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以使用Shell来启动、挂起,停止、编写一些程序

shell是用户和内核中间的一个媒介

  1. 什么是shell编程?
    shell编程就是组织shell语法写入一个文本
    运行文件的是后依次执行命令,文件当中必须存在shell语法
  2. c语言和shell编程的比较
c语言shell编程
语法c语法shell语法
编译gcc编译器不需要编译
文件后缀*.c*.sh
文件位置linux任何环境一般写在家目录
执行./hello./ hello.sh
  1. C语言和shell运行方式

c语言: hello.c
1.编辑工程:VScode等编辑器生成hello.c
2.编译工程:gcc hello.c -o hello,默认有权限执行权
3.测试工程:./ hello

shell编程: hello.sh
1.编辑工程:vi等编辑器 生成hello.sh文件
2.修改文件权限:chmod 777 hello.sh
3.测试工程:./hello.sh

  1. shell编程
    1.shell编程没有头文件,没有主函数,里面所有命令都是bash解析器解析所以在执行所有的命令的时候,在文件的开头加上bash解析器的路径shel1因脚本的第一句必须是:# !/ bin/bash
    # !/ bin/bash的作用:指明解析器的路径
    #!是shell编程的特殊的标识符

在这里插入图片描述
文件名为白色的时候,表示没有没有执行权限,改变执行权限之后可以执行

  • 练习
    练习: shell编程输出以下内容
    cat dog pig
    hello
    welcome
echo -e "cat\tdog\tpig"
echo -e "hello\nwelcome"
  1. echo (输内容到控制台)
    -e:单行输出

  2. 脚本格式

  • 脚本开头:#!/bin/bash

shell中的变量和定义
3. Share脚本命名规则和C语言一样。
数字,字母,下划线,不能以数字开头。

  1. 变量不需要声明数据类型,所有的类型默认字符串类型

  2. shell语法给变量赋值的时候,等号的两边不能出现空格
    a=234,等号两边不能有空格。

  3. 变量的引用需要在变量之前加上$
    a=hello
    echo $a
    就会输出a的值hello

  4. 变量的种类

    1. 用户自定义变量
      a=hello
    2. 命令行变量
      $#和$*类似于C语言中的argc和argv

argc 是 argument count的缩写,表示传入main函数的参数个数;

argv 是 argument vector的缩写,表示传入main函数的参数序列或指针,并且第一个参数argv[0]一定是程序的名称,并且包含了程序所在的完整路径,所以确切的说需要我们输入的main函数的参数个数应该是argc-1个;

. / num.sh 123 456 789
3	# $#返回值,返回参数个数,三个参数
123 456 789	 # $*返回值,返回所有数值
123	# $1返回值,返回第一个数值
456	# $2返回值,返回第二个数值
789	# $3返回值,返回第三个数值

shell参数表示★

  • $# 命令行额外的参数(不包括执行脚本名即./名.sh)
  • $* 命令行额外的内容(不包括执行脚本名即./名.sh)
  • $1 命令行的第1个参数(argv[1])
  • $2 命令行的第2个参数(argv[2])
  • $? 代表最后一行的shell 语句执行结果返回值
  1. 外部传参给内部变量
#!/bin/bash

a=$1  # a等于外部传参,a引用1
echo $a  # 输出a的引用结果
cat $1

在这里插入图片描述

符号的作用

双引号

作用:将某些对象变成字符串输出

  1. 字符串中有空格必须使用双引号,如果没有可以不用加双引号。
    str=hello
    str="hello word "
  2. 当双引号中要对变量引用
    echo "$a world"
  3. 在双引号当中调用shell命令,当shell命名需要识别的时候使用**反引号``**帮我命令。
    echo " `ls -l` "

单引号

作用:将包裹的内容当作字符串使用
echo 'day is `date` ’ Date为命令加反引号

反引号

作用:识别双引号中的命令,并执行该命令

重定向运算符 > >>

> 重定向到某一个文件完成覆盖
>> 重定向到某一个文件完成追加

例题:使用shell将Hello追加到2.TXT文件中,然后将ls -l内容也追加到2.TXT文件中

	touch 2.txt  // 创建2.TXT文件
	echo "hello">2.txt 
	echo "`ls -l`">>2.txt
  	cat 2.txt  // 输出2.TXT文件

字符串处理

计算字符串

	str=jddojsafkjdfkjdfdlkfjkldjfkn
	echo "${#str}"  计算长度为:

通配符

通配符含义
*代表任意长度的任意字符
?代表占一个长度的任意字符
[a-z]代表a到z当中一个长度的任意字符。
[az]代表a或z当中的一个长度的字符串。
[^az]代表指a和z以外的字符串(指定范围之外)
%从右到左(←)尽可能少的匹配
%%从右到左(←)尽可能多的匹配
#从左到右(→)尽可能少的匹配
# #从左到右(→)尽可能多的匹配
  1. str=asgkdfhello,删除字符串str的左边的三个字符asg,其他的保留
    从左到右进行一次查找
str=asgkdfhello
echo "${str#*asg}"
#:代表匹配方式
*:代表匹配内容
#:从左到右尽可能少
*:任意多
从左到右尽可能少删除任意多个字符到asg为止,包含asg

  1. 如果字符串str=asgkdfhello,删除前面的所有,只剩最后的hello
    从左到右进行多次查找
str=asgkdfhello
echo "${str##*f}"

##: 从左到右尽可能多
* :任意多
从左到右尽可能多的删除任意多个字符,到f为止,包含f

删除总结:查找到删除的最近的字符,根据前后来删除

  1. 删除字符串str=asgkdfhello右侧的hello
    从右到左,进行一次寻找
str=asgkdfhello
echo "${str%h*}"

%:右到左
*:任意多
从右到左,到h的位置截止,删除任意多分字符,包含h
  1. 删除字符串str=asgkdfhello右侧的字符,仅保留as
    从右到左,进行多次匹配
str=asgkdfhello
echo "${str%%g*}"

%%:从右到左,进肯能多
*:任意多个字符
从右到左,进肯能多删除任意多个字符,到g为止,包含g

text语句

判断命令

语句含义说明
文件判断
text -e file判断文件file是否 存在是返回0,否返回1
text -r file判断文件file是否可读是返回0,否返回1
text -w file判断文件file是否可写是返回0,否返回1
text -x file判断文件file是否可执行是返回0,否返回1
text -d file判断文件file是否是目录是返回0,否返回1
text -f file判断文件file是否是普通文件是返回0,否返回1
text -s file判断文件file是否非空是返回0,否返回1
字符串判断
test s1 = s2判断字符串s1和s2是否相同相同返回0,否则返回1
test s1 != s2判断字符串s1和s2是否不同不同返回0,否则返回1
test s1 < s2判断字符串s1是否小于s2s1小于s2返回0,否则返回1
test s1 > s2判断字符串s1是否大于s2s1大于s2返回0,否则返回1
test -n s判断字符串s 长度是否为非0s长度为非0返回0,否则返回1
test -z s判断字符串s 长度是否为0s长度为0返回0,否则返回1
数组判断
test n1 -eq n2判断数值n1是否等于n2n1等于n2返回0,否则返回1
test n1 -ne n2判断数值n1是否不等于n2n1不等于n2返回0,否则返回1
test n1 -gt n2判断数值n1是否大于n2n1大于n2返回0,否则返回1
test n1 -ge n2判断数值n1是否大于等于n2n1大于等于n2返回0,否则返回1
test n1 -lt n2判断数值n1是否小于n2n1小于n2返回0,否则返回1
test n1 -le n2判断数值n1是否小于等于n2n1小于等于n2返回0,否则返回1

test测试语句

根据不同态势语句实现不同的操作。

  1. 判断命令行的执行参数是否为两个?如果不是两个就报错。
test $# -ne 2 条件
   if(条件)
      echo "error"
   else
      echo ""

分支控制语句

C语言:
分支: if-else switch-case
控制: while do-while for goto
shell和C语言的分支控制相同
分支:if-else-fi case-esac
控制:while for until

1. if-else-fi 两种情况的判断

if 判断条件(test测试语句)
then
	xxxx
else
	xxxx
fi
  • fi:是结束if语句的标志

    $# 命令行额外的参数(不包括执行脚本名即./名.sh)
    $* 命令行额外的内容(不包括执行脚本名即./名.sh)
    $1 命令行的第1个参数(argv[1])
    $2 命令行的第2个参数(argv[2])
    $? 代表最后一行的shell 语句执行结果返回值

  • 练习:判断参数是否大于2

if test $# -ne 2
then
echo "error"
else
echo "good"
fi

去掉test的等价命令

if[ $# -eq 2 ]  // 注意在[]里面的内容要与[]都保持有一个空格
then
echo "error"
else
echo "good"
fi

2. 三种情况的判断

三种情况框架:

if 判断条件  // if后面都要跟一个then(一个if配一个then)
then
	XXXXX
elif 判断条件
then
	XxXXX
else
	XXXX
fi

注意:

  1. 每一个if语句都要有fi作为结尾(fi是if语句的标志
  2. if判断条件为真,才能执行Lhen后面的语句(一个if配一个then
  3. if 判断条件等价于if判断条件;,后面有没有;都可以

例子:使用命令行传参,传递两个参数if-elif-else-fi
如果numl>num2 , num1>num2
如果numl=num2 , numl=num2
如果numl<num2 , numl<num2

if test $1 < $2
then
	echo "$1 < $2"
elif test $1 >$2
then
	echo "S1 > $2"
else
	echo "$1 = $2"
fi

3. 分支:case

C语言:
switch格式:

switch(变量)
{
	case l: xSxXx;
		break;
	case 2: xSXxx ; 
		break;
	case 3: ×SXXx ; 
		break ;
	default: xXxx;
		break;
}

shell:框架

case 变量 in
xx)
	aaaa;;	//变量如果是xx,那么执行该语句
				// 没有break就加两个;,第二个;就相当于break
yy)
	bbbb ; ;
zz)
	XXX××;;
*)		//其他情况
	XXXx;;
esca  	// 结束标志
case $1 in
12)
	echo "12";;
13)
	echo "13";;
*) 
	echo "456";;
esac

键盘输入

c语言:scanf ( "sd" , &a ) ;
shell:
输入: read

read str        // 获取键盘输入一个字符串保存到变量

read -p "please input a num" s  // -p 参数 打印“”中提示语句并输入一个内容,为s

运算

运算符:+ - * / %

shell:
格式:`expr 变量1 运算符 变量2 开头有一个反双引号


echo "please input a nun"
read str
echo $str
read -p "please input a nun " s
echo $s

sums=`expr Sstr + $secho $sursl

练习:
1.利用shell脚本实现,c语言的模板

./ c.sh 1.c
#include <stdio.h>
int main (int argc, char  **argv)
{
	return 0;)
}

建立一个 .sh文件,在.sh文件里面输入一下代码
这里代码放在了home1.sh文件里

#!/bin/bash
// 往文件里面写,没有文件写不了
// 先判断传进来的参数,
if test $# -ne 1
then
	echo "error"
fi
// 外部传参第一个,自定义一个文件名为filename,然后输入定义这个文件名
filename=$1
// 然后输出要输出的东西,并追加到指定的文件里面
echo "#include <stdio.h>">$filename
echo " ">>$filename
echo "int main (int argc, char * *argv) ">>$filename
echo " { ">>$filename
echo " } ">>$filename
// 直接打开文件名
gedit $filename

改变一下home1.是文件的权限:chmod 777 home1.sh
然后执行

在这里插入图片描述

  1. 利用case和expr read计算,实现计算器的加减乘除

创建一个.sh文件,并在文件里面输入一下代码

#!/bin/bash
echo "input nup1" 
read str1
echo "input type"	// 运算符
read c
echo "input num2"
read str2

case $c in
+)
	echo " $str1 + $str2 ='`expr $str1 + $str2`" ; ;
-)
	echo "$str1 - $str2 = '`expr $str1 - $str2`"; ;
\*)
	echo "$str1 * $str2 = '`expr $str1 \* $str2`" ; ;
/)
	echo $str1 / $str2 ='`expr $str1 / $str2`" ; ;
esac

  1. 写一个脚本实现如下功能
    1.显示当前的系统时问,然后创建一个目录/ tmp/lstest
    2.切换工作路径/ tmp / lstest
    3.创建目录ald b56a otest.4.创建文件 xyx2y 732
    5.列出当前目录下以a,x或者6开头的文件或者日录

创建一个.sh文件,并在文件里面输入一下代码

echo 'date'
sudo mkdir /tmp/lstest
cd /tmp/lstest
sudo mkdir ald b56a 6test
sudo touch xyx2y 732
ls [ ax6]*
ls | grep ^a
ls | grep ^x
ls | grep ^6

sudo 是一种权限管理机制,管理员可以授权于一些普通用户去执行一些 root 执行的操作,而不需要知道 root 的密码。


for循环

c语言:

for(循环变量初始化;判断循环条件;条件累计)
{
	循环体 ;
}

shell框架:

for 循环变量 in 次数
do				// 循环体放在do和done之间
	循环体
done
区间次数表示: `seq 1 5` 次数1到5次

练习1:输出五次
文件为for.sh
seq 1 5:表示产生1到5之间的所有数

#!/bin/bash
for i in 'seq 1 5`
do
	echo "i is si: hello world"
done

在这里插入图片描述
c语言:
int i 整型
shell:
存放整型数据declare -i n=整数

!/bin/bash
declare -i n=1
n=$n+1
echo $n

在这里插入图片描述
练习2:尝试for 将命令行的参数全部打印出来

#!/ bin/ bash

declare -i n=1
for data in $*
do
	echo "argv [$n] : $data"n=$n+1
done

练习3: shell编程实现从1+2+3+…+100

#!/bin/bash
for i in `seq 1 100`
do
sum= ``expr $sum + $i`
done
echo $sum

while循环

c语言:

while(判断条件)   条件为真执行条件为假不执行
{
	循环体
}

shell:

while 判断条件(test测试语句[]do
	循环体
done
  • 循环体放在do和done之间

练习1:在终端上打印1到100的值

#!/ bin/bash
declare -i n=1
while test $n -le 100
do
echo " $n"
n=$n+1
done

练习2:使用shell,while循环实现10 !

#!/bin / bash
declare -i n=1
declare -i s=1
while test $n -le 10
do
	s=$s \ * $n
	n=$n+1
done
echo $s

函数

shell编程中的函数和C语言的函数非常相似,功能内容封装
框架:

函数名()
{
	函数封装内容
}

注意:

  1. shell函数里面不需要写形参和返回值,默认类型是int类型
  2. 在函数内部,$#$*代表函数的内部参数个数(不是命令的参数和参数个数)
  3. 函数内部的参数要和传参一致,否则传不进去
  4. 再调用的时候参数传递,不需要添加括号
    fun (hello,world) ; //错误的
    fun hello world //正确的

信号的捕捉

正则表达式

四、正则表达式
正则表达式RE,实际上特殊符号的组成的一个式子,帮助你模糊查询
grep 寻找对象

  • 语法:
    grep 寻找范围 寻找对象参数
参数作用
-H将你查询的文件名输出
-n打印匹配的行号
-w全字匹配,只有一模一样的才会输出

grep 配套的

在这里插入图片描述

练习:查找以hello为开头的

grep '^hello' 3.txt -Hn

在这里插入图片描述
练习:查找以hello为结尾的
$放在结尾

grep 'hello$' 3.txt -Hn

在这里插入图片描述

例子.查询电话簿
区号是3位或者4位
并且是0开头的
电话号码和区号之前要么是空格要么是-
所有的区号和电话号码都只能数字8位到9位

区号是3位或者4位:[0,9]\{3,4\},\是转义字符
并且是0开头的:^0
电话号码和区号之前要么是空格要么是-:[ -]
所有的区号和电话号码都只能数字8位到9位[0-9]\{8,9\}

grep '^0[0-9]\{3,4\}[ -][0,9]\{8,9\}' phone.txt -Hn

练习:
作业:
1 .shell脚本
使用shell脚本生成一个随机数,提示猜测数字,每次输入都会提示猜大了或者猜小了,直到用户猜对了就退出
$RANDOM

# !/ bin/ bash
declare -i num
declare -i a
num=$( ($RANDOM%100+0))
read -p "input num: " a
while test $num -ne $a
do
if test $num -gt $a
then
	echo "num > a"
elif test $num -lt $a
then
	echo "num < a"
fi
	read -p "input num=" a
done

2.使用ls遍历当前目录下的文件,如果文件存在并可读就打印文件名,如果存在不可读就打印error

#!/ bin/ bash

for str in `ls`
do
if test -e $str & & test -x $str
then
	echo $str
elif test -e $str
then
	echo "error"
fi
done

附加题:
3.读取普通文件,提示用户和密码输入
如果输入的内容和文件中的内容一致,打印登录成功,否则登录失败

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值