linux中shell编程

时间:2023-04-01 08:06:31

shell编程

1 echo
-e 识别\转义符 \a \b \t \n \x十六进制 \0八进制 等等
#!/bin/bash
echo -e "hello world"

执行脚本:方式1 :chmod 755 hello.sh
./hello.sh
方式2 :bash ./hello.sh(这种方式不需要给执行权限)

1 历史命令
history 直接回车就可以看到已经敲过得命令。-c清空缓存中和文件中的命令 -w将缓存中命令写入 家目录/.bash_history
这个命令可以帮助管理员查看linux系统被操作过什么
/etc/profile 文件对history命令做了设置。默认是可以保存10000条。
!n表示重复执行第n条命令
!!重复执行上一条命令
!字串 重复执行最后一条以该字串开始的命令

2 tab键补全

3 命令的别名
alias 别名='原命令' alias直接回车是查询现在系统中的别名设置情况

命令执行顺序:1 路径下的命令 2 执行别名 3 执行bash的内部命令(例如cd这种命令是在linux中找不到执行文件的,因为这种命令是shell中自带的 命令) 4环境变量定义的中的命令

利用以上方式定义的别名,计算机重启就会失效,修改 vi /root/.bashrc 将别名加上去就可以了 若在别的用户里就修改别的用户下的.bashrc文件

2 bash的常用快捷键
ctrl+c ctrl+l ctrl+u(剪切光标左侧所有内容,也相当于删除了一行) ctrl+y(粘贴) ctrl+d(退出当前命令) ctrl+r(搜索历史命令)

3 标准输入输出
键盘 /dev/stdin 0 标准输入
显示器 /dev/sdtout 1 标准输出
显示器 /dev/sdtout 2 标准错误输出

输出、输入重定向
输出重定向:命令>文件 以覆盖的方式,把命令的正确输入输出到指定的文件或设备中
命令>>文件 以追加的方式,把命令的正确输入输出到指定的文件或设备中
错误命令 2>文件 以覆盖的方式,把命令的错误输出到指定的文件或设备中
错误命令 2>>文件 以追加的方式,把命令的错误输出到指定的文件或设备中

实际工作中使用:命令 &> 文件 以覆盖的方式,把命令的正确或错误的输入输出到指定的文件或设备中
命令 &>>文件 以追加的方式,把命令的正确或错误输入输出到指定的文件或设备中
命令>>文件1 2>>文件2 把正确的命令保存到文件1 把错误的命令保存到文件2

命令 &>/dev/null null文件是一个“垃圾箱”
输入重定向:
wc [选项 -c 统计字节数 -w 统计单词数 -l 统计行数] < [文件名]
wc 回车 输入 ctrl+d 结束wc命令
wc < 文件名

4 多命令执行

顺序执行

; 命令1;命令2 多个命令顺序执行,命令之间没有任何逻辑联系
&& 命令1&&命令2 逻辑与 命令1正确执行了命令2才会执行
|| 命令1||命令2 逻辑或 命令1正确执行命令2就不执行了,反之执行

例子:date;dd if=/dev/zero of=/root/testfile bs=lk count=10000;date
命令 && echo yes || echo no

命令替换

命令1 $(命令2)    or

命令1 `命令2`

命令别名

alias [别名]=[需要定义别名的命令]

命名中有空格的话,就需要用引号   ege: alias ok="ls -l /boot"

取消别名:unalias [别名]

