shell
2021/7/26 7:37:51
本文主要是介绍shell,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
source filename 与 sh filename 及./filename执行脚本的区别
- 当shell脚本具有可执行权限时,用
sh filename
与./filename
执行脚本是没有区别得。./filename
是因为当前目录没有在PATH中,所有”.”是用来表示当前目录的。 sh filename
重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。source filename
:这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。
单引号和双引号和反引号``
单引号和双引号用于变量值出现空格时将字符用引号括起来。 二者的主要区别在于,
被单引号括起来的字符都是普通字符,就算特殊字符也不再有特殊含义;
被双引号括起来的字符中,"$"、"“和反引号是拥有特殊含义的,”$"代表引用变量的值,而反引号代表引用命令。
反引号
如果需要调用命令的输出,或把命令的输出赋予变量,则命令必须使用反引号包含,这条命令才会执行,反引号的作用和 $(命令) 是一样的。命令如下:
if 条件判断
注意事项:
[ $yn = “y” ] 位置的空格,和其他语言相差巨大,如果没有空格就会报错
#!/bin/bash echo "please input y or n" read yn if [ $yn = "y" ]; then echo "yes" else echo "no" fi # 判断A中是否包含B字符串。注意空格,否则语法错误。 A="helloworld" B="low" if [[ $A == *$B* ]] then echo "包含" else echo "不包含" fi
find查找文件
# find本身默认是递归查找 find ./ -type f # 查找当前目录的所有文件,包括子目录里的文件,但是目录不算 find ./ -type f -name "test*" # 查找文件名test开头的文件,f 所有文件,-name 按照名字查找
find结合xargs
# 查找所有图片并复制到指定文件夹, find ./ -name "*.pgm" |cp `xargs` ./picture #下面会删除picture这个文件夹的 rm -rf ./picture/ && mkdir picture && find ./output/ -name "*.pgm" |cp `xargs` ./picture
grep 分离想要的和不想要的
例子
grep -n "echo" copymodel.sh #在指定的文件下查找想要的内容 grep -rn "echo" ./ #可以是文件夹,文件夹必须加上-r表示递归,否则报错。 grep -rvn "echo" ./ #-v表示不想要echo,只要没有这个字符串都显示出来。
查找指定字符的下一行行 -A
adb shell dumpsys media.camera | grep -A 1 "android.sensor.frameDuration" # man grep 看到 -A -B -C 就知道了
与操作
grep同时匹配多个关键字,同时匹配str1、str2和str3
grep ‘str1’ filename | grep ‘str2’ | grep ‘str3’
1
或操作
grep匹配任意关键字
grep -E ‘str1|str2|str3’ filename
1
egrep实现
egrep ‘str1|str2|str3’ filename
1
awk实现
awk ‘/str1|str2/str3/’ filename
1
其他操作
grep -i pattern filename #不区分大小写地搜索。默认情况区分大小写。
grep -l pattern filename #只列出匹配的文件名。
grep -L pattern filename #列出不匹配的文件名。
grep -w pattern filename #只匹配整个单词,而不是字符串的一部分(如匹配‘magic’,而不是‘magical’)。
sed 擅长过滤一下在做其他处理
其他的处理:比如打印、替换,删除等
sed -n '/echo/p' test.sh # echo过滤的内容,p是打印的意思。-n:取消默认输出,如果没有-n它会先把文件内容打印出来,在把 echo 打印出来。 # 一般来讲需要加上-n sed -n '/echo/d' test.sh # d删除的意思 #替换 #s表示字符串查找并替换,g表示全局范围,还可以替换第几列可以选择。#是分隔符可以用/或者@都可以。 sed "s#ab#12#g" test.sh # 将ab替换为12,注意单引号和双引号的区别 sed "s#ab#$PATH#g" test.sh #替换为环境变量的内容,但是没有真正的替换,先看一下替换后的效果,只是输出返回值,没有赋值 sed -i "s#ab#$PATH#g" test.sh #-i是真正意义上的替换,
awk
用途:以列为单位将一行数据分隔成数个“字段”来处理 awk ‘条件1{动作1} 条件2{动作2} ...’ filename
echo 追加文件内容
清空文件添加内容。
echo "# abc" >test.sh # 小心:这个会先清空文件在添加内容
追加文件内容
echo "# abc" >> test.sh
管道和重定向
重定向概念:
标准输入是我们的键盘,标准输出为命令行界面,如果我们想将标准输出改了,不输出到命令行界面了,而是输出到文件,那么这个动作就叫做重定向,意思重新改变输出数据的流向,就是重定向.不能重定向标准错误信息.因为错误的命令不可能被执行的,所以想想也知道.但是可以设置的,也可以将错误信息重定向到文件,日志文件很有用,
重定向标准输入
原来我们的标准输入是键盘,现在我们可以改变这个输入,将键盘改变为文件.比如下面这个命令,首先认清什么是标准输入,grep 不是输入,"zjw"也不是输入,而是要查找的关键字,后面的路径文件内容才是标准输入呢.
grep "zjw" < /etc/passwd grep "zjw" /etc/passwd
管道
前面的输出就是后面的输入,所以有必要清楚什么是输入,比如
ls -al | grep "test"
ls -al 输出我们知道,然后将这个输出,当成文本内容,传给了后面的输入,后面的输入就不用在写了.
grep "关键字" [标准输入,文本内容,或者文件都可以] 如果不写后面的输入,那么命令行就像scanf函数一样卡在那里,等待用户的输入,这个输入就是键盘输入
#查找并替换 find ./ -type f -name "test*"|xargs sed "s/aaa/bbb/g"
下面这个例子:
-user 是参数,按照用户名查找,2> 重定向标准错误,null 像一个垃圾桶,丢弃掉,应该是有这个文件,
find / -user "zjw" 2> /dev/null | grep Video
下面这个用法:没见过。
echo "ls; exit"|adb shell
xargs用法
下面这两个例子作用不一样,区别很大,
find ./ -name "exampl*" |xargs grep "Name" find ./ -name "exampl*" | grep "Name"
解释:
find 是查找文件的,不查找文件内部的内容的. 他的结果,我们知道比如
./Python-RVO2-master/examples 将这个作为文本内容,传给grep
而xargs 将这个文件内容作为参数传给grep ,所以结果完全不一样.
进程相关的
ps -el # 查看全部进程 ps pstree # 进程树 kill
shell脚本
这个文档比较好
http://c.biancheng.net/view/810.html
自定义变量
这些变量由用户定义。shell脚本允许我们在脚本中设置和使用自己的变量。设置变量允许您临时存储数据并在整个脚本中使用它,使得shell脚本更像一个真正的计算机程序。
用户变量区分大小写,因此变量Var1与变量var1不同。这个小规则经常让新手脚本程序员陷入困境。
使用等号将值分配给用户变量。变量,等号和值(新手的另一个麻烦点)之间不能有空格。以下是为用户变量赋值的几个示例:
a=1 # 注意之间不允许有空格,否则会报错,新手都会入这个坑。 echo $a
shell脚本自动确定用于变量值的数据类型。shell脚本中定义的变量在shell脚本的整个生命周期中保持其值,但在shell脚本完成时删除。
就像系统变量一样,用户变量可以使用美元符号来引用;如果不适用美元符号,系统将他看出字符串了。
value1=10 value2=$value1 # 注意 不能写成value2=value1 [本人批注]
反引号
#testing=`date` # 这里 date 是一个命令,可以在terminal中输入,就会出现日期 testing=$(date) # 也可以这么写, echo "date&time:"$testing
总结:
脚本中我们想要显示原来的$,需要在其前面添加反斜杠;因为脚本在引号内看到$,它就会假定您正在引用一个变量。
我么在定义变量的时候:等号和值之间不能有空格。
当引用一个变量值时使用$,但当引用变量来为其赋值时,不要使用$,否则shell会将变量名称解释为普通文本字符串。
将命令行赋值给变量:使用`(反引号字符)或者使用$()来包围命令。
如`命令`或者$(命令)。
定义数组
#!/bin/sh #==定义数组=============================================== # 在 Shell 中,用括号( )来表示数组,数组元素之间用空格来分隔。由此,定义数组的一般形式为: nums=(29 100 13 8 91 44)# 注意,赋值号=两边不能有空格,必须紧挨着数组名和数组元素。 # Shell 是弱类型的,它并不要求所有数组元素的类型必须相同,例如: arr=(20 56 "http://c.biancheng.net/shell/") # Shell 数组的长度不是固定的,定义之后还可以增加元素。例如,对于上面的 nums 数组,它的长度是 6,使用下面的代码会在最后增加一个元素,使其长度扩展到 7: nums[6]=88 # 此外,你也无需逐个元素地给数组赋值,下面的代码就是只给特定元素赋值: ages=([3]=24 [5]=19 [10]=12) #以上代码就只给第 3、5、10 个元素赋值,所以数组长度是 3。
数组元素的的获取
#!/bin/bash nums=(29 100 13 8 91 44) echo ${nums[@]} #输出所有数组元素 nums[10]=66 #给第10个元素赋值(此时会增加数组长度) echo ${nums[*]} #输出所有数组元素 echo ${nums[4]} #输出第4个元素,索引从0开始 echo $array[0] #也可以这样使用
获取数组的长度
echo ${#array[@]} echo ${#array[*]}
shell 命令的特殊符号
$0 当前脚本的文件名,带有绝对路径的文件名 $n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 $# 传递给脚本或函数的参数个数。 $* 传递给脚本或函数的所有参数。 $@ 传递给脚本或函数的所有参数。 $* 和 $@ 的区别 $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号" “包含时,都以”$1" “$2"…"$n” 的形式输出所有参数,被双引号" “包含时,”$*" 会将所有的参数作为一个整体;"@" 会将各个参数分开,以换行形式输出所有参数。 $? 上个命令的退出状态,或函数的返回值。 $$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID
Shell 函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。 shell中函数的定义格式如下: [ function ] funname [()] { action; [return int;] } 说明: 1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255 下面的例子定义了一个函数并进行调用: #!/bin/bash # author:菜鸟教程 # url:www.runoob.com demoFun(){ echo "这是我的第一个 shell 函数!" } echo "-----函数开始执行-----" demoFun echo "-----函数执行完毕-----"
for循环
#/bin/sh #============================语法1,有点像Python #!/bin/bash #for a in {1..10} #for a in 1 2 3 for a in "abc" "cde" bbb # bbb 被当成字符串了。 #for 变量 in {起始值..终止值} #这里面的起始值和终止值必须是纯数字,不能是$a,即不能是变量的值 #for 变量 in `命令` do echo $a # mkdir /datas/aaa$a # cd /datas/aaa$a # for b in {1..10} # do # mkdir bbb$b # done done #============================语法2,有点像C语言 #for ((初始值;循环控制;变量变化)) # #do # # 循环主体 # #done for (( i = 0; i < 10; i++ )); do echo $i done
read
Read可以带有-a, -d, -e, -n, -p, -r, -t, 和 -s八个选项。
-a :将内容读入到数值中
echo -n "Input muliple values into an array:" read -a array # 输入必须以空格为分界符 echo "get ${#array[@]} values in array" # 获取数组长度
adb shell settings put system screen_off_timeout 600000000 #=这个代码看不懂,是系统手机设置,有什么用?
从百度中找到了,我理解是10分钟后手机进入休眠模式。用手机试一试就知道了。
#获取屏幕休眠时间
adb shell settings get system screen_off_timeout
15000
#更改休眠时间,10分钟
C:\Users\Administrator>adb shell settings put system screen_off_timeout 600000 # 单位毫秒
3 存入一个后缀名为.cvmat文件中,目前这个文件是什么还不清楚。还有很多,有输入有输出,都是什么?
拓展:
#获取亮度是否为自动获取
C:\Users\Administrator>adb shell settings get system screen_brightness_mode
#获取当前亮度值
C:\Users\Administrator>adb shell settings get system screen_brightness
#更改亮度值(亮度值在0—255之间)
C:\Users\Administrator>adb shell settings put system screen_brightness 150
#获取日期时间选项中通过网络获取时间的状态,1为允许、0为不允许
adb shell settings get global auto_time
#更改该状态,从1改为0
C:\Users\Administrator>adb shell settings put global auto_time 0
以及获取、修改wifi状态(wifi_on)、飞行模式(airlpane_mode_on)等,这里也是appium中getNetworkConnection获得设备网络状态的方法。
字符串拼接
logfile=$1 #logfile="./log/test_performance_64bit_mode_0x2203_core7_20190909131036.log" clResult="./performence/cl_result_${logfile}.csv" a="aaa"${logfile}
monkey测试截取某两行的字符串
-
如果你只想看文件的前100行,可以使用head命令,如
head -100 filename
-
如果你想查看文件的后100行,可以使用tail命令,如:
tail -100 filename 或 tail -n 100 filename
-
查看文件中间一段,你可以使用sed命令,如:
sed -n '100,200p' filename
这样你就可以只查看文件的第100行到第200行。
截取的文件可以用重定向输入到新的文件中:
head -100 filename >a.txt sed -n '4405725,4442615p' logcat_s400.txt > w22.1_400.log sed -n '523013,646601p' ./s415/... > w22.2_415.log
函数
作用:一般用于shell内局部变量的定义,多使用在函数内部
关于局部变量和全局变量:
(1)shell 脚本中定义的变量是global的,作用域从被定义的地方开始,一直到shell结束或者被显示删除的地方为止。
(2)shell函数定义的变量也是global的,其作用域从 函数被调用执行变量的地方 开始,到shell或结束或者显示删除为止。函数定义的变量可以是local的,其作用域局限于函数内部。但是函数的参数是local的。
(3)如果局部变量和全局变量名字相同,那么在这个函数内部,会使用局部变量。
输出带有颜色
https://www.cnblogs.com/cangqinglang/p/9837126.html
格式: echo -e "\033[字背景颜色;字体颜色m 字符串 \033[0m" 或者 printf "\033[字背景颜色;字体颜色m 字符串 \033[0m" 或者 echo -e "\033[字背景颜色;字体颜色m;ascii码m 字符串 \033[0m 字符串(can null) \n" 例子:带有颜色和背景颜色 echo -e "\033[43;35m david use echo say Hello World \033[0m \n" printf "\033[44;36m david use printf say Hello World \033[0m \n" echo -e "\033[47;30;5m david use echo say \033[0m Hello World \n" 字体闪烁--牛逼 echo -e "\033[47;30;5m david use echo say \033[0m Hello World \n"
定义一个函数,使用函数进行输出。
REDCOLOR='\e[1;31m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT GREENCOLOR='\e[1;32m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT YELLOWCOLOR='\e[1;33m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT BLUECOLOR='\e[1;34m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT PURPLECOLOR='\e[1;35m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT CYANCOLOR='\e[1;36m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT NOCOLOR='\e[0m' # 使用案例:colorizeEcho $YELLOWCOLOR "Remove existing CrashDump folder on SD Card" function colorizeEcho () # 两个参数 { if [ -n "$JENKINS_BUILD_URL" ]; then # Do not use color if run as a jenkins job. echo "$2" else printf $1 echo "$2" printf $NOCOLOR fi } #
字符串处理
获取文件名
path=$1 files=$(ls $path) files=$(find ./ -name "*.mp4") # 这个方法比较好。将所有文件及子文件夹下的mp4 视频,拿出来带有路径,在处理 for filename in $files do echo $filename >> filename.txt done
字符串的拼接
在脚本语言中,字符串的拼接(也称字符串连接或者字符串合并)往往都非常简单,例如:
- 在 PHP 中,使用
.
即可连接两个字符串; - 在 JavaScript 中,使用
+
即可将两个字符串合并为一个。
然而,在 Shell 中你不需要使用任何运算符,将两个字符串并排放在一起就能实现拼接,非常简单粗暴。请看下面的例子:
#!/bin/bash name="Shell" url="http://c.biancheng.net/shell/" str1=$name$url #中间不能有空格 str2="$name $url" #如果被双引号包围,那么中间可以有空格 str3=$name": "$url #中间可以出现别的字符串 str4="$name: $url" #这样写也可以 str5="${name}Script: ${url}index.html" #这个时候需要给变量名加上大括号 echo $str1 echo $str2 echo $str3 echo $str4 echo $str5
删除字符串
#!/bin/bash name="Shell" #删除指定个数字符串 echo ${name:3} #从0开始算,第3个到最后。 输出:ll echo ${name:0-2:3} #从右面第二个开始。 输出:ll #删除左边字符串 echo ${name#*e} #删除从左面数,第一e及e左面的操作符。 #和*是运算符。 输出:ll echo ${name#*e} #删除从右面数,第一e及e左面的操作符。 #和*是运算符。 输出:ll # 删除右面字符串 echo ${name%e*} #从右面第一个e开始,搜索关键字 是e,e及右侧的字符串被删除。 echo ${name%%e*} #从左面第一个e开始,搜索关键字 是e
案例:
将aaa文件夹里面的所有文件名保存数组,然后下面的for循环针对每一个文件处理。
设置了颜色处理
#!/bin/bash REDCOLOR='\e[1;31m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT GREENCOLOR='\e[1;32m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT YELLOWCOLOR='\e[1;33m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT BLUECOLOR='\e[1;34m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT PURPLECOLOR='\e[1;35m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT CYANCOLOR='\e[1;36m' # CONTROL CODE TO CHANGE COLOR OF TERMINAL TEXT NOCOLOR='\e[0m' # 使用案例:colorizeEcho $YELLOWCOLOR "Remove existing CrashDump folder on SD Card" function colorizeEcho () # 两个参数 { if [ -n "$JENKINS_BUILD_URL" ]; then # Do not use color if run as a jenkins job. echo "$2" else printf $1 echo "$2" printf $NOCOLOR fi } # # files=$(ls aaa) # 将aaa文件夹里面的所有文件名保存数组,然后下面的for循环针对每一个文件处理。注意是不带路径的文件名 files=$(find ./ -name "*.mp4") # 这个方法比较好。将所有文件及子文件夹下的mp4 视频,拿出来带有路径,在处理 for filename in $files #这里自带文件路径了。 do echo "$filename" head=${filename%.*} # 删除从右侧数,第一个点,及点。 txtName="$head.txt" #将head保留的左侧字符,加上.txt # 处理文件 # mediainfo "./aaa/$filename" > $txtName mediainfo $filename > $txtName #http://blog.chinaunix.net/uid-10062010-id-5751344.html # 该软件的命令使用 colorizeEcho $YELLOWCOLOR "process <$filename> success to <$txtName> !" done
一次杀死所有寻找出来的线程
ps -ef | grep /bin/bash | awk '{print $2;}' | xargs kill -s 9
这篇关于shell的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-19JAVA分布式id教程:轻松入门与实践
- 2024-11-19Java高并发教程:入门与实践指南
- 2024-11-19JAVA高并发直播教程:新手入门指南
- 2024-11-19Java高并发直播教程:入门与实践指南
- 2024-11-19Java微服务教程:初学者快速入门指南
- 2024-11-19JAVA微服务教程:新手入门的详细指南
- 2024-11-19Java微服务教程:从零开始搭建你的第一个微服务应用
- 2024-11-19Java项目开发教程:初学者必备指南
- 2024-11-19Java项目开发教程:新手快速入门指南
- 2024-11-19Java项目开发教程:零基础入门到实战