前言:
shell是一种命令行解释器,是Unix操作系统下最传统的人机接口。
确认当前终端使用的shell类型
$ echo $0
bash
// 本文基于bash 3.2来练习
$ bash
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
bash-3.2
// Macos 还提供了其他类型的shell
$ ls -ls /bin/*sh
/* 1360 -r-xr-xr-x 1 root wheel 1296640 1 1 2020 /bin/bash
1040 -rwxr-xr-x 1 root wheel 1104640 1 1 2020 /bin/csh
224 -rwxr-xr-x 1 root wheel 277408 1 1 2020 /bin/dash
2720 -r-xr-xr-x 1 root wheel 2552352 1 1 2020 /bin/ksh
16 -rwxr-xr-x 1 root wheel 120912 1 1 2020 /bin/sh
1040 -rwxr-xr-x 1 root wheel 1104640 1 1 2020 /bin/tcsh
1464 -rwxr-xr-x 1 root wheel 1331248 1 1 2020 /bin/zsh */
// 交互式登录和非登录shell --login之后会显示当前用户
$ bash --login
一. Shell初探与注意事项
// 打印提示符
$ echo $PS1
\s-\v\$
// 给website设置值
$ read website
cat
// 打印website
$ echo $website
cat
双引号中除了 "$" "" "`(反引号)" 有特殊含义,其余符号并无特殊含义
单引号功能与双引号类似,不过所有单引号都无特殊含义
文件中搜索api命令
// 第一种方式
$ grep weak test.m
// 第二种方式 在test.m文件中搜索关键api
$ grep "weak" test.m
// 第三种方式
$ nm -pa test | grep "weak"
// 注意shell命令中会把 空格 分隔成两个命令
$ grep weak --color=auto -- ../Common\ Symbol/test.m
二. 标准输出&输入&错误
将标准输出重定位到一个文件中
// 标准输出(stdout):代码为1,使用>或>>;
// 把LGCat写入 Cat文件
$ echo "LGCat" > Cat
// 查看Cat文件内容
$ cat Cat
LGCat
// 1> 以覆盖的方式将正确的数据输出到指定到文件或设备;
// 1>> 以累加到方法将正确到数据输出到指定到文件或者设备上;
$ echo "123456" >> Cat
$ cat Cat
LGCat
123456
|:管道仅能处理前面一个命令传来的正确信息,将正确信息作为stdin传给下一个命令
(减号)- :stdin和stdout利用减号“-“来代替
三. 三种运行方式
- 第一种方式 ./build.sh 或者 sh build.sh
在当前终端shell下面派生出一个子 shell来执行,子shell执行完成回到当前终端shell,此时子shell 就会销毁
缺点:子shell中创建的变量,在子shell执行完成会丢失 - 第二种方式 source build.sh
不会开启子shell,直接在当前终端shell执行,创建的变量不会丢失 - 第三种方式 exec build.sh
开启子shell之后,会替换当前终端shell进程
关于三种执行方式的权限问题:
sh/ bash/ zsh/ source 不需要执行权限
./build.sh exex build.sh 需要有执行权限
四. 变量与函数的定义与使用
4.1 变量的使用
shell变量分为两种:
局部变量,在创建它们的shell中可用,在函数内定义,函数执行完成就删除
环境变量:在创建它们的shell以及派生出来的任意子shell中都可用,例如export(导出符号) a b=3,a b 就是一个环境变量
shell 变量默认是字符串,默认的数值运算是整数类型
// 编写脚本tesh.sh文件
expr 3+4
expr 3 + 4
RESULT=`expr 3 + 4`
echo $RESULT
echo ${RESULT}
// 执行之后输出内容
3+4
7
7
7
declare/typeset [-aixrp] 变量
-a 将变量定义成数组
-i 将变量定义成整数
-x 将变量定义成环境变量
-r 将变量定义成readonly
-p:显示变量定义的方式和值
+:取消变量属性,但是 +a 和 +r 无效,无法删除数组和只读属性,可以使用unset删除数组,但是 unset 不能删除只读变量。
// 使用空格来区分参数
set 11 22 33 44
echo $1 //就代表第一个参数 11
echo "$#" //$#代表参数个数
echo "$@" //$@代表全部参数
eval echo "\$$#" //取最后一个参数 扫描两遍 第一次是 $4 第二次是44
4.2 函数的使用
有function可以不加(),没有function必须加()
函数名和”{“之间必须有空格。
function 函数名 {
函数体
}
// 或者
函数名 () {
函数体
}
function dowork {
local LG_Cat="LG_Cat" // local 表示LG_Cat只在函数体有效,不加local 就意味着是环境变量,外面也可以访问
echo "$1"
return 0 //表示函数返回true
}
dowork 123
echo "$LG_Cat"
// 打印
123
五. 参数扩展
参数扩展:通过符号$获得参数中存储的值。
1. 间接参数扩展${!parameter},,zsh不支持
i. ${parameter-string}:当parameter未设置则替换成string,不更改parameter值。否则,不做处理。
ii. ${parameter=string}:当parameter未设置则替换成string,更改parameter值。否则,不做处理。
iii. ${parameter?string}:parameter没有设置,则把string输出到标准错误中。否则,不做处理。
iiii. ${parameter+string}:当parameter为空的时替换成string。否则,不做处理。
2. 冒号后面跟 等号,加号,减号,问号(⚠不能有空格):
i. ${parameter:-string}:当parameter未设置或者为空则替换成string,不更改parameter值。
ii. ${parameter:=string}:当parameter未设置或者为空则替换成string,更改parameter值。
iii. ${parameter:?string}:若变量parameter不为空,则使用变量parameter的值。
若为空,则把string输出到标准错误中,并从脚本中退出。
iiii. ${parameter:+string}:当parameter不为空的时替换成string。若为空时则不替换或者说是替换空值。
3. 子串扩展:${parameter:offset}和${parameter:offset:length}。
从offset位置开始截取长度为length的子串,如果没有提供length,则是从offset开始到结尾。
i. offset可以是负值,且必须与冒号有间隔或者用()包裹。开始位置是从字符串末尾开始算起,然后取长度为length的子串。
例如,-1代表是从最后一个字符开始。
ii. parameter是@,也就是所有的位置参数时,offset必须从1开始。
4. 替换:${parameter/pattern/string}、${parameter//pattern/string}、${parameter/pattern}和${parameter//pattern}。
大小写敏感。string为空时,则相当于将匹配的子串删除。 parameter之后如果是/,则只匹配遇到的第一个子串;
parameter之后如果是//,则匹配所有的子串。
5. 删除:${parameter#pattern}、${parameter##pattern}、${parameter%pattern}和${parameter%%pattern}。
i. # 是去掉左边,% 是去掉右边。单一符号是最小匹配﹔两个符号是最大匹配。
6. 参数长度:${#parameter}
六. test与判断
[]:判断符号,两个等号和一个等号,效果类似。
1. 中括号里面的每个组件都需要空格分隔。
2. 中括号的变量,使用双引号
3. 中括号的常量,使用单引号或双引号
if [ true ]; then
fi //if语句结束
七. 循环
当条件成立,就进行循环:
while [ condation ] #判断条件
do #循环开始
程序
done #循环结束
当条件成立,就终止循环:
until [ condation ] #判断条件
do #循环开始
程序
done #循环结束
按照指定次数循环:
for var in con1 con2 con3 ...
do
程序
done
for (( 初始值; 限制值; 执行步长 ))
do
程序
done
网友评论