shell编程

本文介绍了shell编程的基本概念,包括编写shell脚本的作用(自动化提高效率),shell脚本的执行过程(如bash启动脚本的加载顺序),以及环境变量、PATH、命令连接符、位置变量、命令替换、随机数生成等细节。还涵盖了函数的使用和用户输入处理的示例。
摘要由CSDN通过智能技术生成

shell编程

编写shell脚本有什么作用

  • 自动化 ---->提高效率,减少失误,减少人力
  • 智能化

其他语言写脚本

  • python ---->非常成熟,库非常多,但是速度慢
  • go ----> 不够成熟,但速度快

shell脚本的执行过程(流程)

bash的启动脚本初始化

先运行 etc/profile 再运行 etc/profile.d下的脚本---->目的是:加载一些配置

再运行 ~/.bash_profile

再 ~/.bashrc

再 etc/bashrc

shell在启动的过程中会加载这些配置文件

  • /etc/profile:配置全局环境变量(变量和函数,别名),影响所有用户

  • ~/.bash_profile :配置个人环境变量,影响一个用户

  • /etc/bashrc :配置全局的别名或者函数,影响所有用户

  • ~/.bashrc :配置个人别名或者函数,影响一个用户

影响全局:所有人

​ /etc/profile 、/etc/bashrc

影响局部:个人

~/.bashrc 、~/.bash_profile

shell脚本的4种执行方式

image-20240109172142222

在Linux中,export命令用于设置环境变量,将一个变量导出为环境变量,使得它对当前shell进程中的所有子进程可见。

导出变量为环境变量:

输入 export VARIABLE_NAME 输出一个变量为全局变量,子进程里的也可以使用

例如: export MY_VAR

这个例子将MY_VAR变量导出为环境变量。

还可以这样:

image-20240109172718268

一些细小知识点

$?

$?预定义的变量:操作系统里预先定义好的变量,不需要我们人去自定义

​ 代表上一条命令的返回值

​ 0 表示上一条命令执行成功

​ 非0 表示执行失败

​ 范围:0~255

linux里的命令,基本上使用c语言编写的

[root@gh-shell shell]# vim hello.c
#include <stdio.h>   //导入头函数:别人写好的文件(别人造好的轮子),里边有很多的函数 standard input outpu
int main()
{
        printf("hello,world\n");
        printf("hello,sanchaung\n");
        return 0; 
}
[root@gh-shell shell]# gcc -o hello hello.c // 编译--》按照某种编码进行翻译,将人能熟悉的代码翻译成机器能认识的代码
[root@gh-shell shell]# ls
hello  hello.c
[root@gh-shell shell]# 
[root@gh-shell shell]# ./hello 
hello,world
hello,sanchaung
[root@gh-shell shell]# echo $?
0

玩一下:
[root@gh-shell shell]# cat hello2.c 
#include <stdio.h>
int main()
{
	printf("hello,world\n");
	printf("hello,sanchaung\n");
	return 20;
}
[root@gh-shell shell]# 
[root@gh-shell shell]# gcc -o hello2 hello2.c 
[root@gh-shell shell]# ls
hello  hello2  hello2.c  hello.c
[root@gh-shell shell]# ./hello2
hello,world
hello,sanchaung
[root@gh-shell shell]# echo $?
20

返回值也是有规范的,给开发者的建议

返回值是编写程序的人定义的 按照约定:

0 成功执行
2 选项或者参数有误
127 命令不存在

[root@gh-shell shell]# find / -name “stdio.h”
/usr/include/bits/stdio.h
/usr/include/stdio.h
/usr/include/c++/4.8.2/tr1/stdio.h
[root@gh-shell shell]#

;命令连接符

先执行前面的命令,再执行后面的命令

不管前面的命令执行成功没有,不影响后边命令的执行

[root@gh-shell shell]# echo hello ; mkdir huya ; echo sanchaung
hello
sanchaung
[root@gh-shell shell]# ls
hello  hello2  hello2.c  hello.c  huya
[root@gh-shell shell]# 

