shell基础知识
shell介绍
shell介于内核与用户之间,负责命令的解释。
shell类型
[root@localhost ~]# cat /etc/shells 查看shell种类
/bin/sh 是bash shell的一个快捷方式
/bin/bash bash shell 是大多数Linux默认的shell,功能齐全
/usr/bin/sh
/usr/bin/bash
/bin/tcsh 是csh的增强版 ,完全兼容csh
/bin/csh 具有C语言风格的一种shell
/sbin/nologin 非交互 ,不能登录操作系统
shell脚本格式
#!/bin/bash
//第一行 #!魔法字符,指定代码的执行程序,即告诉系统用什么解释器(用那种shell)
//脚本基本信息描述
#name:名字
#describe:描述用途
#Path:存放路径
#usage:用法
#update:更新时间
//脚本具体内容
.......
shell脚本执行方法
标准执行:
shell脚本必须要有可执行权限
chmod +x 脚本文件 (加可执行权限)
绝对路径执行:/shell10/shell1.sh
相对路径执行:./shell1.sh
非标准执行:
shell脚本可以不要可执行权限
bash shell1.sh
bash -x 脚本名 查看脚本执行过程
bash -n 脚本名 查看脚本是否有语法错误
source shell1.sh
. shell1.sh(.后有个空格)
****除了绝对路径执行外,其他的执行命令必须在脚本所在目录下执行
bash的基本特性
常见快捷键
ctrl +c 终止某个操作
z 将前台运行的程序挂到后台
d 退出 等于exit
1 清屏等于clear
a 光标移动到命令行最前端
e 光标移动到命令行最后端
u 删除光标前所有字符
k删除光标后所有字符
r 搜索历史命令(输入关键字即可)
常用通配符
* :匹配0或多个字符
? :匹配任意单个字符
[list] :匹配[list]中的任意单个字符或者一组单个字符 file[abc] 匹配filea或fileb或filec, file[1-47] 匹配file1到file4和file7 (-必须后边的大于前边的)
[!list] :匹配除[!list]中的任意单个字符 或一组单个字符[!abc] 匹配除filea、fileb、filec 外的任意file加一个字符
{string1,string2,.......} :匹配string1,string2 ,或更多字符 file{3..6}(必须要两个点) 匹配file3 file4 .....file6 or file{3,4,5,6}
例子:有两个文件file1 ,file11
ls -l fi* 或者 flile*能匹配到两个文件 ls -l file1* 能匹配到file1
但ls -l file1? 匹配不到file1 且 ls -l fil? 匹配不到连个文件 只有ls -l file? 匹配到file1 ls -l file1?匹配到file11
bash中的引号
双引号"" :会把引号内的内容当成整体来看,允许通过$符合引用其他变量值
单引号'' : 会把引号内的内容当成整体来看,禁止引用其他变量值,shell中特殊符号都被视为普通字符
反撇号`` :反撇号和$()一样,引号或括号里的命令会优先执行,如果存在嵌套,反撇号不能用
echo "$(date +%F)" = echo "`date +%F`"
echo `echo "`date +%F`"` 这就是嵌套,是不允许的会报错,可以改为 echo $(echo "`date +%F`")
重命名文件
mv 只能重命名单个文件 (多个就会当成移动文件)
把file1-3重命名为text1-3
rename file text file?
把file11-13 重命名为text11-13
rename file1 text file1? or rename file text file??
变量的定义
1、变量的分类
本地变量:当前用户自定义的变量,当前进程中有效,其他进程即当前的子进程无效。
环境变量:当前进程有效,并且能够被子进程调用
全局变量:全局所有用户和程序都能调用,且继承、新建的用户也能调用。
查看当前用户的环境变量: env |grep ^A
查看当前用户的所有变量:set
临时将临时(本地)变量变成环境变量:export A=hello
永久生效:vim /etc/profile 末尾加上 export A=hello 重新加载此文件source /etc/profile
第三方软件配置环境变量
which 软件名 找到命令所在文件
vim /etc/profile 末尾加上
export PATH="$PATH:/usr/local/mysql/bin:第二个路径" (加export是环境变量,不加则是本地变量)
系统变量(内置bash中的变量):shell本身已经固定好了其名字和作用
$? :上一条命令执行后的返回状态,返回值为0表示正常,非零为出异常或出错
0 命令成功结束
1 通用未知错误
2 误用shell命令
126 找到命令,但命令不可执行(权限不够)
127 没找到命令
128 无效退出参数
128+x Linux 信号x的严重错误
130 Linux 信号2 的严重错误,即命令通过SIGINT(Ctrl+C)终止
255 退出状态码越界
$$ :当前所在进程的进程号 kill -9 `echo $$` 杀死当前进程
$! :后台运行的最后一个进程号 echo $!
!$:调用最后一条命令历史中的参数
!!:调用最后一条历史命令
$#:脚本后面接的参数个数
$*:脚本后面所有参数,参数当成一个整体输出,每一个变量参数之间以空格隔开
$@:脚本后面所有的参数,参数是独立的,也是全部输出
$0:当前执行的进程/程序名
$1~$9:位置参数变量
${10}~${n} :扩展位置参数变量,第十个位置变量必须用{}括起来
变量定义
1、默认情况下,shell里定义变量是不分类型的,可以给变量赋予任何类型的值;等号两边不能有空格,对于有空格的字符串作为赋值时,要用引号引起来。变量名=变量值
2、变量的获取方式:$变量名
A=123456
echo $A or echo ${A}
都显示:123456
echo ${变量名:从第几个字符截取:截取的字符个数}
echo ${A:2:3} ***第二段为下标,从0开始。下标0对应A中第一个字符,第三段表示显示几个字符***
显示为:345
unset 变量名 :删除变量
变量定义规则
shell中变量名区分大小写,A =123 a=456 这是两个变量。
shell中变量重新赋值后会覆盖,先定义A=123,后定义A=456 最后A的变量值为456
shell中变量名不能以数字开头,也不能有特殊字符,如? $ *等
shell中可以把一个命令的执行结果赋值给一个变量
自己定义有类型的变量
declare 选项 变量名=变量值
- -f 仅显示函数。
- -r 将变量设置为只读。
- -x 指定的变量会成为环境变量,可供shell以外的程序来使用。相当于用export 变量名 进行导出
- -i [设置值]声明变量为整数型 "+r"则是取消变量所设的属性。
- -a 指定为索引数组(普通数组)
- -A 指定为关联数组
如:declare -r A=123 :设置变量为只读,此时,想要再设置A变量进行覆盖是不行的。unset A也不能删除变量
取消只读:
# cat << EOF| gdb
> attach $$
> call unbind_variable("test") test为变量名
> detach
> EOF
数组
普通数组:只能使用整数作为数据索引(元素下标)
关联数组:可以使用字符串作为数组索引(元素的下标)
普通数组定义:用括号来表示数字,数组元素(变量)用空格符号分割开,
定义数组的一般形式为:
变量名=变量值
array[0]=v1 数组下标0赋值为v1
array[1]=v2 数组下标1赋值为v2
array[2]=v3
or
array=(v1 v2 v3) 数组下标0 ,1, 2,赋值为 v1 ,v2, v3
array1=(`cat /etc/passwd`) or array1=($(cat /etc/passwd))把passwd中每一行赋值给array1数组
array2=(1 2 3 "hello word" [10]=linux) ""里为一个元素 []=元素 :指定元素下标
echo ${array[*]} :获取数组所有元素,也可以用@
echo ${array[1]} :获取数组下标1的元素
echo ${array[*]:1:2} :获取数组从下标1开始,后两个下标的元素,即下标1下标2的值,是v2 v3
数组变量也会覆盖(只会覆盖再定义的下标的元素)
如:再定义 array[0]=m1 array[10]=m2
则数组array='(array[0]=m1 array[1]=v2 array[2]=v3 array[10]=m2)'
获取数组里的元素个数:echo ${#array[*]} /数组长度
获取数组里有元素值的下标号 :echo ${!array[*]}
关联数组定义:
首先声明关联数组
declare -A array10
数组赋值:
数组名[索引下标]=变量值
一次赋一个值:
array10[linux]=one
array10[java]=two
一次赋多个值:
array10=([linux]=one [java]=two [name]="feng xue")
查看关联数组:
declare -A
echo ${array10[*]} :获取关联数组的所有元素,其是无序的 。@也可
echo ${array10[name]} :获取固定数组下标的元素
echo ${#array10[*]} :获取关联数组里的元素个数/数组长度
echo ${!array10[*]} :获取关联数组里的下标值
交互式定义变量的值 read 让用户去定义变量的值
-p 定义提示信息
-n 字符数(限制变量值的字符)
-s 不显示
-t 超时(默认单位为秒)(限制用户输入变量的超时时间)
read -p "提示信息如:input your name:" name
read -s -p "input your passwd:" passwd 你输入的字符不在屏幕上显示
read -n 3 "input your name:" name 只能输入三个字符如abc
read -t 3 "input your name:" name 三秒后退出输入界面,三秒内没有回车确认不会给变量赋值
#read A B
hello world
上边A赋值hello B赋值world
#read A B < 1.txt 从文件中获取值 1.txt内容为hello world
上边A赋值hello B赋值world
注意:read A B 赋值多个变量时 只有遇到空格后才会分别赋值两个变量,若1.txt内容为hello:world 变量A值为hello:world B为空
其他变量(扩展)
1、取出一个目录下的目录和文件:dirname和basname
2、变量内容的删除和替换
一个"%"代表从右往左去掉一个/key/
两个"%%"代表从右往左去掉最大的一个/key/
一个"#"代表从左往右去掉一个/key/
两个"##"代表从左往右去掉最大的一个/key/
${变量名#关键字符} 如果变量内容从头开始的数据符合"关键字符",则将符合的最短数据删除
${变量名##关键字符} 如果变量内容从头开始的数据符合"关键字符",则将符合的最长数据删除
${变量名%关键字符} 如果变量内容从尾开始的数据符合"关键字符",则将符合的最短数据删除
${变量名%%关键字符} 如果变量内容从尾开始的数据符合"关键字符",则将符合的最长数据删除
#A=/root/desktop/shell/mem.txt 定义变量为此目录
#dirname $A 取出目录
/root/desktop/shell
#basname $A 取出文件
mem.txt
#url=www.taobao.com
#echo ${#url} 获得变量长度
#echo ${url#*.} #从左往右最短匹配 *.表示关键字
taobao.com
#echo ${url##*.} #从左往右最长匹配
com
#echo ${url%.*} #从右往左最短匹配
www.taobao
#echo ${url%%.*} #从右往左最长匹配
www
替换
${变量名/旧字符串/新字符串} |
表示若变量内容符有旧字符串则第一个旧字符串会被新字符串替换 |
${变量名//旧字符串/新字符串} |
表示若变量内容有旧字符串则全部旧字符串会被新字符串替换 |
#echo ${url/taobao/wangyi}
www.wangyi.com
#echo ${url//o/i}
www.taibai.cim
Shell变量的替代
给Shell变量设置默认值的格式为${变量名-新的变量值}or${变量名=新的变量值}
,如果变量名没有被赋值,会使用新的变量值替代,如果已被赋值(包括空值),则该值不会被替代。
${变量名:-新的变量名}
这样如果变量为空值也会被替代
简单的四则运算
算术运算:默认情况下,shell就只能支持简单的整数运算
+ - * / % (/求商 %取余数)
bash shell中算数运算有四种方式
1、使用$(()) echo $((5/10)) 得0 echo $((5%10)) 得5
2、使用$[] echo $[5*10] 50 echo $[5/10] 0
3、使用expr 外部程式 exper 3 +(-,/,%) 2 expr 2 \* 3 等于6 乘号比较特殊需要转义一下 数字 符号 数字间得有空格,不然就直接输出字符串:expr 2*3 输出:2*3
4、使用let命令 let n=n+(-,%,/,*)1 等于 let n+(-,%,/,*)=1 let n=n**2(求n的2次方) let n=n**3(4,5,6....)(n的三(4,5,6...)次方)
如何算小数 bc
echo 1+1.5 |bc (跟bc的话,数字 符号 数字间可以没有空格)
还可以直接输bc进入其中计算
[root@localhost ~]# bc bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 2.4*4.5 (输入计算) 10.8 (结果) 5/2 2 ^C (interrupt) Exiting bc.
i++与++i的区别
对变量值无影响:i=1,j=1,let i++ =let j++ 值是一样的
对表达式的值有影响:
let x=i++ i++ 先赋值后运算(先把i的值给x,i再加一)
let y=++j ++j 先运算后赋值 (j先加一。再把j的值给y)
上边i=2 j=2 但x=1,y=2
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!