0、命令行的意义:在于逻辑脚本化
1、命令行执行的脚本是shell脚本。
- shell程序(/bin/bash),其实是shell脚本引擎。。类似于python脚本之于python引擎
2、terminal 终端仿真器
- ssh程序是ssh客户端,sshd程序是ssh服务器。sshd,默认监听22。是用来远程执行shell脚本的工具。
- d程序后缀,指daemon守护进程,驻留在后台长期运行的程序,一般是CS模式中的server端程序,监听某个端口,监听客户端请求。
3、所有可执行性单元都是命令:
- 注意:
- 如果定义重复命令标识,会覆盖之前的命令。
- 命令
- 可执行程序:在系统变量$PATH中查找
- 这些可执行程序,大多是脚本。。使用shebang指定脚本解释器的位置(有bash、sh、python等等)
- 不一定都是shell脚本。也可能是python脚本等
- 所以自定义脚本,可以放到$PATH下,然后快捷访问。
- shell函数:在环境变量中查找
- alias别名:在环境变量中查找
- 可执行程序:在系统变量$PATH中查找
- 语句:除了关键字,其可执行单元,还是命令(commands)。
- 注意:
- if测试命令之后必须加then。否则无法与后面的commands断开。而else没有测试,所以没有then
- 循环体前必须加do的原因,也是断开测试和循环体。否则都是命令无法区分。
- 语句和命令的区别是:命令后面不是分号就是换行。。。语句之后只需要IFS分隔符即可
- 函数声明语句
- function funcName { commands; return } 或者 funcName() { commands; return }
- 赋值语句:注意等号两侧不得有空格
- name=value
- 分支:
- if语句:
- if commands; then
- commands
- [elif commands; then
- commands ...]
- [else commands]
- fi
- if commands; then
- case语句:
- case word in
- [pattern [| pattern]...) commands ;;]...
- esac
- 注意:
- word为一个变量【$xx】或其常量
- pattern为通配符模式【即路径展开的模式】
- 匹配多项:【;;&】表达式替换【;;】,否则默认只匹配一项
- case word in
- if语句:
- 循环:循环都是【do 循环体 done】
- while/until语句:while-until语义正好相反
- while commands; do
- commands;
- done
- while commands; do
- for传统shell形式:
- for variable [in words]; do
- commands
- done
- 注意:
- 其中words是一个展开模式
- variable是shell变量名,在循环内部以$variable来使用
- 如果省略掉 for 命令的可选项 words 部分,for 命令会默认处理位置参数
- for variable [in words]; do
- for C语言形式:
- for (( expression1; expression2; expression3 )); do
- commands
- done
- for (( expression1; expression2; expression3 )); do
- while/until语句:while-until语义正好相反
- 注意:
4、测试命令:用于if、while等逻辑表达式
- 注意:
- 操作符两侧,一定要有单词分割
- 命令的退出状态决定测试真假:
- 退出状态为0表示true。跟C语言正好相反
- test命令,测试失败,退出状态非0
- 多个命令,以最后一个为准
- 退出状态为0表示true。跟C语言正好相反
- test/[ expression ] 中所有字符都会被shell看作【命令参数】,所以有特殊意义的符号,需要转义。。。[[]]/(())则不需要
- 两种形式:
- test/[ expression ]
- 文件测试
- -e、-f、-d、-L等 存在exist、存在并且是文件File、是目录dir、是符号链接Link
- -r、-w、-x 存在并且可读r、可写w、可执行x
- -s 存在并且size>0
- 字符串测试
- string 不为null,则真
- -n、-z 长度不为0 no、长度为0 zero
- 字符串比较表达式:><=。。。其中表示相等,可用=也可用==。为统一风格,推荐==
- 整数测试
- 整数比较表达式:-eq 【equal】、-gt【greater than】、-lt【less than】等等
- 文件测试
- [[]]/(())复合命令:也是命令。更接近现代自然语言。推荐来代替 test 命令
- [[]]
- 字符串测试,支持正则表达式【=~】
- 支持展开模式的比较【==】
- (())
- 通过名字识别出变量,而不需要执行展开操作【即变量前的$可加可不加】
- 整数比较表达式:><=
- 整数运算值:非0为true,0为false【与命令退出状态正好相反】
- [[]]
- test/[ expression ]
- 结合表达式
- 多个表达式组合在一起。。
- test/ [ expression ] : 使用 -a 、-o 、!
- (()) / [[]] : 使用 && 、|| 、!
- 可以使用圆括号分组。但是test/ [ expression ]中,需要转义
- 多个表达式组合在一起。。
- 控制操作符:
- 两种形式:commands && commands 以及 commands || commands
- 根据前一个commands中最后一条命令的退出状态决定。
- 类似短路,是分支的一种便捷写法。
6、【.】命令: 用字符串引用的文件名不能直接执行(展开模式的文件名可执行)。点命令就是用来执行字符串引用的文件名
7、位置参数
- shell脚本、shell函数都可以传递位置参数
- 类似字符串展开:
- 位置参数个数${#}
- 截取位置参数:${@或者*:offset:length}
- 从第 offset 个位置参数开始【注意:offset必须从1开始】,截取length个位置参数
- offset、length都省略。即整个位置参数【也叫集体位置参数】
- 访问位置参数:
- 根据位置次序访问${number}
- for i; 循环访问位置参数
- shift命令访问:位置参数“向小移动一个位置”
- 选项options,可以利用位置参数,来处理?
8、命令参考:
- 获取命令用法参考:
- common --help 或者 command -h
- help command
- man command
- 查看命令信息: whereis 、type、which
- 命令usage 语法:
- 参数包括:选项options、参数arguments
- 【[]】表示可选,【...】表示多个,【|】表示或者
- 【<>】表示参数
- 多级命令
- 比如docker ps、docker image、docker service ps等等
- 类似于单个命令
- 可以逐级使用--help查看帮助选项
9、命令的退出状态:
- 所有命令都有一个整数类型的退出状态。
- shell函数中,通过return来产生退出状态。。默认return,退出状态为0
- 不同于其他语言中的函数/return概念,不存在返回值的概念。return对应的概念是退出状态
- 所以return必须跟一个整数,或者省略。否则报错。
- 命令作为逻辑表达式时,退出状态0为true,其他为false
- 多个命令分号分隔组成的表达式,退出状态,以最后一个命令的退出状态为准
10、命令执行shell环境:
- 启动shell会话,执行【启动文件】,初始化shell环境
- 登录shell【关键词profile】,会读取全局/etc/profile、以及用户的~/.bash_profile
- 默认脚本中,登录shell会也会读取非登录shell的启动脚本。
- 非登录shell【关键词bashrc】,会读取全局/etc/bashrc、以及用户的~/.bashrc
- 应用于所有shell、所有用户的,应写在/etc/bashrc中
- 所有shell、特定用户的,应写在/etc/.bashrc中。。其他情况类推。
- 登录shell【关键词profile】,会读取全局/etc/profile、以及用户的~/.bash_profile
- su:切换用户并开启shell、切换用户执行命令。需验证目标用户密码。
- su会开启shell会话。。su -c只是执行命令,不开启shell会话。。
- -l/-的作用是:开启登录shell,加载所有脚本。
- 只要开启了shell会话,就一定会加载非登录shell环境(bashrc)
- 所以:su -c 'commands' 不加载任何启动脚本(因为他不开启shell会话,非登录shell的脚本都不加载)
- sudo:切换用户执行命令。需要root授权可执行的命令。只需验证当前用户密码。
- root用户在/etc/sudoers中授权用户可执行命令
- 语法:who host=(runas) TAG:command
- TAG有PASSWD和NOPASSWD。后者能让sudo免密执行。
- sudo不会启动shell,也不会加载shell环境。
- 但是注意:通过指定各种各样的选项,依然能做到
- sudo -i 类似su -
- sudo -s类似su
- 但是注意:通过指定各种各样的选项,依然能做到
- root用户在/etc/sudoers中授权用户可执行命令
- su执行命令必须引用,禁止在当前shell中展开。
- sudo执行命令不用引用,因为就是要在当前shell中执行。
- 运行shell脚本程序时,系统将创建一个子shell
- 父shell的变量,只在父shell中有效。如果,要应用到子shell中,则可使用export命令导出该变量