PATH变量

要想在其他地方执行 . hello 就得把路径添加到path环境变量里边

[root@gh-shell shell]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@gh-shell shell]# cp hello /usr/local/bin
[root@gh-shell shell]# hello
hello,world
hello,sanchaung
[root@gh-shell shell]# which hello
/usr/local/bin/hello
[root@gh-shell shell]# 

之后我们自己在写完一个文件时候,可以在PATH中加上自己的文件夹
[root@gh-shell shell]# PATH=/shell:$PATH
[root@gh-shell shell]# echo $PATH
/shell:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@gh-shell shell]# 

用户输入一条ip add 发生的故事

image-20240109170407698

还是接上边的hello 如果 直接在其他目录输入 . hello 是会报错的,因为没找到

同样的 这个ip add也是 输入之后 shell解释器会去磁盘里边找ip这个命令 去磁盘中的path变量指定的路径下找

&& 与

命令1 && 命令2 && 命令3
'命令1必须执行成功才会执行命令2,命令2执行成功才会执行命令3'

|| 或

命令1 || 命令2 
'命令1执行不成功才会执行命令2,命令1执行成功,不会执行命令2'

简单的玩一下

[root@gh-shell init.d]# sg="gaohui"
[root@gh-shell init.d]# [ -z $sg ]  '判断字符串的长度是否为0'
[root@gh-shell init.d]# echo $?
1
[root@gh-shell init.d]# [ -n $sg ]  '判断字符串的长度是否不为空'
[root@gh-shell init.d]# echo $?	
0

输出一个字符串的长度

[root@gh-shell ~]# sg="gaohui"
[root@gh-shell ~]# echo ${#sg}   
6
[root@gh-shell ~]# num=${#sg}
[root@gh-shell ~]# echo $num
6

单引号,双引号,反引号

反引号----->命令替换

[root@gh-shell shell]# soft=`which ip`
[root@gh-shell shell]# echo $soft
/usr/sbin/ip
[root@gh-shell shell]# 
[root@gh-shell shell]# rpm -qf `which ip`
iproute-4.11.0-30.el7.x86_64
[root@gh-shell shell]# 

反引号就是优先执行这条命令,将命令的结果赋值给变量

$() 也是命令替换 一样的 更好一点

[root@gh-shell shell]# echo '$sg changsha'
$sg changsha
[root@gh-shell shell]# echo "$sg changsha"
huya changsha
[root@gh-shell shell]# 

双引号可以引用变量的值

单引号是所见即所得

$()的例子:

[root@gh-shell shell]# num=$(rpm -qf $(which ip))
[root@gh-shell shell]# echo $num
iproute-4.11.0-30.el7.x86_64
[root@gh-shell shell]# 

产生随机数

random产生随机数的范围: 0~32767

[root@gh-shell shell]# echo $RANDOM
23994
[root@gh-shell shell]# echo $((RANDOM%10))   #取余 还在是命令替换的范畴  产生余10以内的

[root@gh-shell shell]# echo $((RANDOM%5))   #产生余5以内的

[root@gh-shell shell]# echo $((RANDOM%100)) #产生余100以内的
31

[root@gh-shell shell]# echo $((RANDOM%100 + 100)) #产生100--200的数字
134
[root@gh-shell shell]# 

通过mkpasswd产生:

可以通过man mkpasswd查看可用的选项

[root@gh-shell shell]# mkpasswd
@uePdi68S

通过random产生:

[root@gh-shell shell]# echo $RANDOM|md5sum   #产生随机字符串
bdc57d502f38f19c888f99a6ae8000f0  -
[root@gh-shell shell]# echo $RANDOM|base64   #产生随机字符串
MjE3NDkK

位置变量

image-20240110112607467

[root@gh-shell shell]# cat pos_var.sh 
#!/bin/bash

echo "第一个位置变量是$1"
echo "第二个位置变量是$2"
echo "第二个位置变量是$3"
echo "第二个位置变量是$4"
echo "第二个位置变量是$5"

