Shell定义
Shell(Unix Shell)
是一种命令行解释器,是Unix操作系统下最传统的人机接口。 Shell脚本是解释执行的,不需要编译,和大部分的编程语言很相似,也有基本的变量和流程控制语句。
shell是一种胶水语言, 把命令放在一起, 来按顺序执行. 我们平时使用Shell有两种方式:
- 输入命令,执行,这种方式称为交互式(Interactive);
- 批处理(Batch)方式,用户事先写好Shell脚本文件,然后顺序执行脚本中的命令。
终端演绎
- echo $0 -> 查看默认终端
- echo -> 终端打印
- -zsh -> 有
-
-> 登录的, Shell有基于用户, 有时候会用到签名所以需要登录 - zsh -> 没有
-
-> 没有登录的- login -> 输入电脑账号/密码就可以登录
- ls -ls /bin/sh -> 查看当前电脑所有已经安装的Shell
- 因为后来的Shell都是基于最初的sh来做兼容进化的, 所以我们学习的话,是基于sh/bash3.2来做研究的.
Shell环境变量配置建议
- bash:
- 将配置选项放到/.bashrc中,然后在/.bash_profile中通过source调用。
- zsh:
- 建议仍然将配置选项放到/.bashrc,/.bash_profile中通过source调用,最后在/.zshrc中source调用/.bash_profile。
- 编译行语言 -> 修改了需要重新走编译流程
- 解释性语言(js/jason/python/shell) -> 中间出错, 不影响后面代码运行
如何学脚本
- 学语法
- 看脚本
- 抄(最重要的-_-!)
Visual Studio Code的注意事项
- 点击.sh
- 点击右下角Shell Sript -> 搜索Shell -> 点击
- 以上操作可以将文件里面的表现形式改为Shell
自定义代码块
- Code -> Preferences -> User Snippets
- 选择要写的代码类型 -> 例如Shell
-
添加代码块(json格式的)
- $0 -> 占位符
Shell初探与注意事项
- #!bin/bash -> Shell开头的固定写法, 详细看上面Shell初探与注意事项.sh文档
- echo $PS1 -> 查看Shell的命令前面的提示符 -> 是一种固定写法 -> 更改其他写法后, shell命令前面的提示会相应的发生变化 -> 解析行语言
-
read ->
- 单#开头的 -> 单行注释
- 多行注释 -> 查看文档Shell初探与注意事项.sh -> 主要用于给比人解析一个概念时有用到
- 也可以单行注释多谢几行
- 双引号 -> 用于字符串 -> 避免引起歧义的 -> 其实通常情况下,加不加一样
- 字符串里有特殊符号 -> 就可以用到双引号
- 单引号跟双引号类似, 但所有字符都没有特殊含有 -> 查看文档Shell初探与注意事项.sh
- echo 'I am
echo SuperYann
' -> I amecho SuperYann
- echo 'I am
- 反引号`` -> 通常是命令行, 程序会优先执行反引号中的内容,并替换
- echo "I am
echo SuperYann
" -> I am Super Yann -> 先执行 I am -> 再到 Super Yann - 不要忘了Shell的执行顺序, 从上到下, 从左到右依次执行
- echo "I am
- echo 输入默认换行(Visual Studio Code中)
- echo -n -> 不换行
- 字符打印还支持特效(在终端中)
- 特殊符号与使用.sh
find_api.sh
- cd到目标文件夹
- grep weak test.m -> grep (要搜索的关键字) (要搜索的文件)
- grep "weak" test.m
- 搜索可执行文件 -> 查找可执行文件的符号表
- nm -pa test | grep "weak"
- find_api.sh -> grep weak --color=auto -- ../Common\ Symbol/test.m
- grep weak --color=auto -- "../Common Symbol/test.m"
- -- -> 代表没有参数要传了, 后面只能跟文件
- shell是通过空格来分割参数的
- 错误写法 -> grep weak --color=auto -- "../Common\ Symbol/test.m"
- 错误写法 -> grep weak --color=auto -- '../Common\ Symbol/test.m'
标准输出&输入&错误.sh
- read website -> 进入标准输入状态
- SuperYann -> 输入后回车,结束该状态
- 进入标准输出&输入&错误.sh -> 终端直接拖拽 -> 回车
- 有错误 -> 因为名字中有特殊字符,需要转义符来声明一下\
- echo "LGSuperYann" > SuperYann -> 将一个标准输出,重定位到一个文件中
- cat SuperYann
- > -> 覆盖 -> echo "LGSuperYann1234" > SuperYann
- >> -> 累加 -> echo "LGSuperYann456" >> SuperYann
- man cat -> 查看cat定义 -> cat 后面如果没有参数, 则进入标准输入模式
- ctrl + d -> 终止
- cat > Cat1237(新的文件) -> 输入后 -> 退出 -> cat Cat1237
- cat > Cat1237 << "cat"(结束输入) -> 这种写法, 最后输入相应的结束字符,就可以结束 -> 日常开发 -> cat > Cat1237 << "eof"
- tty -> 查看当前终端xcode_run_cmd
- &>$TTY -> 将标准输出和错误,都重定位到终端
- ; -> 用来分割两个命令,代表连续执行
- 当前一个命令执行成功会回传一个 $?=0的值。
- echo "cat" -> echo $? -> 0,代表执行成功
- e -> echo $? -> 123(随机值) -> 执行失败
- cmd1 && cmd2 如果第一个命令的$?为0,则执行第二个命令。
- md1 || cmd2 如果第一个命令的$?为0,则不执行第二个命令。否则执行第二个命令。
- |:管道仅能处理前面一个命令传来的正确信息,将正确信息作为stdin传给下一个命令。
- otool -l test | grep 'DYLIB' -A 3 -i -
- 管道命令只处理前一个命令正确输出,不处理错误输出;
- 管道命令右边命令,必须能够接收标准输入流命令才行;
- 大多数命令都不接受标准输入作为参数,只能直接在命令行输入参数,这导致无法用管道命令传递参数。
- echo "Cat1237" | cat
- echo "Cat1237" | xargs cat -> xargs:是将标准输入转为命令行参数
- :减号在一些命令中表示从标准输入(stdin)中获取内容
三种运行方式
- shell也是有进程,以及子shell的
- 运行方式:
- sh:使用
$ sh script.sh
执行脚本时,当前shell是父进程,生成一个子shell进程,在子shell中执行脚本。脚本执行完毕,退出子shell,回到当前shell。$ ./script.sh
与$ sh script.sh
等效。也叫fork方式 - source:使用
$ source script.sh
方式,在当前上下文中执行脚本,不会生成新的进程。脚本执行完毕,回到当前shell。$ . script.sh
与$ source script.sh
等效。不需要有"执行权限" - exec方式:使用exec ./scriptsh方式,会用command进程替换当前shell进程,并且保持PID不变。执行完毕,直接退出,不回到之前的shell环境。
- sh:使用
- 是否需要权限:
- sh /bash/zsh不需要有"执行权限"
- ./script.sh需要有"执行权限"
- source script.sh不需要有"执行权限"
- exec需要有"执行权限"
变量与函数的定义与作用
- 函数函数.sh
- function DoWork {} -> 注意空格
- 返回值 -> 只能是整数, 0代表成功,失败返回其他整数 -> 不写默认返回上一条的命令的执行结果
- 在shell中定义的变量, 默认是全局变量
- 如果申明局部变量 -> local
- 变量的定义变量的定义.sh
- 因为Shell空格敏感
- expr 3+4
- expr 3 + 4
- 更多例子, 请查看变量的定义.sh
- vim ~/.bashrc
-
所以我们的终端配置环境变量时,
- echo $PATH -> 查看配置的环境变量
- set 11 22 33 44
- echo 2 4
- echo "$#" -> 参数个数
- echo "$@" -> 输出全部参数
- eval echo "$$#" -> 拿到最后一个参数 -> #$5 -> #55
- 注意上面的完整写法 eval echo "$$#" -> 此处出问题也是因为Shell的执行顺序是从左往右
05 参数的扩展
06 test与判断
07 循环
实战Shell
写一个Shell思考两点:
- 命令如何来执行
- 执行的命令到底是哪一个 -> -v
- 错误信息, 自己控制输出
实战操作探寻
- touch shell.sh
- #!/bin/sh
- 运行命令达到输出的效果
- echo "$@"
- sh shell.sh 12 23 34 -> 执行Shell,有点像去执行一个函数
- "echo "$@"" -> 执行报错
- eval "echo "$@"" -> eval,扫描两边,可以执行成功
- RunCommand() { "$@" &>文件 } -> 最后输入的位置可以是文件路经,也可以是终端
- 想看到命令执行时的详细信息 -> 函数里面写个echo来打印一下
- 并不是任何时候都需要打印的, 建议写个变量判断一下, 有需要才打印
- 以后写模板的参考 RunCommand/Echoerror
总结
- Fluter编译原理的脚本注释, 要拿到xcode_build.sh