字符串比较 四种判断方式 == != < >
(按 ascii 值比较大小), ==
相等则为真,!=
不相等则为真。
- str="bacd"
- ##判断字符串是否相等 这里的== 也可以换做 = 但是一般情况下使用==
- if [ "$str"x == "abcdsd"x ]; then
- echo "相等"
- fi
- ##不相等则为真
- if [ "$str"x != "abcdsd"x ]; then
- echo "不相等"
- fi
- ##注意 比较字符串是否相等,可以字符串后面+上个别的字符,如果str为空的话,可以防止表达式报错:[: =: unary operator expected
实践要求
按照右侧“代码文件”中提示的要求补全代码,本关的目的,是希望通过学习,对于字符串的使用能有一个大致的了解,在实际工作中遇到需要对某一个字符串处理的时候,能够找到对应的方法。
任务描述
本关将带领大家熟悉 bash 的内置命令,并掌握一些常用的内置命令。 在开启此小节之前,相信你已经对 shell 编程的变量和字符串的使用有了一定的了解。需注意: 本课程没有描述 shell 数组的概念,因为在实际的操作中 shell 数组并不是很友好,一般在数据处理的模型都用 python 来代替 shell,如果大家对 shell 数组感兴趣,请同学们可以自行翻阅资料了解一下 shell 的数组概念。
相关知识
什么是内建命令
所谓 Shell 内建命令,就是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件。 例如,用于进入或者切换目录的 cd 命令,虽然我们一直在使用它,但如果不加以注意,很难意识到它与普通命令的性质是不一样的:该命令并不是某个外部文件,只要在 Shell 中你就可以运行这个命令。 可以使用 type
来确定一个命令是否是内建命令:
- root@Test-old-web01:/opt/f89vxyw7/task1# type cd
- cd is a shell builtin
- root@Test-old-web01:/opt/f89vxyw7/task1# type ifconfig
- ifconfig is /sbin/ifconfig
由此可见,cd 是一个 Shell 内建命令,而 ifconfig 是一个外部文件,它的位置是/sbin/ifconfig
。 还记得系统变量 $PATH
吗?$PATH
变量包含的目录中几乎聚集了系统中绝大多数的可执行命令,它们都是外部命令。
通常来说,内建命令会比外部命令执行得更快,执行外部命令时不但会触发磁盘 I/O,还需要 fork 出一个单独的进程来执行,执行完成后再退出。而执行内建命令相当于调用当前 Shell 进程的一个函数。
shell有哪些内建命令
下表列出了 Bash Shell 中直接可用的内建命令。
命令 说明
- : 扩展参数列表,执行重定向操作
- . 读取并执行指定文件中的命令(在当前 shell 环境中)
- alias 为指定命令定义一个别名
- bg 将作业以后台模式运行
- bind 将键盘序列绑定到一个 readline 函数或宏
- break 退出 for、while、select 或 until 循环
- builtin 执行指定的 shell 内建命令
- caller 返回活动子函数调用的上下文
- cd 将当前目录切换为指定的目录
- command 执行指定的命令,无需进行通常的 shell 查找
- compgen 为指定单词生成可能的补全匹配
- complete 显示指定的单词是如何补全的
- compopt 修改指定单词的补全选项
- continue 继续执行 for、while、select 或 until 循环的下一次迭代
- declare 声明一个变量或变量类型。
- dirs 显示当前存储目录的列表
- disown 从进程作业表中刪除指定的作业
- echo 将指定字符串输出到 STDOUT
- enable 启用或禁用指定的内建shell命令
- eval 将指定的参数拼接成一个命令,然后执行该命令
- exec 用指定命令替换 shell 进程
- exit 强制 shell 以指定的退出状态码退出
- export 设置子 shell 进程可用的变量
- fc 从历史记录中选择命令列表
- fg 将作业以前台模式运行
- getopts 分析指定的位置参数
- hash 查找并记住指定命令的全路径名
- help 显示帮助文件
- history 显示命令历史记录
- jobs 列出活动作业
- kill 向指定的进程 ID(PID) 发送一个系统信号
- let 计算一个数学表达式中的每个参数
- local 在函数中创建一个作用域受限的变量
- logout 退出登录 shell
- mapfile 从 STDIN 读取数据行,并将其加入索引数组
- popd 从目录栈中删除记录
- printf 使用格式化字符串显示文本
- pushd 向目录栈添加一个目录
- pwd 显示当前工作目录的路径名
- read 从 STDIN 读取一行数据并将其赋给一个变量
- readarray 从 STDIN 读取数据行并将其放入索引数组
- readonly 从 STDIN 读取一行数据并将其赋给一个不可修改的变量
- return 强制函数以某个值退出,这个值可以被调用脚本提取
- set 设置并显示环境变量的值和 shell 属性
- shift 将位置参数依次向下降一个位置
- shopt 打开/关闭控制 shell 可选行为的变量值
- source 读取并执行指定文件中的命令(在当前 shell 环境中)
- suspend 暂停 Shell 的执行,直到收到一个 SIGCONT 信号
- test 基于指定条件返回退出状态码 0 或 1
- times 显示累计的用户和系统时间
- trap 如果收到了指定的系统信号,执行指定的命令
- type 显示指定的单词如果作为命令将会如何被解释
- typeset 声明一个变量或变量类型。
- ulimit 为系统用户设置指定的资源的上限
- umask 为新建的文件和目录设置默认权限
- unalias 刪除指定的别名
- unset 刪除指定的环境变量或 shell 属性
- wait 等待指定的进程完成,并返回退出状态码
常用的内建命令
一下子掌握所有的内建命令难度要求比较大,我们可以从常用内建命令入手,第一个内置命令: alias
。 1、alias alias 用来给命令创建一个别名。若直接输入该命令且不带任何参数,则列出当前 Shell 进程中使用了哪些别名,如下:
- root@Test-old-web01:/opt/f89vxyw7/task1# alias
- alias egrep='egrep --color=auto'
- alias fgrep='fgrep --color=auto'
- alias grep='grep --color=auto'
- alias l='ls -CF'
- alias la='ls -A'a
- alias ll='ls -alF'
- alias ls='ls --color=auto'
现在你应该能理解类似ll
这样的命令为什么与ls -l
或者 ls -alF
的效果是一样的吧,是因为ls -alF
被重新命名为ll
。因此,在命令行输入 ll
,即相当于输入了 ls -alF
。
使用 alias 命令自定义别名的语法格式为(临时):
- alias new_name='command'
通过 date 命令可以获得当前的 UNIX 时间戳,具体写法为 date +%s
,如果你嫌弃它太长或者不容易记住,那可以给它定义一个别名。
- alias timestamp='date +%s'
这样你在命令行输入 timestamp
获得的效果及跟输入date +%s
一样,如下:
- root@Test-old-web01:/opt/f89vxyw7/task1# date +%s
- 1580972143
- root@Test-old-web01:/opt/f89vxyw7/task1# alias timestamp='date +%s'
- root@Test-old-web01:/opt/f89vxyw7/task1# timestamp
- 1580972158
注意:通过以上方式命令别名后,在退出当前窗口后,刚设定的 alias 命令别名也就消失了,如何才能永久使用了?请看下面的介绍:
首先,如果想让别名能够在不同的 shell 会话中使用,就需要把它们添加到 shell 用来保存别名的文件中。大多数情况下,这个文件不是 .bashrc
,就是 .bash_aliases
,我们使用的系统 CentOS,是保存在.bashrc
里。(或者可以在 root 家目录下输入:ls -a ~
看到那个文件)
如果要永久保存,就把alias new_name='command'
给编辑到 /root/.bashrc
下,然后:wq
保存退出,但得重新加载别名文件,才能生效,可执行 source ~/.bashrc
(这样更改后只有 root 用户的别名生效,要想普通用户有效,普通用户目录下的.bashrc
也必需作同样的修改!比如现在有用户为 jerry,则需要到其/home/jerry/.bashrc
下编辑然后执行source ~/.bashrc
)。
- ##pdl用户登录,在/home/pdl加目录下 或者 "~"及代表用户的家目录
- ## /home/pdl/.bashrc 某行添加
- ## alias homeview='ll ~'
- ##添加
- pdl@Test-old-web01:~$ vim /home/pdl/.bashrc
- ##重新加载别名文件
- pdl@Test-old-web01:~$ source ~/.bashrc
- ##执行homeview 即相当于 执行 ll ~
- pdl@Test-old-web01:~$ homeview
- total 36
- drwx------ 4 pdl pdl 4096 Feb 6 15:10 ./
- drwxr-xr-x 5 root root 4096 Dec 30 11:18 ../
- -rw------- 1 pdl pdl 1114 Nov 21 16:54 .bash_history
- -rw-r--r-- 1 pdl pdl 220 Sep 1 2015 .bash_logout
- -rw-r--r-- 1 pdl pdl 3795 Feb 6 15:10 .bashrc
- drwx------ 2 pdl pdl 4096 Aug 22 09:00 .cache/
- -rw-r--r-- 1 pdl pdl 655 May 16 2017 .profile
- drwx------ 2 pdl pdl 4096 Aug 22 15:11 .ssh/
- -rw------- 1 pdl pdl 1016 Feb 6 15:10 .viminfo
- ##退出终端重新加载,发现别名homeview永久存在
实际用例:假设生产环境有三台机器127.1.1.2
;127.1.1.3
;127.1.1.4
; 你可以通过 alias 的方式简化 ssh 登录方式,操作如下: 在~/.bashrc
下末尾行追加内容。然后 source ~/.bashrc
,这样即可以在命令行直接输入 ssh_01
,ssh_02,ssh_03
快速登陆。
- alias ssh_01= 'sshpass -p 密码 ssh -o StrictHostKeyChecking=no -p 22 root@127.1.2'
- alias ssh_02= 'sshpass -p pass2 ssh -o StrictHostKeyChecking=no -p 22 root@127.1.1.3'
- alias ssh_03= 'sshpass -p pass4 ssh -o StrictHostKeyChecking=no -p 22 root@127.1.1.4'
实践要求
本关没有评测,希望大家独立在命令行按照示例自己操作一遍,了解熟悉 shell 的内置命令,并掌握 alias 的使用方式以及应用场景。
任务描述
本关继续为大家介绍 shell 的内置命令 echo 和 read,通过学习掌握 echo 和 read 的用法。
相关知识
内置命令——echo
echo 是一个 Shell 内建命令,用来在终端输出字符串,并在最后默认加上换行符。请看下面的例子:
- #!/bin/bash
- name="在线编程"
- url="www.educoder.net"
- echo "小哥哥,小姐姐,你好!" #直接输出字符串
- echo $url #输出变量
- echo "${name}的网址是:${url}" #双引号包围的字符串中可以解析变量
- echo '${name}的网址是:${url}' #单引号包围的字符串中不能解析变量
输出结果为:
- [root@pre-host-work02 opt]# bash a.sh
- 小哥哥,小姐姐,你好!
- www.educoder.net
- 在线编程的网址是:www.educoder.net
echo 命令输出结束后默认会换行,如果不希望换行,可以加上-n
参数,如下所示:
- #!/bin/bash
- name="在线编程"
- url="www.educoder.net"
- echo -n "小哥哥,小姐姐,你好!" #直接输出字符串
- echo -n $url #输出变量
- echo "${name}的网址是:${url}" #双引号包围的字符串中可以解析变量
输出结果为:
- [root@pre-host-work02 opt]# bash a.sh
- 小哥哥,小姐姐,你好!www.educoder.net在线编程的网址是:www.educoder.net
默认情况下,echo 不会解析以反斜杠\
开头的转义字符。比如,\n
表示换行,echo 默认会将它作为普通字符对待。请看下面的例子:
- [root@localhost ~]# echo "hello \nworld"
- hello \nworld
我们可以添加-e
参数来让 echo 命令解析转义字符。例如:
- [root@localhost ~]# echo -e "hello \nworld"
- hello
- world
内置变量——read
read 是 Shell 内置命令,用来从标准输入中读取数据并赋值给变量。如果没有进行重定向,默认就是从键盘读取用户输入的数据;如果进行了重定向,那么可以从文件中读取数据(后续我们会在 shell 的输入和输出中深入讲解重定向的概念,不了解的同学可以不用理会,暂时就认为:read 命令就是从键盘读取数据)。
read 命令的用法为:
- read [-options] [variables]
options 表示选项,如下表所示;variables 表示用来存储数据的变量,可以有一个,也可以有多个。
options 和 variables 都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量 REPLY 中。 Shell read 命令支持的选项:
【实例1】使用 read 命令给多个变量赋值,并打印提示语 read -p
。
- #!/bin/bash
- read -p "Enter some information > " name age
- echo "网站名字:$name"
- echo "年龄:$age"
输出结果为:
- [root@pre-host-work02 opt]# bash a.sh
- Enter some information > educoder 20
- 网站名字:educoder
- 年龄:20
Tips: 如果用 read 交互参数,输入错了,请按住Ctrl+Backspace清除而不是只按住Backspace。
【示例2】只读取一个字符。
- #!/bin/bash
- read -n 1 -p "Enter a char > " char
- printf "\n" #换行
- echo $char
运行结果:
- Enter a char > 1
- 1