echo "一个有 $# 个位置变量"
echo "所有的位置变量的内容是 $@"
echo "所有的位置变量的内容是 $*"

echo "脚本的名字是 $0"

[root@gh-shell shell]# 
[root@gh-shell shell]# bash pos_var.sh gaohui gaofei huya xue changai
第一个位置变量是gaohui
第二个位置变量是gaofei
第二个位置变量是huya
第二个位置变量是xue
第二个位置变量是changai
一个有 5 个位置变量
所有的位置变量的内容是 gaohui gaofei huya xue changai
所有的位置变量的内容是 gaohui gaofei huya xue changai
脚本的名字是 pos_var.sh
[root@gh-shell shell]# 

也就是说 像 service network restart 中的restart就是位置变量

历史命令

  • history 默认情况下会记录最近1000条命令
  • history -c 清楚历史命令 —>再清楚 rm -rf ~/.bash_history 就完全清楚了
  • !123可以执行 第123个的那个历史命令
  • !接字符串 标志执行 history中最近以 该字符串开头的命令

查看命令在哪安装的

[root@gh-shell shell]# which ip
/usr/sbin/ip
[root@gh-shell shell]# rpm -qf /usr/sbin/ip
iproute-4.11.0-30.el7.x86_64
[root@gh-shell shell]# 

查找一个命令的安装包

[root@gh-shell shell]# yum provides mkpasswd

函数

其实就是一段代码实现某个功能或者多个功能的代码,可以被其他的函数调用

​ 函数理解为一个“轮子”,可以复用,减少shell编程的代码,提高了效率

local 定义一个局部变量,只是在函数里使用

作用域: 发挥作用的区域

shell脚本里边如果有命令出错了,默认执行下边的语句

'简单的代码'
[root@gh-shell shell]# cat functions 
#!/bin/bash


#定义menu函数
menu(){
	echo "1.查看cpu信息"
	echo "2.查看内存信息"
	echo "3.查看磁盘信息"
	echo "4.退出"
	read -p "请输入你的选择:" option
}

#调用函数 call
#menu

#定义一个采集cpu信息的函数
cpuinfo(){
	top -n 1|grep "Cpu"
	local num=100
	read -p "请输入一个函数的返回值" num1
	if (( $num1 ==1  ));then
		return 1
	else
		return 0
	fi

}


#定义一个采集内存的函数
meminfo(){
	free -h	
}

#定义一个主函数
main(){
	menu
	echo "### $num ###"	
	case $option in
	1)
		cpuinfo
		if (( $? == 0  ));then
			echo "cpuinfo return 0"
		fi
		;;
	2)
		meminfo
		;;
	3)
		df -h
		;;
	4)
		exit
		;;

	esac
}

#call main
main
[root@gh-shell shell]# 

在其他脚本里调用 function

[root@gh-shell shell]# cat sc.sh 
#!/bin/bash

#导入/shell/functions文件里的函数
#在当前终端执行
. /shell/functions

#直接调用函数
main
[root@gh-shell shell]# 
[root@gh-shell shell]# . sc.sh 
1.查看cpu信息
2.查看内存信息
3.查看磁盘信息
4.退出
请输入你的选择:3
### 6 ###
文件系统                 容量  已用  可用 已用% 挂载点
devtmpfs                 898M     0  898M    0% /dev
tmpfs                    910M     0  910M    0% /dev/shm
tmpfs                    910M  9.6M  901M    2% /run
tmpfs                    910M     0  910M    0% /sys/fs/cgroup
/dev/mapper/centos-root   50G  1.9G   49G    4% /
/dev/sda1               1014M  151M  864M   15% /boot
/dev/mapper/centos-home   47G   33M   47G    1% /home
tmpfs                    182M     0  182M    0% /run/user/0

小作业

使用位置变量

1.使用函数

​ 1.加法

​ 2.减法

​ 3.退出

#!/bin/bash

