欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

shell总结

程序员文章站 2022-06-11 19:27:22
...

文章目录


忘记了但是看得是那本书,然后做的笔记。

1.)变量和表达式
1.运行程序的三种方式:

a. 使文件有可执行的权限,可以直接运行(./执行,没x,则提示权限不够)
b. 直接调用命令解释器执行程序
c. 使用source执行文件

2.选择解释器:

第一行中声明: #!/bin/bash 或者 #!/usr/bin/python等解释器

3.执行原理:

一般父进程fork一个子进程,脚本在子进程中执行,不会影响父进程。
但是source (也叫点命令 .)执行的脚本,不会创建子进程,而直接在父进程中执行。

4.shell的命令种类
5.变量

命名规范:以一个字母或下划线开头,后面可以跟任意长字母,数字和下划线。
如:count=0 等号两边不能有空格。
调用时:在名称前加$符, echo $count, 更规范的是: ${count}

a.环境变量(全局变量):可以在创建他的的shell中以及fork出来的子进程中使用。如:PATH
b.局部变量: 只能在父进程fork出来的进程中使用。

5.1 配置文件加载顺序:

profile类文件作用:/etc/profile , /etc/profile.d/*.sh (常用) ,~/.bash_profile
a. 定义环境变量
b. 运行命令和脚本
bashrc类文件作用: /etc/bashrc , ~/.bashrc
a. 定义本地变量,函数
b. 命令别名

加载顺序:
登陆式: /etc/profile > ~/.bash_profile > ~/.bah_login > ~/.profile > ~/.bash_logout
非登陆式shell配置加载顺序: /etc/bash.bashrc > ~/.bashrc

6.单双引号:

var=1
单引号中的变量不能被解释,'varvar'就是var字符串
双引号: "$var"解释为1

7.Null和初始化变量

如果没有初始化变量,值为Null,打印出来为空,类似js中"",可以做加减运算,等于0
但是可能不可移植。

8.变量类型: 全局和局部(local)

即便在函数中的变量,如果没有local关键字,那么变量也是全局的。

9.export声明变量

export变量只能影响这个脚本所在的子进程,需要使用source来改变父进程
export的变量只能影响当前登录操作,当连接关闭后,变量失效。
所以需要把声明的变量写到配置文件(登入和登出文件)中:
a./etc/profile (常用)
b./etc/bashrc
c.HOME/.bashprofiled.HOME/.bash_profile d.HOME/.bashrc
e.$HOME/.bash_logout

10.env 临时修改环境变量值,下一条命令就会改回来

-i:清空父级的继承过来的环境变量。

11.unset 删除当前shell中的函数或变量,

删除函数时,需要 -f

11.1 申明变量的常见方式:

export 变量
export 变量=value
declare -x 变量=value

12. 数值运算

(()) 整数运算.也可以进行与或非和比较运算
let 类似(())
bc linux下计算器
awk 整数和小数

13. 条件表达式

在while和if语句中常使用条件表达式进行语句控制
a. test <测试表达式>
b. [<测试表达式>] 可以使用 -a -o -gt -lt等,不能使用&&,<,|等
c. [[<测试表达式>]] 可以使用&&,||,<
d. ((<测试表达式>))

14. 整数二元比较字符串

在[]和test (())和[[]]
-eq ==或=
-ne !=
-gt >
-ge >=
-lt <
-le <=

test和[]中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较

15.逻辑操作符

在[]和test (())和[[]]
-a &&
-o ||
! !

16.常用的使用命令返回值得形式:

a. nowTime=date +%F #反引号的形式
b. nowTime=$(date +%F) #小括号计算的形式

17 文件系统

[ -f $file_var ] :如果给定的变量包含正常的文件路径或文件名,则返回真。
[ -x $var ] :如果给定的变量包含的文件可执行,则返回真。
[ -d $var ] :如果给定的变量包含的是目录,则返回真。
[ -e $var ] :如果给定的变量包含的文件存在,则返回真。
[ -c $var ] :如果给定的变量包含的是一个字符设备文件的路径,则返回真。
[ -b $var ] :如果给定的变量包含的是一个块设备文件的路径,则返回真。
[ -w $var ] :如果给定的变量包含的文件可写,则返回真。
[ -r $var ] :如果给定的变量包含的文件可读,则返回真。
[ -L $var ] :如果给定的变量包含的是一个符号链接,则返回真。

2.脚本传参以及重定向
1.) 脚本参数和特殊变量

如执行脚本:sh test.sh a b c
脚本中:$#表示参数个数,上面是3个
[email protected]表示所有参数内容,a b c (常用)
如果参数中包含空格,使用双引号,或单引号(两个区别同变量时区别一样)
sh test “my name is joker”
除此之外还有如下:

  0,1,2,...:  0表示程序名,1表示第一个参数,以此类推,如果大于10 ,则使用 ${10}
  * :以一个单字符串显示所有参数,可以超过9个参数
  $: 当前进程ID
  !:后台运行的最后一个进程的ID号
  ?:显示最后命令的退出状态,0表示没有后错误,其他任何值都表明有错误。
    常见的状态值含义:
      0 :表示运行成功
      2 :权限拒绝
      1-125: 命令或者参数传递错误
      126: 找到命令,但是无法执行
      127: 未找到命令
      128之后: 命令被系统强制结束

  -:显示shell使用的当前选项,与set命令功能一样。
2.mkdir -p :创建中间目录,如果目录不存在
3.标准输入、输出和错误 (>覆盖, >>追加)

a.stdin: 代码为0 ,使用<或<<
b.stdout:代码为1,使用>或>>
c.stderr:代码为2,使用2>或2>>
如: find /home -name .bashrc >right_msg 2>error_msg
黑洞: /dev/null
常见的将错误和标准都输入一个文件中:

list_doc 2>&1
或 &>list_doc

标准输入:
a.
cat > newfile < oldfile
b.
cat > newfile << “eof”
this is a test
ok new stop
eof

4.管道:通过 | 建立

cat file | grep ‘test’

5.head -n 10 显示前10行
6.未声明的变量在做加减运算时,等同于null
7.常见特殊符号:

~ `(反引号) # $ & * ( [ ] ) {} ; ’ " < > \ ? !

8.事实上shell只有字符串类型:

a=1
a+=1
echo $a;结果为11,字符串拼接。

9.第十个即以后位置参数,使用${10},以此类推。
10.替换运算符,用于测试变量是声明,给与默认值或给出提示消息。

${varname:-word} , ${varname:=word}, varname:?message,{varname:?message},{varname:+word}

11.模式匹配运算符:也可以用sed进行匹配

${varname#pattern} 删去匹配最短的
${varname##pattern}删除最长的匹配
${varname%pattern} 从右侧开始匹配,删除最短的匹配
${varname%%pattern} 从右侧开始匹配,删除最长的匹配。
${varname/pattern/string}

12.shift命令,截取参数列表最左端一个,类似js中的shift函数。
13.type命令:

type ls , type cat … 显示命令是内建命令还是外部命令,还是aliase

14. 字符串长度

count=“1234g”
echo ${#count}

3. for_if_while_function
1.函数声明

function funName()
{
代码块
}
或者:
funName()
{

}
function关键字的函数,可以省略(),但是不建议
花括号必须在函数名下面。

2.函数参数和返回值

函数调用时,fun 1 2 使用类似命令
通过[email protected]或$1,2...return2...等获取传递给函数的参数 通过return 返回一个值,这个值通过?获取。

有个注意点就是: 在脚本里面定义的变量(只要不是在函数中添加local定义的),那么函数中是可见的。
还有: $1,$2这些脚本的外部传递进来的参数是对于函数是不可见的。所有必须函数传参方式。

3.if-elif-else

if condition
then
statement
[elif condition
then statement]
[else
statement]
fi
if语句使用test进行内容测试
if test "2>3"等同 if [ “2>3” ],中括号里面前后都需要有空格。

if语句可以使用如下代替:
[条件1] && {
命令1
命令2
。。。
}

4. 与或非

! && ||

5.文件属性检查,检查变量时,需要双引号

[ -f “filename"][!f"filename" ] [ ! -f "filename” ]
类型检查:
-b(块设备)
-c(字符设备)
-d(目录)
-f(一般文件)
-h 、-L(符号链接)
-p 管道文件
-S (大写,套接字文件)

其他检查:
-e 文件是否存在
-g 是否设置了setgid
-u setuid
-r 是否可读
-w 可写
-x可执行
-s 内容非空
-O 大写,是否是文件拥有者
-G 文件的Gid匹配你的id

file1 -nt file2 文件1是否比文件2新 new then
file1 -ot file2 文件1是否比文件2旧 old then

6. case语句

case expression in
pattern1)
statement;;
pattern2)
statement;;
pattern3 | pattern4)
statement;;
*)
statement;; 类似default
esac
任何pattern之间都可以使用管道进行分割处理。

7 循环控制

for n in list
do

done
如果in list 被省略,那么默认是 in “[email protected]
for name
do
case $name in
f) …
d) …
esac
done

常见迭代:
a){a…z}, {1…50}等
for i in {a…z}
do
echo $i
done
b.)seq
for i in $(seq 1 6);do echo $i;done
c.) c语言形式
for((i=0;i<20;i++)) {
echo $i
}

8. while和until

while condition
do
statement
done
类似的:
until condition
do
statement
done

9.字符串测试表达式

-n “字符串” :若字符串长度>0,true;反之false,理解成not zero
-z “字符串” :若字符串长度为0, true;反之false (用这个)
“字符串1” = “字符串2” :判断是是否相同,可以使用==替代
“字符串1” != “字符串2”

10 break用于跳槽循环,continue跳过本次,继续循环。
4. 正则表达式
1.元字符
^  开头锚定
$   结尾锚定
.   任意一个字符
*   匹配0到任意多个先前字符
[]  方括号中的字符匹配任意一个
\   转移元字符
上面的都是支持egrep和grep
\(\)  类似js的组,如'\(app\).*\1'匹配两个app之间的任意数目字符。g
\n  重复再\(和\)内的第n个模式,n为1-9 .g
x\{m,n\} 匹配x字符m-n次 g
x{m,n} 同上 eg
+   匹配前一个表达式最少一次 eg
?   匹配前一个表达式0-1次 eg
|  匹配 | 前面或后面的正则表达式 eg
() 匹配括号括起来的正则表达式群 eg

grep支持的附加
\< 匹配指定单词开头的行
\> 匹配指定单词结尾的行
\w 字母和数字
\b 单词分界符
5.数组
1.数组定义

arr=(v1 v2 v3)
echo ${arr[*]} 所有元素 或使用@
arr=([1]=a [2]=b [3]=c)

2.修改或赋值

arr[1]=aa

3.动态定义

arr=($(命令))
arr=(命令)

4.数组个数

echo $(#arr[@])

5.列出数组索引

v=(1 2 3);v[9]=9;echo ${!v[*]}

6.关联数组,即索引可以使用字符串

必须声明: declare -A arr
其他使用同上
arr=([apple]=12 [banana]=23)
echo ${!arr[*]}

6.常见命令
1.查看其他进程环境变量:

cat /proc/$PID/environ #这里pid是一个整数

2.查看进程id : pgrep mysql #查看mysql程序的pid,

也有些程序是有多进程的,也就是多个pid

3. tr 命令用于转换或删除文件中的字符,也可使用sed

cat testfile |tr a-z A-Z

\0此字符也作为string 的结束符。
cat /proc/12501/environ | tr ‘\0’ ‘\n’

4. 3种计算字符串长度的方式

chars=$(seq -s " " 100 )

a. echo ${#chars}
b. echo (exprlength"(expr length "chars")
c. echo ${chars} | wc -m #该结果会变上面多一,它包含了字符串结束符(\0)

5.计算时间:

a.计算某条命令或某个脚本执行时间
time 命令
b.计算shell脚本中某个函数执行时间,可以使用前后时间差统计。
start=(datedate="(date --date="s" +%s)
配合%N能计算纳秒,当然也可计算毫秒了
date +%s.%N
配合bc计算器:
result=$(printf “%.2f” $(echo “scale=2;1.23-1.11”|bc)) #scale是小数位数,printf保证前置零不丢失。

6.数值计算: (()) , let, expr, bc , $[]

a. (())常用,但是只能计算整数
常见的一些运算符都可以在其中使用
v=4;((v++));echo $v; #结果5
((v=1*5+2));echo $v; #结果为7

b. let 赋值表达式,效率没有双括号高
i=2;let i=i+8 ;echo $i ;#结果为10

c. expr:除了数值计算,它内部提供了一些函数
expr 2 * 2 ;特殊字符需要转义。
expr 2 + 2

d. bc计算器 ,可以指定小数位数。
v=1;echo v+1.2bc;2.1;result=v+1.2 |bc ; 2.1; result=(printf “%.2f” $(echo “scale=2;1.23-1.11”|bc))

e. []v=1;a=2;result=[] v=1;a=2;result=[ v+a ]
[]使[]里面也可使用, v=1;a=3;result=$[ $v+a ]

7.获取用户输入:read

-p: prompt设置提示信息b
-t: timeout 设置输入的等待时间
-s: 静默模式,不会回显
-a 后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符

read -t 3 -p “请输入两个数:” v1 v2

8.设置时间date,ntpdate

date -s “2019-06-28 09:00:00” #设置系统时间,shell登出退出后仍能起作用。

9.配置限制进程文件

/etc/security/limits.conf 中nproc来限制可生产的最大进程数

10.保留空格和换行符:

echo (cat1.txt)echo"(cat 1.txt)不会保留换行符 需要: echo "(cat 1.txt)"

11.空命令 “:”

没有任何效果,什么都不做。类似python中的pass,永远成功,退出状态0
所以常用他来替代true,资源利用率比true好。
repeat() {
while :
do
echo 1
sleep 2
done
}

12 IFS,内部字段分隔符,处理文本数据时候有用。

#!/bin/bash
data=“name,gender,age,location”
oldIFS=$IFS
IFS=,
for item in $data
do
echo item: itemdoneIFS=item done IFS=oldIFS
输出:
item: name
item: gender
item: age
item: location

13.cat命令

a.)单文件
cat filename
b.) 多文件
cat file1 file2
c.) 管道
echo 1 | cat
而且还可以合并文件和标准输出
echo “test” | cat - file.txt

-s:去掉多余空白行(tr命令也可以)
-T:将制表符显示为 ^I
-n:显示行号,配合-b可以跳过空白行,行号不会重排。

14 find用来查找文件是非常有用的,基于通配符,正则表达式,可以设定目录树深度,文件日期,文件类型等条件

a) -name:指定文件名的形式 , -iname忽略大小写。
find / -name ".js" -print
b) -a -and , -o -or ,可以使用逻辑操作
find / (-name '
.js’ -o -name ‘*.html’ ) -print

c) -path限制所匹配文件的路径
find / -path ‘/web/’ -name ‘*.html’ -print; 这样路径中必须包含/web/了
d) -regex ,-iregex使用正则表达式 (2.4.31)

e)排除模式: !
find / !-name “*.txt” 匹配以非txt结尾的。

f) -maxdepth , -mindepth指定目录深度
他们应该及早出现在find命令中出现,如果作为靠后的选项可能会影响find的效率。

g) 根据文件类型
find / -type d
常见的:f , l , d,c,b,s,p(FIFO)

h)重要的,按照文件的时间进行搜索
atime: access time,用户最近一次访问文件时间
mtime: modify time ,用户最近一次修改文件内容时间
ctime: change time , 文件元数据(如权限和所有权变更)最后一次变化时间
+表示大于,-表示小于。
find . -maxdepth 1 -type f -atime -1 ;访问时间小于一天的(一天之内),
find . -maxdepth 1 -type f -atime +1 ;一天前访问过的。

同时find命令还支持以分钟为计时单位,
-amin: 访问时间 
-mmin: 修改时间 
-cmin: 改变时间
和上面三个对应,只不过计时单位不同。

i) 基于文件大小的搜索
find . -type f -size +2k #大于2k
find . -type f -size -2k #小于2k
find . -type f -size 2k #等于2k的文件
还有其他单位:
b: 512字节,块
c: 字节
w: 字,2个字节
k: 千字节
M: 1024k
G: 1024M

o) 基于文件权限和所有权的匹配
find . -type f -perm 644; 权限是644的
同时可以设置反向过滤
find . -type f ! -perm 644; 权限不是644的

同时还有-user,-group等指定用户组,用户的。

p) 删除文件,find查找到文件,还可以删除
find . -type f -name “*.swp” -delete;他会删除匹配到的文件。

q) 匹配的文件可以执行其他命令
find . -type f -name “*.sh” -exec chown 755 {} ;
后面的{} ;是固定格式。;是命令结束的意思,\做转义。
find命令会将{}替换成相应的文件名。
-exec 后只能跟一条命令,所以为了实现多命令
可以吧命令写在脚本中, 然后: -exec ./youscript.sh {} ;

r) 让find跳过特定的目录或文件:在截取的时候,-print不能忽略,否则结果可能不正确。
find . -name ‘.git’ -prune -o -type f -print;忽略.git目录
find /root/myscripts -name ‘1.txt’ -prune -o -name “1*” -print

15.xargs命令应该紧跟管道命令之后,它使用标准输入作为主要的数据源,

将从sdtin中读取的数据作为指定命令的参数并执行。
a.)多行可以转一行
cat 1.txt | xargs
b.)多行转指定行
cat 1.txt | xargs -n 3
c.)切割
echo “splitXsplitXsplitXsplitX” | xargs -d X
split split split split

16.tr (translate)将一组字符转换成另一组字符

tr [options] set1 set2
来自 stdin 的输入字符会按照位置从 set1 映射到 set2 ( set1 中的第一个字符映射到 set2
中的第一个字符,以此类推),然后将输出写入 stdout (标准输出)。 set1 和 set2 是字符类或字符组
echo ‘hello world’ | tr ‘a-z’ ‘A-Z’ ;结果HELLO WORLD

a)使用 -d删除字符
cat file | tr -d “0-9” ;从管道里面传进来的文本删除数字。

17. at:单一时刻执行一次任务,atq:查询待执行的队列
18.定时任务
          • command
            分钟 0-59
            小时 0-23
            日 1-31
            月 1-12
            星期 0-7 ,0和7都是星期日
            crontab -e 添加定时任务。
            如果里面涉及到路径,必须使用绝对路径
19 ping命令

-q 不显示任何信息,只显示结果
-c 总次数,发几次包
-i 时间间隔
-W 大写的w,超时时间 秒。
ping -W 2 -c 3 -q www.baidu.com

20 shell的并发

while read line
do
{
command 1
} &
done

command 2
使用 {}&并发,使结果快多了,但是同时cpu在短时间也会飙升。

21 jobs查看当前工作(包括stoped),配合fg和bg
22 设置开机启动:

chkconfig 服务名 on
chkconfig mysqld on

23 mysql shell免密登录

在家目录下配置my.cnf文件里面填写password字段
给该文件chmod 400 权限。只有该用户有权限读。

7.变量子串和特殊扩展变量
1. 变量子串:

表达式 说明
parameter{parameter} 返回变量parameter的内容
KaTeX parse error: Expected '}', got '#' at position 2: {#̲parameter} …parameter内容的长度(按字符),也使用与特殊变量
parameter:offset{parameter:offset} 返回变量{parameter}中,从位置offset之后开始提取子串
${parameter:offset:length} 从offset开始,提取长度length的子串
${parameter#word} 从开始删除最短匹配的word子串
${parameter##word} 从开头开始删除最长匹配的word子串
${parameter%word} 从结尾开始删除最短匹配的word子串
${parameter%%word} 从结尾开始删除最长匹配的word子串
${parameter/pattern/string} 使用string代替第一个匹配的pattern
${parameter//pattern/string} 使用string代替所有匹配的pattern

2.特殊扩展变量:

${parameter:-word}
如果parameter变量值为空或未赋值,则返回word字符串作为返回值
${parameter:=word}
如果parameter的变量值为空或未赋值,则设置该变量值为word,并返回该值
${parameter:?word}
如果parameter的变量值为空或未赋值,那么word字符串将为作为标准错误输出,否则输出变量的值。
${parameter:+word}
如果parameter的变量值为空或未赋值,则什么都不做,否则word字符串将替代变量的值。