学习shell第一天
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种执行方式
在Linux中,export命令用于设置环境变量,将一个变量导出为环境变量,使得它对当前shell进程中的所有子进程可见。
导出变量为环境变量:
输入 export VARIABLE_NAME 输出一个变量为全局变量,子进程里的也可以使用
例如: export MY_VAR
这个例子将MY_VAR变量导出为环境变量。
还可以这样:
一些细小知识点
$?
$?预定义的变量:操作系统里预先定义好的变量,不需要我们人去自定义
代表上一条命令的返回值
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 发生的故事
还是接上边的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
位置变量
[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]#
- 批量创建用户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