# 定义加法函数
function add() {
    result=$(($1 + $2))
    echo "加法结果为: $result"
}

# 定义减法函数
function subtract() {
    result=$(($1 - $2))
    echo "减法结果为: $result"
}

# 获取用户输入的两个数字
read -p "请输入第一个数字:" num1
read -p "请输入第二个数字:" num2

while true
do
    # 显示菜单选项
    echo "请选择操作:"
    echo "1. 加法"
    echo "2. 减法"
    echo "3. 退出"

    # 获取用户选择的操作
    read -p "请输入选项:" option

    case $option in
        1)
            add $num1 $num2
            ;;
        2)
            subtract $num1 $num2
            ;;
        3)
            echo "退出程序"
            exit
            ;;
        *)
            echo "无效的选项!"
            ;;
    esac
done

[root@gh-shell shell]# cat compute.sh 
#!/bin/bash  
  
# 获取用户输入的两个数字  
read -p "请输入第一个数字:" num1  
read -p "请输入第二个数字:" num2  
  
# 根据用户输入的运算符执行相应的操作  
case "$1" in  
  "+")  
    echo "$num1加$num2的值为: $(($num1 + $num2))"  
    ;;  
  "-")  
    echo "$num1减$num2的值为: $(($num1 - $num2))"  
    ;;  
  *)  
    echo "无效的运算符!!"  
    ;;  
esac
[root@gh-shell shell]# 

  1. 批量创建用户sc开头,20个用户,sc1到sc20,使用随机的密码,密码长度为10位
[root@gh-shell shell]# cat create_pass.sh 
#!/bin/bash

user=$1
for i in {1..20}
	do
		username="$user$i"
		useradd $username
		pass=$(echo $RANDOM|md5sum|cut -b 1-10)
		echo $pass|passwd --stdin $username
		echo "User $username created and password set."
	done

[root@gh-shell shell]# 
[root@gh-shell shell]# bash create_pass.sh sc
更改用户 sc1 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc1 created and password set.
更改用户 sc2 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc2 created and password set.
更改用户 sc3 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc3 created and password set.
更改用户 sc4 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc4 created and password set.
更改用户 sc5 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc5 created and password set.
更改用户 sc6 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc6 created and password set.
更改用户 sc7 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc7 created and password set.
更改用户 sc8 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc8 created and password set.
更改用户 sc9 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc9 created and password set.
更改用户 sc10 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc10 created and password set.
更改用户 sc11 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc11 created and password set.
更改用户 sc12 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc12 created and password set.
更改用户 sc13 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc13 created and password set.
更改用户 sc14 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc14 created and password set.
更改用户 sc15 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc15 created and password set.
更改用户 sc16 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc16 created and password set.
更改用户 sc17 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc17 created and password set.
更改用户 sc18 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc18 created and password set.
更改用户 sc19 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc19 created and password set.
更改用户 sc20 的密码 。
passwd:所有的身份验证令牌已经成功更新。
User sc20 created and password set.

3.编写一个抽奖程序,先随机产生一个中奖号码 在10以内,然后让用户去猜,顺便统计一下猜的次数,没用猜中就一直猜,如果在三次以内猜中的,输出你是天才,三次以上的就输出运气不好

​ while 死循环

​ let i++ 累加功能

​ ((i++))

[root@gh-shell shell]# cat lucky.sh 
#!/bin/bash

#生成中奖号码:
lucky_num=$((RANDOM%10))
#抽奖活动开始!
echo "开始抽奖!!!"
#echo "中奖号码为: $lucky_num"
i=1
while true
	do
		read -p "请输入你选取的号码: " num
		if (($i <= 3));then
			if (($num == $lucky_num));then
				echo "你是天才"
				exit
			else
				echo "回答错误!"
			fi
		else
			if (($num == $lucky_num));then
                        	echo "你得运气不好哦"
				exit
			else
				echo  "回答错误!"
                	fi
		
		fi
		let i++
	done

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不冤不乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值