- 管理整个计算机硬件的其实是操作系统的内核,这个内核是需要保护的,所以一般用户只能通过 Shell 与内核进行沟通。
- 操作系统其实是一组软件,这组软件在控制整个硬件与管理系统的监测。如果这组软件能被用户随意操作,若用户操作不当,将会使得整个系统奔溃。
- Linux 默认的 shell 是 bash
Bash shell 的功能
- 历史命令:在命令行按【上下键】就可以找到前后一个输入的命令。默认记录命令条目可达1000个,这些命令记录在家目录的 .bash_history 里,需要注意的是,记录的是前一次登录以前所执行过的命令,而这一次登录所执行的命令被缓存在内存中,当你成功注销系统后,这一次的命令才会存到 .bash_history 中。这个功能的优点是你在某些时候可以查询你曾经使用过的命令而进行排错,但如果你的历史操作中有一些包含密码的操作,也有一定的被黑客入侵风险。
- 命令与文件补全功能:【Tab】键接在一串命令的第一个字后面,则为命令补全;【Tab】键接在一串命令的第二个字后面,则为文件名补全;若安装 bash-completion 软件,则在某些命令后边使用【Tab】键时可以进行某些【参数/选项】的补齐。
- 命令别名设置功能:alias,如:alias lm=‘ ls -al ’,就表示给 ls -al 这个命令设置了一个 lm 别名
- 任务管理、前台、后台控制
- 程序化脚本
- 通配符
查询命令是否为 Bash Shell 内置命令:type
- 指令格式:type [-tpa] name(命令)
参数或选项 | 含义 |
---|---|
无参数选项 | type 会显示出 name 是外部命令还是 bash shell 内置命令 |
-t | type 将 name 以 file 、alias、builtin 这三个字眼来表示,file 代表为外部命令;alias 代表为命令别名;builtin 代表 为bash 内置命令 |
-p | 当后边跟的为外部命令时,才会显示出完整文件名 |
-a | 会由 PATH 变量定义的路径中,将所有含 name 的命令都列出来,包括 alias(命令别名) |
- 通过 type 可以知道每个命令是否为 Bash 内置命令;但由于利用 type 查找后边的名称时,如果后边接的名称并不能以执行文件的状态被找到,那么该名称不会被显示出来,也就是说 type 主要找的是执行文件而不是一般文件名。
Shell 的变量功能
- 变量其实就是一串特定的字符串,可以给它赋值,赋值后再使用这个变量时其实就是使用赋给它的值。比如: a = 3,就是将值 3 赋给变量 a,后边再执行 a + 1 等操作时其实就是 3 + 1
变量的使用与设置
变量的使用:echo
- 变量在被使用时前边要加上 $ 美元符号
- 指令格式:echo $变量名
- 如:echo $PATH,执行该条命令就会打印出 PATH 变量的值
变量设置规则
- 变量与变量内容(值)以等号【=】连接,如:myname=VBird
- 等号两边不能直接跟空格
- 变量内容若有空格可以使用双引号【“ ”】或单引号【‘ ’】引起来;但双引号内的特殊字符可以保留其原本的特性,如:stu=" I am $myname",打印 stu 可得:I am VBird。而单引号内的特殊字符仅为一般字符(纯文本)
- 可用转义字符【 \ 】将特殊字符(如:[Enter]、$、空格等)变成一般字符
- 在一串命令的执行中,还需要借由其他额外的命令所提供的信息时,可以使用反单引号【 ` 命令】或【$ (命令)】。如想要取得内核版本信息:version=$ (uname -r),打印 version 就可得到 3.10.0-299.el7.x86-64
- 若该变量为扩增变量内容时,则可以用 ”$变量名称“ 或 ${变量} 累加内容。
- 若该变量需要在其他子程序中执行,则需要用 export 来使变量变成环境变量
- 通常大写字符为系统默认变量,自行设置变量可以使用小写字符
- 取消变量使用 unset ,格式为:unset 变量名称,即可取消变量的设置
- 在一般状态下,父进程自定义的变量,子进程是无法使用的;除非使用 export 将自定义变量变成环境变量后,子进程才能使用。
环境变量的功能
用 env 可以观察环境变量
- 用 env 可以列出目前 shell 环境下的所有环境变量与内容
环境变量 | 含义 |
---|---|
HOME | 代表用户的根目录 |
SHELL | 告知目前环境使用的SHELL是哪个程序 |
HISTSIZE | 设置记录历史命令的条数 |
使用 mail 命令收信时,系统会去读取的邮箱文件 | |
PATH | 执行文件的查找路径,目录与目录中间以冒号【:】分割 |
LANG | 语系数据,当我们启动某些程序语言文件时,它会主动地去分析语系数据文件,如果有它无法解析的编码语系,可能会产生错误 |
RANDOM | 随机数变量,在 BASH 环境下,执行 echo $RANDOM,系统会主动地从0~32767之间取出一个数值 |
- 打印 0~9 之间的一个随机数:declare -i number=$RANDOM*10/32768;echo $number
用 set 可以观察环境变量和自定义变量
- 在 Linux 默认的情况中,{大写字母}来设置的变量一般为系统内定需要的变量
- PS1 提示字符的设置(命令提示符)
符号 | 意义 |
---|---|
\d | 可显示出【星期 月 日】的日期格式 |
\H | 完整的主机名 |
\h | 仅取主机名在第一个小数点之前的名字 |
\t | 显示为24小时格式为【HH:MM:SS】的时间 |
\T | 显示为12小时格式为【HH:MM:SS】的时间 |
\A | 显示为24小时格式为【HH:MM】的时间 |
\@ | 显示为12小时格式为【am/pm】的时间 |
\u | 目前用户的账号名称 |
\v | BASH 的版本信息 |
\w | 完整的工作目录名称,从根目录写起,但根目录一般会以~替换 |
\W | 利用 basename 函数取得工作目录名称,故仅会列出最后一个目录名 |
\# | 执行的第几个命令 |
\$ | 提示字符,如果是 root,提示字符为 #,否则为 $ |
$ | 关于本 shell 的 PID,PID 即进程的 shell 号 |
? | 关于上个执行命令的返回值。当执行某些命令时,这些命令会返回一个执行后的代码,若成功执行则返回 0 ,否则返回错误代码(非 0 数值) |
OSTYPE,HOSTTYPE,MACHTYPE | 主机硬件与内核等级 |
export:自定义变量转成环境变量
- 自定义变量与环境变量的差异在于,【改变了是否会被子进程所继续引用】
- 子进程:在当前这个 shell 下,启用另一个新的shell;新启用的 shell 就是当前 shell 的子进程,而当前进程就是【父进程】
- 子进程仅会继承父进程的环境变量,而不会继承父进程的自定义变量
- 指令格式:export 变量名
变量的有效范围
- 全局变量=环境变量;局部变量=自定义变量
为什么环境变量可以被子进程引用?
- 当启动一个 shell,操作系统会分配一个内存区域给 shell 使用,此内存中的变量可让子进程使用。
- 若在父进程利用 export 的功能,可以让自定义变量的内容写到上述内存区域中(环境变量)。
- 当加载另一个 shell 时(即启动子进程,离开原本的父进程),子 shell 可以将父 shell 的环境变量所在的内存区域导入自己的环境变量区块中。
变量键盘读取
read:读取键盘输入的变量
- 格式:read [-pt] 变量名
- -p:后边可接提示字符
- -t:后边接等待秒数
声明变量的类型:declare,typeset
- declare 与 typeset 功能一致
- 格式:declare [-参数] 变量名
参数 | 含义 |
---|---|
-a | 将变量定义为【数组】类型 |
-i | 将变量定义为【整数】类型 |
-x | 将变量变成【环境变量】,同 export 功能一样 |
-r | 将变量设置为readonly(只读)类型,该变量不能被修改内容,也不能被 unset |
- 如果不使用 declare 设置变量类型,那么变量类型默认为字符串
- bash 中的数值运算,默认最多能达到整数
- 如果不小心将变量变为只读,通常需要注销登录才能恢复该变量类型
数组变量类型
- 声明:数组名[index]=内容
文件系统及程序的限制关系:ulimit
- bash 可以限制用户的某些系统资源,包括可以开启的文件数量,可以使用的 CPU 时间,可以使用的内存总量等
- 格式:ulimit [-参数] 配额
参数 | 含义 |
---|---|
-H | 严格的设置,一定不能超过这个设置的数值 |
-S | 警告设置,可以超过该设置值,但超过后会有警告提示 |
-a | 后边不跟任何选项参数,可以列出所有的限制额度 |
-c | 当某些程序发生错误时,系统可能会将该程序在内存中的信息写成文件(除错用) |
-f | 该 shell 可以建立最大的文件容量,单位为 KB |
-d | 程序可使用的最大段内存容量 |
-l | 用于锁定的内存量 |
-t | 可使用的最大 CPU 时间 |
-u | 单一使用者可以使用的最大进程数量 |
变量内容的删除、取代与替换
删除:
- ${变量名#/*关键词}
- #:代表【从变量内容的最左边向右删除】,且仅删除【最短】的那条数据
- ##:代表【从变量内容的最左边向右删除】,且仅删除【最长】的那条数据
- 通配符 * 替换0到无穷多个任意字符
变量设置方式 | 说明 |
---|---|
${变量#关键词} | 若变量内容【从头】开始的数据符合关键词,则将符合的【最短】数据删除 |
${变量##关键词} | 若变量内容【从头】开始的数据符合关键词,则将符合的【最长】数据删除 |
${变量%关键词} | 若变量内容【从尾】开始的数据符合关键词,则将符合的【最短】数据删除 |
${变量%%关键词} | 若变量内容【从尾】开始的数据符合关键词,则将符合的【最长】数据删除 |
${变量/旧字符串/新字符串} | 若变量内容符合旧字符串,则【第一个】旧字符串会被新字符串替换 |
${变量//旧字符串/新字符串} | 若变量内容符合旧字符串,则【全部】的旧字符串都会被新字符串替换 |
变量的测试与内容替换
- 某些情况下我们需要【判断】某个变量是否存在,若变量存在则使用已有的设置,若不存在则给予一个常用的设置。
- 新变量=${旧变量-内容},一般新旧变量名称一样,当旧变量不存在时,就会将后边的内容给与该变量,其实就是设置一个新变量并给初值。
变量设置方式 | str 没有设置 | str 为空字串 | str 为非空字串 |
---|---|---|---|
var=${str-expr} | var=expr | var= | var=$str |
var=${str:-expr} | var=expr | var=expr | var=$str |
var=${str+expr} | var= | var=expr | var=expr |
var=${str:+expr} | var= | var= | var=expr |
var=${str=expr} | str=expr var=expr | str不变,var= | str不变 var=$str |
var=${str?expr} | expr 输出至 stderr | var= | var=$str |
var=${str=expr} | expr 输出至 stderr | expr 输出至 stderr | var=$str |
命令别名设置
- alias 后边不带东西,可以查看已经设置的命令别名
历史命令:histrory
- history [n] / [-c] / [-raw] histfiles (文件名)
参数 | 含义 |
---|---|
n | 表示列出最近的 n 条命令行表 |
-c | 将目前 shell 中所有的 history 内容全部清除 |
-a | 将新增的命令写入 histfiles 中,若无 histfiles,则默认写入~/.bash_history |
-r | 将 histfiles 内容读到目前这个 shell 的 history 记录中 |
-w | 将目前的 history 记录写入 histfiles 中 |
- !number,执行第 number 条命令
- !command,由最近的命令向前查找【命令串开头为 command 】的命令,并执行
- ! ! 执行上一个命令
Bash shell 操作环境
路径与命令查找顺序
- 命令查找并执行的顺序
- 以相对 / 绝对路径执行命令,例如【/bin/ls】或【./ls】
- 由 alias 找到命令来执行
- 由 bash 内置的命令来执行
- 通过 $PATH 这个变量的顺序查找的第一个命令来执行
bash的登录与欢迎信息:/etc/issue、/etc/mod
- issue 内各代码意义:
代码 | 意义 |
---|---|
\d | 本地端时间的日期 |
\l | 显示第几个终端页面 |
\m | 显示硬件的等级 |
\n | 显示主机的网络名称 |
\O | 显示 domain name |
\r | 操作系统的版本 |
\t | 显示本地端时间的时间 |
\S | 操作系统的名称 |
\v | 操作系统的版本 |
- 如果想要让用户登录后取得一些信息,例如想要让大家都知道的信息,那么可以将信息加入 /etc/mod
bash的环境配置文件
- 系统中有一些配置文件存在,让 bash 启动时直接读取这些配置文件,以规划好 bash 的操作环境。这些配置文件可为全局系统配置文件和用户个人偏好配置文件。需要注意的是,命令别名、自定义变量在注销 bash 后就会失效,如果想要保留这些设置,需要将它们写入配置文件才可以。
login 与 no-login shell
- login shell:取得 bash 时需要完整的登录流程。
- no-login shell:取得 bash 不需要重复的登录操作。例如:以 X Windows 登录 Linux 后,再以 X 的图形化接口启动终端,此时这个终端接口并没有要求再次输入账户密码登录,那么该 bash 环境就称为 no-login shell。
/etc/profile 配置文件:(login shell 才会读)
- 该文件是系统的整体设置,最好不要轻易修改
- 每个用户登录取得 bash 时一定会读取的配置文件
- 该文件设置的变量主要有以下:
变量 | 说明 |
---|---|
PATH | 根据 UID 决定 PATH 变量要不要含有 sbin 的系统命令目录 |
根据 账号设置好用户的 mailbox 到 /var/spool/mail/ 账号名 | |
USER | 根据用户账号设置此变量内容 |
HOSTNAME | 根据主机的 hostname 决定该变量内容 |
HISTSIZE | 历史命令记录条数 |
umask | 包括 root 默认为 022,一般用户默认为 002 |
- /etc/profile 还会调用外部文件,在CentOS 7.x 默认的情况下会依序调用以下文件:
文件 | 说明 |
---|---|
/etc/profile.d/*.sh | 其实这是个目录内的众多文件,* 为通配符;即在 /etc/profile.d/ 这个目录下所有的 .sh 文件。另外,用户能够具有 r(可读)的权限,那么该文件就会被 /etc/profile.d 调用。如果你需要帮用户设置一些共享的命令别名时,可以在该目录下创建扩展名为 .sh 的文件,将相关数据写进去即可。 |
/etc/locate.conf | 这个文件由 /etc/profile.d/lang.sh 调用,该文件也是决定 bash 默认使用何种语系的重要配置文件,文件中最重要的就是 LANG/LC_ALL 这个变量的设置 。 |
/usr/share/bash-completion/completions/* | [ Tab ] 键的命令补齐,参数补齐等,都是从该文件中找到相应的命令 |
- bash 的 login shell 情况下所读取的整体配置环境文件其实只有 /etc/profile/,但 /etc/profile/ 会调用其他的配置文件。
~/.bash_profile (login shell 才会读)或 ~/.bash_login 或 ~/.profile 配置文件:
- bash 在读取完整体环境设置的 /etc/profile/ ,并借此调用其他文件后,接下来读取会读取用户的个人配置文件。主要有三个,依序分别是:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
- 其实 bash shell 的 login shell 设置只会读取上述三个文件中的一个,而读取顺序则是依照上边的顺序。也就是说,如果 ~/.bash_profile 文件存在,那么另外两个文件无论存在与否都不会去读取。
source(或小数点):读入环境配置文件的命令
- 指令格式:source 配置文件名 或者 . 配置文件名
- 使用 source 就可以很方便的将配置文件读入到当前的 bash 环境中
~/.bashrc(no login-shell 会读)
- 默认的 ~/.bashrc 文件内容一般有用户的个人设置和整体环境设置;root 身份的 ~/.bashrc 中规范了较为安全的命令别名。此外 CentOS 7.x 会主动地调用 /etc/bashrc 这个文件,该文件帮bash定义出以下内容:
- 根据不同的 UID 设置 umask 值
- 根据不同的 UID 设置提示字符(即 PS1 变量)
- 调用 /etc/profile.d/*.h 的设置
- 注意:/etc/bashrc 是 CentOS 特有的,其他不同的Linux发行版可能会使用不同的文件名
/etc/man_db.conf:
- 该文件规范了使用 man 的时候,man page 的路径到哪里去寻找,简单来说这个文件规定了执行 man 的时候,该去哪里查看数据的路径设置。
~/.bash_logout:
- 该文件记录了当用户注销 bash 后,系统再帮我做完什么操作后才离开。默认情况下,注销时,bash 只是帮我们清掉屏幕信息而已。
终端环境的设置
stty:帮助设置终端的输入按键代表的意义
- 指令格式:stty [ -a ]
- -a:将目前所有的 stty 参数列出来
- 在列出来的列表中,需要注意特殊字体,如 ^ 则代表 [ Ctrl ] 这个按键
- 下面是几个重要的关键词及其意义:
关键词 | 意义 |
---|---|
intr | 发送一个 interrupt(中断)信号给正在运行的程序(即终止) |
quit | 发送一个 quit 信号给正在运行的程序 |
erase | 向后删除字符 |
kill | 删除在目前命令行上的所有文字 |
enof | 代表 end of file,结束输入 |
start | 在某个程序停止后,重新启动它的 output |
stop | 停止目前屏幕的输出 |
susp | 送出一个 terminal stop 信号给正在运行的程序 |
set 设置终端
- 指令格式:set [ -参数 ]
- 范例:显示目前所有的 set 设置值,set $-
参数 | 含义 |
---|---|
-u | 默认不启用,若启用后,当使用未设置的变量时,会报错 |
-v | 默认不启用,若启用后,在信息被输出前,会先显示出信息的原始内容 |
-x | 默认不启用,若启用后,在命令被执行前,会显示命令内容(前面有++符号) |
-h | 默认启用,与历史命令有关 |
-H | 默认启用,与历史命令有关 |
-m | 默认启用,与任务管理有关 |
-B | 默认启用,与中括号 [ ] 作用有关 |
-C | 默认不启用,若使用 > 等,则当文件存在时,该文件不会被覆盖 |
- bash 默认组合按键:
组合按键 | 执行结果 |
---|---|
Ctrl+C | 终止目前的命令 |
Ctrl+D | 输入结束(eof),例如邮件结束时 |
Ctrl+M | 回车 |
Ctrl+S | 暂停屏幕的输出 |
Ctrl+Q | 恢复屏幕的输出 |
Ctrl+U | 在提示字符下将整列命令删除 |
Ctrl+Z | 暂停目前的命令 |
通配符:
符号 | 意义 |
---|---|
* | 代表 【0 到无穷多】个任意字符 |
? | 代表【一定有一个】任意字符 |
[ ] | 代表【一定有一个在括号内】的字符(非任意字符) |
[ - ] | 代表在编码顺序内的所有字符 |
[ ^ ] | 表示【反向选择】(即 非)如:[ ^abc],代表一定有一个字符只要不是 a、b、c 其中之一即可 |
bash 环境中的特殊符号:
符号 | 意义 |
---|---|
# | 注释符号,最常被用于脚本中,用作说明,其后跟的数据不执行 |
\ | 转义符:将特殊字符或通配符转为一般字符 |
| | 管道:分割两个管道命令的符号 |
; | 连续命令执行分隔符,连续性命令的界定 |
~ | 用户的家目录 |
$ | 使用变量前导符:即变量之前需要加的变量替换值 |
& | 任务管理:将命令变成后台任务 |
! | 逻辑运算意义上的【非】 |
/ | 目录符号:路径分隔符 |
>、>> | 数据流重定向:输出定向,分别是【替换】与【累加】 |
<、<< | 数据流重定向:输入定向 |
’ ’ | 单引号:不具备变量替换功能($ 变为纯文本) |
“ ” | 双引号:具有变量替换功能($ 可保留相关功能) |
· · | 反单引号:被返单引号引起来的部分可以先执行命令,也可以用 $( ) |
( ) | 在中间为子 shell 的起始与结束 |
{ } | 在中间为命令区块的组合 |
- 在设置文件名时尽量不要用到这些特殊符号
数据流重定向
- 当我们执行一个命令的时候,这个命令可能会由文件读入数据,经过处理后,再将文件输出到屏幕
- 数据流重定向就是将某个命令执行后将要出现在屏幕上的数据传输到另一个地方。
standard out【标准输出】 与 standard error output【标准错误输出】
- 标准输出与标准错误输出都是会输出到屏幕上的
- 标准输出指的是命令执行所返回的正确信息
- 标准错误输出指的是,命令执行失败后,所返回的错误信息
- 不论是标准输出还是标准错误输出,都会直接输出到屏幕上,这将导致屏幕上的信息比较混乱,这个时候就可以使用数据流重定向将这两个输出分开。数据流重定向可以将标准输出与标准错误输出分别传送到其他文件或设备,而分别传送所用的特殊字符如下所示:
特殊字符 | 说明 |
---|---|
标准输入(stdin) | 代码为 0 ,使用 < 或 << |
标准输出(stdout) | 代码为 1 ,使用 > 或 >> |
标准错误输出(stderr) | 代码为 2 ,使用 2> 或 2>> |
范例 1:ll / > ~/rootfile
- 该范例中【ll /】为查看系统根目录( / )下各目录的文件名、权限与属性,原本是会将命令成功的结果输出到屏幕上,但此范例中屏幕上并无数据输出,这是因为【>】 将命令执行成功的输出传送到了 ~/rootfile 文件中。当 ~/rootfile 文件不存在时,系统会自动建立该文件;当 ~/rootfile 文件存在时,系统会将该文件中原本的数据清空,然后再讲命令执行的输出写入,也就是说若以 > 输出到一个已存在的文件时,会将文件原本的内容覆盖掉。
字符 | 说明 |
---|---|
1> | 以【覆盖】的方式将【正确】的文件输出到指定的文件或设备 |
1>> | 以【累加】的方式将【正确】的文件输出到指定的文件或设备 |
2> | 以【覆盖】的方式将【错误】的文件输出到指定的文件或设备 |
2>> | 以【累加】的方式将【错误】的文件输出到指定的文件或设备 |
范例 2:find /home -name .bashrc > list_right 2> list_error
- 该范例中【find /home -name .bashrc】命令执行的结果,正确的输出会传送到 list_right 文件中,而错误的输出会传送到 list_error 文件中。这样就可以一次性将正确信息与错误信息分别传送到不同的文件中。
/dev/null 垃圾桶黑洞设备与特殊写法
- 有时候我们指定会有错误信息且希望将错误信息忽略不显示或存储,就可以使用黑洞设备 /dev/null
范例 3(依据范例 2):find /home -name .bashrc 2> /dev/null
- 范例 3 最后的结果就是屏幕上只会输出正确输出,而错误输出则会被丢弃。这就是黑洞设备 /dev/null 的作用,它可以吃掉任何导向这个设备的信息。
范例 4:find /home -name .bashrc > list 2>&1
- 范例 4 使用特殊符号将标准输出与标准错误输出传送到了同一个文件中,还有另一种等价写法为【find /home -name .bashrc &> list】
stanard input(标准输入):< 与 <<
- < 与 << 简单来说就是将原本由键盘输入的数据改由文件内容来替换
范例 4:cat > catfile < ~/.bashrc
- 该范例 4,用 ~/.bashrc 这个文件的内容来替换键盘输入,将文件内容输入到了 catfile 这个文件中
- <<:代表【结束的输入字符】用范例 5 对其进行说明
范例 5:
cat > catfile << “eof”
> test1
> test2
> eof
- 该范例在输入完【cat > catfile << “eof”】回车后,可以由键盘输入数据到 catfile,并且在遇到 eof 时终止本次输入。以范例 5 来看,输入 eof 后本次输入终止,test1 和 test2 会被存入 catfile,eof 是终止输入的关键词所以不会存入 catfile。
为什么要使用命令输出重定向?
- 有时屏幕输出的某些重要信息需要我们将它存储
- 不让在后台运行的程序干扰到屏幕正常的输出
- 将一些系统的计划任务命令的执行结果进行保存
- 在执行命令之前已经知晓某些想要忽略的错误信息,可以使用垃圾桶黑洞设备 /dev/null 进行丢弃
- 错误信息与正确信息需要分别输出时
范例 6:将 echo “error message” 以标准错误的格式输出,所用命令为【echo “error message” 1>&2】
命令执行的判断依据:;、&&、||
不考虑命令相关性的连续命令执行:命令;命令
- 命令与命令之间用【;】分号隔开,分号前的命令执行完后会立刻接着执行分号后的命令
$?(命令返回值)&&或||
- 若前一个命令执行正确,在 Linux 下面会返回一个 $?=0 的值
命令执行情况 | 说明 |
---|---|
cmd1 && cmd2 | 若 cmd1 执行完毕且【正确】执行($?=0),则【开始执行 cmd2】 |
cmd1 && cmd2 | 若 cmd1 执行完毕且【错误】($? !=0),则【不执行 cmd2】 |
cmd1 || cmd2 | 若 cmd1 执行完毕且【正确】执行($?=0),则【不执行 cmd2】 |
cmd1 || cmd2 | 若 cmd1 执行完毕且【错误】($? !=0),则【开始执行 cmd2】 |
- 注:Linux 下面的命令是【由左往右】执行
范例 7:不清楚 /tmp/abc 是否存在,但要建立 /tmp/abc/hehe 文件,所用命令为【ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe】
- 对于范例 7进行如下分析:
- 命令1【ls /tmp/abc】将会判断 /tmp/abc 是否存在,【若不存在】则返回 $? !=0;——> || 遇到 $? !=0,则开始执行命令2【mkdir /tmp/abc】,也就是会创建 /tmp/abc这个目录,执行成功后返回 $?=0;——> &&遇到 $?=0,则开始执行命令3【touch /tmp/abc/hehe】,也就是在目录 /tmp/abc/ 下建立 hehe 这个文件。
- 命令1【ls /tmp/abc】将会判断 /tmp/abc 是否存在,【若存在】则返回 $?=0;——> || 遇到 $?=0,则不会执行命令2【mkdir /tmp/abc】,而此时 $?=0 会继续向后传;——> &&遇到 $?=0,则开始执行命令3【touch /tmp/abc/hehe】,也就是在目录 /tmp/abc/ 下建立 hehe 这个文件。
范例 8:以 ls 测试 /tmp/vbirding 是否存在,若存在则显示“exit”,不存在显示“no exit”;所用命令为【 ls /tmp/vbirding && echo “exit” || echo “no exit” 】,意思就是说当【 ls /tmp/vbirding 】执行正确,就会执行 【echo “exit”】,若执行出错,则会执行【echo “no exit“】。
- 若范例 8 命令改写为:【 ls /tmp/vbirding || echo “no exit" && echo “exit” 】,就无法满足题目要求。因为 Linux 命令是从左往右依次执行,那么当【 ls /tmp/vbirding 】执行出错就会去执行【echo “no exit“】,而【echo “no exit“】一定是执行成功的,所以紧跟着后边的【echo “exit”】也会执行。