shell版本
# 输出当前系统执行的 shell 版本
echo "$SHELL:$BASH_VERSION"
字符串操作
#获取文件名
filepath= "/home/youname/shell/gotfilename/bin/demo.apk"
name= `basename $filepath .apk` # demo
name= `basename $filepath` # demo.apk
path= `dirname $filepath` # /home/youname/shell/gotfilename/bin/
name=${filepath##*/}
suffix=${filepath##*.}
path=${filepath%/*}
# #从左边截取(##最大限度从左边截取)
# %从右边截取(%%最大限度从右边截取)
# 获取字符串长度
len=${#str}
#去除单引号
$(echo "$str" | sed $'s/\'//g')
#截取指定字符串 (用法为 -cx-y 这个意思是取得第x至第y个字符串 )
echo "$info" | cut -c2-6
#分割字符串 (-d代表用什么进行分割,-f2代表要第2个结果 )
echo $b | cut -d "," -f2
#去除空格
echo ${str// /}
echo $str | sed 's/ //g'
echo $str | tr -d " "
[[ $a == z* ]] # 如果$a以"z"开头(模式匹配)那么将为true
[[ $a == "z*" ]] # 如果$a等于z*(字符匹配),那么结果为true
格式 |
说明 |
${string: start :length} |
从 string 字符串的左边第 start 个字符开始,向右截取 length 个字符。 |
${string: start} |
从 string 字符串的左边第 start 个字符开始截取,直到最后。 |
${string: 0-start :length} |
从 string 字符串的右边第 start 个字符开始,向右截取 length 个字符。 |
${string: 0-start} |
从 string 字符串的右边第 start 个字符开始截取,直到最后。 |
${string#*chars} |
从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。 |
${string##*chars} |
从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。 |
${string%*chars} |
从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。 |
${string%%*chars} |
从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。 |
日志操作
# 输出日志到指定的文件 并刷新文件
> log.txt
>> log.txt # 以增补的形式输出到指定的文件
#|grep --line-buffer package 日志过滤
# 运行日志的拦截
log= $( cmmond|tail -1|grep --line-buffer package )
echo $log #无换行
echo "$log" #带换行
# 变量中的内容按行输出
# 1 开子进程
line_count=0
echo "$info" | while read line
do
echo $line
line_count=$(expr $line_count + 1)
echo "这是第${line_count}行"
# break
done
# 2 同进程
while read line
do
#匹配包名
if [[ "$line" == package* ]]
then
echo "$line"
fi
# break
done < "$info"
AAPT
#获取apk 声明
aapt dump badging filepath
grep
# 过滤条件
# -e 或者
grep -e META-INF -e RSA
grep -E '123|abc' filename // 找出文件(filename)中包含123或者包含abc的行
egrep '123|abc' filename // 用egrep同样可以实现
awk '/123|abc/' filename // awk 的实现方式
# 多个条件
grep META-INF | grep -e RSA
# 其他特殊要求
grep -i pattern files //不区分大小写地搜索。默认情况区分大小写,
grep -l pattern files //只列出匹配的文件名,
grep -L pattern files //列出不匹配的文件名,
grep -w pattern files //只匹配整个单词,而不是字符串的一部分(如匹配‘magic’,而不是‘magical’),
grep -C number pattern files //匹配的上下文分别显示[number]行,
目录
#列出指定目录
ls -l "$path" |awk '/^d/ {print $NF}'
#查找文件
find / -name "filename"
版本号比对
# 大于
function version_gt() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; }
# 大于等于
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
# 小于
function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }
# 小于等于
function version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" == "$1"; }
文件
# 获取文件大小
du -sh "$1"
# 创建目录
mkdir aaa
# 递归创建目录
mkdir -p aaa/bbb/ccc
# 批量创建目录
mkdir -p dir/{a,b,c,d}/src
引号 ('' "" )
- 由单引号' '包围的字符串:
- 任何字符都会原样输出,在其中使用变量是无效的。
- 字符串中不能出现单引号,即使对单引号进行转义也不行。
- 由双引号" "包围的字符串:
- 如果其中包含了某个变量,那么该变量会被解析(得到该变量的值),而不是原样输出。
- 字符串中可以出现双引号,只要它被转义了就行。
- 不被引号包围的字符串
- 不被引号包围的字符串中出现变量时也会被解析,这一点和双引号
" "
包围的字符串一样。
- 字符串中不能出现空格,否则空格后边的会作为其他变量或者字符串解析。
算术
#!/bin/bash
count=0
until [[ $count > 4 ]]; do
count=$[count + 1]
sleep 1
done
echo $count
# expr 对表达式的格式有几点特殊的要求:
# 出现在表达式中的运算符、数字、变量和小括号的左右两边至少要有一个空格,否则会报错。
# 有些特殊符号必须用反斜杠\进行转义(屏蔽其特殊含义),比如乘号*和小括号(),如果不用\转义,那么 Shell 会把它# 们误解为正则表达式中的符号(*对应通配符,()对应分组)。
# 使用变量时要加$前缀。
a=100;b=101; echo `expr $a + $b`
# (())
a=$((10+11)); echo $a; #21
((a=11*12));echo $a; #132
#在使用(())时,变量无需加上$前缀,(()) 会自动解析变量名,这使得代码更加简洁
((a=3+5, b=a+10)); echo $a $b; # 8 18
# (()) 支持逻辑运算
echo $((8==8)); # 1
# let
a=1 b=7 ;let a+=1 c=a+b;echo $a $c # 2 9
# $[]
# !!!!!!不能单独使用 $[],必须能够接收 $[] 的计算结果
echo $[3*5];#15
a=1 b=7 ; echo $[4*(m+n)]# 36
# declare -i 声明为数字类型 仅支持最基本的数学运算(加减乘除和取余)
declare -i m n ret
BC
// An arbitrary precision calculator language
// 一款任意精度的计算器语言
echo "10/(3+2)-2+(2+4)*8"|bc #48
n=`echo "3+4*(5-2)-10/3"|bc`;echo $n #12
# scale 精度,默认0
n=`echo "scale=3;3+4*(5-2)-10/3"|bc`;echo $n # 11.667
# obase 输出进程
n=`echo "ibase=16;scale=3;3+4*(5-2)-8/3"|bc`;echo $n # 12.334
test
# test 命令也可以简写为[],它的用法为
[$a>$b]
#注意[]和expression之间的空格,这两个空格是必须的,否则会导致语法错误。
#[]的写法更加简洁,比 test 使用频率高
#(()) 支持各种运算符,写法也符合数学规则,用起来更加方便,几乎完全兼容 test .
case
case expression in
pattern1)
statement1
;;
pattern2)
statement2
;;
pattern3)
statement3
;;
……
*)
statementn
esac
注意点:
- 赋值号=的周围不能有空格,这可能和你熟悉的大部分编程语言都不一样。
- 变量名由数字、字母、下划线组成;
- 必须以字母或者下划线开头;
- 不能使用 Shell 里的关键字(通过 help 命令可以查看保留关键字)
- 为了防止出现格式混乱的情况,在输出变量时加上双引号。
- $()仅在 Bash Shell 中有效,而反引号可在多种 Shell 中使用
declare
选项 |
含义 |
-f [name] |
列出之前由用户在脚本中定义的函数名称和函数体。 |
-F [name] |
仅列出自定义函数名称。 |
-g name |
在 Shell 函数内部创建全局变量。 |
-p [name] |
显示指定变量的属性和值。 |
-a name |
声明变量为普通数组。 |
-A name |
声明变量为关联数组(支持索引下标为字符串)。 |
-i name |
将变量定义为整数型。 |
-r name[=value] |
将变量定义为只读(不可修改和删除),等价于 readonly name。 |
-x name[=value] |
将变量设置为环境变量,等价于 export name[=value]。 |