shell

shell

shell创立的目的就是把一些常规的命令封号,本质是c语言写的,编译成二进制,一些shell脚本存放在/usr/bin目录中,打开可以看到是二进制文件
shell有很多种,有sh,bash,zsh等

我们可以把一些命令写到文件当中,下次我们直接执行这个文件方便很多,这种就是shell脚本
在windows中是*.bat
在linux中一般(约定俗成)是.sh文件结尾

shell脚本规则
第一行(SheBang):#!/bin/bash
第一行使用#! 指定shell执行的解释器,后面再出现#号就都是注释了

#!/bin/bash
#!/bin/sh 软链接也指向了bash
#!/usr/bin/python 使用python解释器,比如yum就是用的这个
#!/usr/bin/env 兼容写法
在这里插入图片描述

执行shell脚本的方式

在这里插入图片描述

bash命令

查看当前用的什么shell解释器 echo $SHELL
print the history story size : echo $HISTSIZE
print the code history : vim ~/.bash_history cat ~/.zsh_history history
history -c :clear the history
history -r : recover the history
!history_id : rapid exec the history cmd
!! : rapid exec the last cmd , also can use the up and down


ctrl+l : rapid cleart the terminal
echo $? : return the last cmd if exec successful ,if return 0 successful ,esle error

变量

变量命名中间不能有空格,比如name = “test”,中间加了空格会分开了,不认识了
变量命名区分大小写,打印变量可以echo $name,完整写法echo ${name},加上了{}

name="test_name"
echo $name # echo ${name}

变量是会有作用域的,在一个子shell的变量会在其它地方找不到,也会有全局变量,就都可以访问了
可以用pstree查看当前在哪个shell里了

让程序在后台跑

example:
nohup vivado &
会返回任务的PID号,需要结束直接kill PID就行
输出内容会存放在nohup.out文件中

其它

单引号不能识别特殊语法,双引号可以识别特殊语法

比如:

name="test" 
name1='${name}'  # name1="${name}" 
name2="${name}"  # name2="test" 

bash执行和source执行区别

如果调用bash/sh解释器执行脚本,就会开启一个子shell,因此不会保留当前的shell变量,可以用pstree进程树查看
如果使用source或者. 在当前shell加载脚本,就会保留变量

`反引号`

`反引号`包含起来的就不是字符串型变量了,他会把反引号中的内容进行执行并返回结果
name=`ll` # name 就会是ll执行的结果

环境变量

在这里插入图片描述

特殊参数变量

$0 shell脚本名字
$n n可以是1-9,如$1,$2等,如果大于9就需要加{},如${10},参数空格隔开
$# 脚本执行后面的参数总个数
$* 获取shell传过来的所有参数,不加引号等于$@, 带引号会把所有参数合并成字符串,无法分割
$@ 不加引号等于$*, 带引号会把参数分开

$*$@区别,在下面这段代码就可以看出来来,如果是$*,就一个参数,是$@就能正常分开循环输出
for var in "$*"
do
	echo "$var"
done

特殊状态变量

$? 上个脚本执行的返回值
$$ 获取当前脚本的PID号
$! 获取上一次执行的后台脚本的PID、
$_ 获取上次命令的最后一个参数

linux自带特殊命令

echo

-n 不换行输出
-e 解析字符串特殊符号如\n换行等

\n 换行
\r 回车
\t 制表符
\b 退格

example:
echo -e "test\ndemo"

printf

和c语言printf一样用就行

eval

执行多个命令时使用

# 使用分号;是隔开多个命令
eval ll;cd ~/Desktop

exec

不创建子进程,执行后续命令,执行完毕后自动exit

shell子串