在重新启动计算机以及关闭终端以后,定义的别名失效;若系统中有与别名同名的系统命令,则定义的别名优先于系统中原有命令
5 管道符
命令1 | 命令2
命令1的正确执行的输出作为命令2的操作对象
ll -a /etc | more
netstat -an | grep ESTABLISHED
too
6 通配符
? (one)
* (0 or more)
[abc] 匹配中括号中任一字符
[a-z] 匹配中括号中范围中的任一字符
[^0-9] 匹配除了0-9范围的任一字符
7 特殊符号
' '在单引号总所有特殊符号都没有特殊含义
" " 在双引号中 $ ` \有特殊意义分别是调用变量值,引用命令,转义符
` ` 反引号括起来的一般是命令,
一般不用反引号,用&(命令)代替反引号
#注释
$用于调用变量的值
\转义符 使特殊符号的特殊作用取消
\t \n是一个整体符号,一般不能把符号中\作为转义符

!$ 前一个命令的最后的参数

  mkdir /root/aaa

  cd !$ 进入到/root/aaa

8 用户自定义变量
变量不允许以数字开头
在bash中,变量的默认类型都是字符串型,如果要进行数值运算,则必须指定变量类型为数值型。

变量用等号连接值,等号左右两侧不能有空格
变量值中如果有空格,则需要用单引号或者双引号括起来

变量有:用户自定义变量、环境变量、位置参数变量、预定义变量

变量的叠加:
a=000
a=$(a)123
a="$a":123

set命令查看当前所有变量。
取消变量:unset 变量名
9 环境变量
用户自定义变量只是在当前的shell中生效。

命令定义的环境变量会在当前shell和这个shell的所有子shell当中生效,相当于全局变量,如果把环境变脸写入相应的配置文件,那么这个环境变量就 会在所有的shell 中生效。

父和子bash的查询通过pstree命令

环境变量的设置;
export 变量名=变量名(相当于定义一个全局变量)
对于已经有的用户自定义变量,直接使用:export 变量名 就把这个变量定义成一个当前的环境变量
env 查询变量
unset 删除变量

常见系统级环境变量:
PATH
PATH="$PATH":/tmp/hello.sh
通过这种定义就可以直接执行hello.sh了,但这是临时生效

PS1定义系统提示符变量 可以修改提示符的格式

10 位置参数变量
$n n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,10以上参数需要用大括号包含,$(10).
使用方法参考视频吧,不好写,不乐意写了。
$* 这个变量代表所有的参数,把所有参数当做一个整体
$@ 同#*,代表所有参数,但是#@把参数区分看待
$# 代表参数个数

11 预定义变量
$? 最后一次执行命令的返回状态,如果是0,则说明上条命令正确执行了,如果非零则说明上条命令没有正确执行
$$ 当前进程的进程号(PID)
在命令最后加上&,表示将程序放入后台运行
$! 后台运行的最后一个进程的进程号(PID)

12 Bash变量—数值运算与运算符
数值运算:
方法一:
declare [+/-][选项] 变量名
- 给变量设定类型属性
+ 取消变量的类型属性
-i 将变量声明为整数型
-x 将变量声明为环境变量 与export命令一样
-p 显示指定变量的被声明的类型
方法二:
expr和let数值运算工具(不常用)
方法三:
$((运算式)) 或 $[运算式]

运算符:
基本全支持

13 变量测试与内容替换

14 环境变量配置文件简介
source 配置文件
或 . 配置文件
以上命令可以省略修改配置文件后必须重新登录这个步骤

环境变量配置文件中主要是定义对系统的操作系统生效的系统默认环境变量,比如PATH
PATH="$PATH":/ROOT 这种形式的修改环境变量只对当前有效

对应环境变量的配置文件主要有: /etc/profile (对所有用户都有效)
/etc/profile.d/*.sh (这表示一组环境变量配置文件,对所有用户都有效)
~/.bash_profile (对自己有效,以.开头表示隐藏文件)
~/.bash_profile (对自己有效)
/etc/bashrc (对所有用户都有效)

15 其他环境变量配置文件
~/.bash_logout 注销时生效的环境变量配置文件
~/bash_history 历史命令保存配置文件(注销后才会写入或者使用history —w)
/etc/issue 本地终端登陆信息(对于远程登陆没用)
/etc/issue.net 远程登陆信息(本地的转义符不能用) 这个需要在/etc/ssh/sshd_config中进行设置
/etc/motd 不管是远程还是本地都有效,但是是针对登陆后的登陆信息

16 基础正则表达式
正则化是用来匹配字符串的 grep awk sed
通配符是用来匹配文件名的 * ? ls find cp不支持正则表达式,所以只能使用shell自己的通配符来进行匹配了。

通配符是全完匹配 也就是说ls aa 只列出aa 不会列出aabb
正则是包含匹配 也就是文件中某行有某个字串就会列出这行

正则:
* 前一个字符匹配0次或任意多次,注意是前一个字符,区别于通配符,"a*"没有任何意义 "aa*" 这样才是匹配首字母为a的字符串的行
( 通配符中*表示任意多个字符 ?表示一个字符)

. 匹配除了换行符外任意一个字符 (相当于通配符中?)(.* 这样写的正则相当于通配符中的*)

^ 匹配行首
$ 匹配行尾 (^$ 这样写匹配空白行) grep -n “^$” 文件
[] 匹配中括号中指定的任意一个字符,只匹配一个字符
[^] 匹配除了中括号以外的任意一个字符
\转义符
\{n\} 表示其前面的字符恰好出现n次 [0-9]\{4\}
\{n,\} 表示其前面的字符出现不小于n次
\{n,m\} 表示其前面的字符至少出现n次
17 字符处理命令
cut字段提取命令
cut [选项] 文件名 -f 提起第几列(默认使用tab键最为分隔符,若不是tab键则需要用-d指定分割符是什么) -d按照指定分隔符割列
当分割符是空格时,需要使用awk命令
printf命令 格式化打印命令
%m.nf m表示浮点型数据的宽度,n表示小数位数
%i 整数
%s 字符串
printf '%s\n' 1,2,3,4 printf '%s %s %s\n' 1 2 3 4 5 6 这样会认为有两组字符串

之所以学习printf是因为awk命令不能调用系统命令,只能使用printf命令输出内容

linux中回车是\r windows是\r\n
awk命令比较复杂 参看视频吧 默认识别的分隔符是空格和tab
awk '条件 {动作} 条件 {动作}' 文件
df -h | awk '{printf $1 "\t" $5 "\n"}'

awk 'BEGIN {printf "this is a transcript\n"}{printf $1 "\n"}' 文件
其中BEGIN表示在正式打印前打印一个this is a transcript,抵消掉awk默认读取第一行以空格或制表符为分隔符
awk 'BEGIN {FS=":"}END{printf this is end }{printf $1 "\n"}' 文件 指定分隔符为:
awk '$6>10{printf hahaha}'

sed命令 轻量级流编辑器 sed主要是用来将数据进行选取、替换、删除和新增
sed [选项] ‘[动作]’ 文件名
选项
-n 一般sed命令会把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕
-e 允许对输入数据应用多条sed命令编辑
-i 用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出
动作
a\ 追加
c\ 行替换
i\ 插入
d 删除
p 打印
s 字串替换

sed '2a hello' 文件 意思是第二行后追加hello
sed '2i hello' 文件 意思是在第二行前插入hello
sed 's/旧字串/新字串/g' 文件 sed '4/hello/wdx/g' 文件名 将文件第4行中hello字串改为wdx字串
sed -e 's/hello/edx/g;s/world/cyj/g' 文件名 将文件中所有hello替换为edx,将world替换为cyj

sort命令 sort [选项] 文件名
-f 忽略大小写
-n 以数值型进行排序,默认使用字符串型排序
-r 反向排序
-t 指定分隔符,默认分隔符是制表符
-k n[,m] 按照指定的字段范围排序,从第n字段开始m字段结束
wc 统计命令
-l 统计行
-w 统计单词数
-m 统计字符数

18 test条件判断式
-b 文件,判断该文件是否存在,并且是否为块设备文件(是块设备文件为真)
-d 文件,判断该文件是否存在,并且是否为目录文件(是目录为真)
-e 文件,判断该文件是否存在
-f 文件,判断该文件是否存在,并且该文件是否是普通文件
-r 文件,判断该文件是否存在,判断是否有读权限
-w 文件,判断该文件是否存在,写
-x 文件,判断该文件是否存在,执行
文件1 -nt 文件2 判断文件1的修改时间是否比文件2的新
文件1 -ot 文件2 判断文件1的修改时间是否比文件2的旧
文件1 -ef 文件2 判断文件1是否和文件2的Inode号相同,可以理解为是否是同一文件(硬链接)

还有判断整数和字符串的命令
-eq判断相等针对整数
==判断字符串是否相等
判断1 -a 判断2 逻辑与
判断1 -o 判断2 逻辑或
!判断 逻辑非 使原始的判断式取反

test [选项] 文件
或者[选项 文件]

19 if语句
if 判断(test语句)
then
语句
else
语句
fi

if 判断
then
语句
elif 判断
then

备份mysql数据库
#!/bin/bash
ntpdate asia.pool.ntp.org$>/dev/null
date=$(date +%y%m%d) #当前系统时间
size=$(du-sh /var/lib/mysql) #统计数据库的大小,把大小赋予size变量
。。。。。。。。。。看视频或者ppt吧

20 case语句
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
*)
都不对执行的程序段

esac

21 for循环
for 变量 in 值1 值2 值3
do
程序段
done

ls > ls.log
for 变量 in $(cat ls.log)
do
程序段
done

tar -zxf 解包
tar -ztf 压包

另一种for语言
s=0
for((i=1;i<=100;1=i+1))
do
s=$((s+i))
done
echo "the sum of 1+2+.....+100 is":$s

批量添加用户

22 while循环与until循环
while循环是不定循环,也称作条件循环,只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环不会停止,这就和for的固定循环不 太一样。

i=0
s=0
while [$i -le 100] #小于等于
do
s=$(($s+$i))
i=$(($i+1))
done
echo "the sum is: $s"

until循环和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序,一旦循环条件成立,则不循环

i=1
s=0
until [$i -gt 100] #大于
do
s=$(($s+$i))
i=$(($i+1))
done
echo "the sum is: $s"

脚本语言所见所得,不需要先“编译”再执行,而是边编译边执行。

由于windows和linux下回车符不一样,从windows到linux的转换执行:dos2unix 文件名