${变量}  # 返回变量   
${#变量} # 返回变量字符长度
${变量:n} # 返回字符串索引n后面的内容
${变量:n:length} # 返回字符串索引n后面length个字符
${变量#word} # 返回从头开始删除最短匹配word的内容 其中word可以使用通配符*等,下面word同理
${变量##word} # 返回从头开始删除最长匹配word的内容 
${变量%word} # 返回从尾开始删除最短匹配word的内容
${变量%%word} # 返回从尾开始删除最长匹配word的内容
${变量/pattern/string} # 用string代替第一个匹配的pattern 
${变量//pattern/string} # 用string代替所有匹配的pattern

${变量:-word} # 如果变量为空,返回word
${变量:=word} # 如果变量为空,用word代替变量,也会返回word值
${变量:?word} # 如果变量为空,会把word输出报错stderr,否则输出变量值
${变量:+word} # 如果变量为空,什么都不做,否则word,(没弄错,是输出word)

拆分语法

{1…5} 从1到5

example:
touch demo_{1..5}_test.cpp # 会创建五个文件

示例:批量修改文件名

假设有五个文件 touch demo_{1…5}_test.cpp
需要将他们后面的_test删除

#!/bin/bash

for file_name in `ls demo*.cpp`
do
        echo $file_name
        mv $file_name `echo ${file_name//_test/}`
done

清空变量

name="test"
unset name

子shell

sh就可以进入子shell,使用ps -ef 就可以查看当前进程树
为什么要用子shell:有一些命令比较耗时或者需要一直执行,比如ping google.com等
那么可以把它放到子shell中运行,提高程序并发执行效率。
$BASH_SUBSHELL 如果是0就是当前shell,如果是1就是子shell
使用()包含起来的命令列表,就会在子shell中运行
example:
(cd ~/Desktop;ll;echo $BASH_SUBSHELL) # 我现在用的zsh,就要把BASH换成ZSH
也可以嵌套子shell,(pwd;(pwd;echo $ZSH_SUBSHELL))

内置命令,外置命令

内置命令:
在系统启动时就加载入内存,常驻内存,比如cd等命令,效率高,但是占资源
外置命令:
系统从硬盘中读取程序文件,再读入内存加载,特点:一定会开启一个子进程执行

通过linux的type命令判断属于哪一种命令

type cd
"cd is a shell builtin"
type ps
ps is /usr/bin/ps

比如使用ps命令,是外置命令,会开启子进程执行。

内置命令不会产生子进程执行。
内置命令和shell是一体的,是shell的一部分,不需要单独读取某个文件,系统启动后就存在内容了

查看linux内置命令:compgen -b

shell 数值计算

注意shell只支持整数运算,不支持浮点数
运算使用(( ))包含起来,也可以使用let,但是(( ))效率更高

num=5
((num=num*5))   # 赋值
echo $num # 打印

a++ # 和c相同,下面同理
a--
++a
--a

示例,shell实现求和

#!/usr/bin/bash

# shell 求和
if ((`echo $#`==0)) 
then 
	echo "error , please input val"
	exit -1
fi
sum=0
for var in "$@"
do
	((sum+=$var))
	# echo ${var}
done
echo "sum=${sum}"
exit 0

使用:
./shell_sum.sh 10 11 12 13 -333
输出:sum=-287

expr使用

man expr 或者 expr --help 查看手册

使用length等特殊

expr length test # 4

运算

# expr 逻辑运算
expr 5+3
expr 5 + 3
# expr 5 +3 是错的
# expr 5 * 3 是错的,因为有些符号是特殊字符
expr 5 \* 3 # 使用转义\

# expr 逻辑判断
expr 5 \> 6 # 返回0
expr 8 \> 6 # 返回1

模式匹配

expr 存在两个特殊字符。

: 冒号,计算字符串字符数量
.*   重复多次 


expr 123456 ":"  ".*"

bc命令

数学运算,支持浮点数

bc命令结合管道符

echo "2.2*4" | bc

计算1+2+3+…+100

echo {1..100} | tr " " "+" | bc

&& ||

A && B 当A成立时,会执行B
A || B 当A不成立时,会执行B

test命令

-e 判断文件/目录是否存在 # test -e main.cpp && echo "file is exist" || touch main.cpp
-f 判断文件是否是普通文件
-d 判断是否为目录

-z 判断字符串是否为空,为空返回真
-n 判断字符串是否为空,为空返回假

-r 判断是否可读 
-w 判断是否可写
-x 判断是否有可执行权限

[ ] 中括号条件测试

  • test和 [] 作用是一样的
  • 注意 [ testcode ] 中间需要有空格,否则报错
  • 在条件测试中使用变量,必须添加双引号
file_name="main.cpp"
[ -e "$file_name" ]  && echo "$file_name is exist" || touch main.cpp

[[ ]] 双中括号

和 [ ] 没啥区别

函数

函数定义写法:

# 第一种
function 函数名() {
	函数体
}

#第二种
#使用function关键词时可以省略()
function 函数名 {
 	函数体
}

#第三种
函数名() {
 	函数体
}
  • 函数定义一定在使用之前。
  • 函数中定义的变量为局部变量
  • 函数中也有return,执行到return就直接返回断了
  • 可以使用$?获取return的返回值
    • return 是结束函数的执行,exit是结束shell的执行
  • 函数单独写在一个文件里,使用source读取
  • 函数内使用locate定义局部变量
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值