Shell学习-06-内建命令

在人生的道路上,不管是潇洒走一回,或者是千山独行,皆须是自己想走的路,虽然,有的人并不是很快就能找到自己的方向和道路,不过,只要坚持到底,我相信,就一定可以找到自己的路,只要找到路,就不必怕路途遥远了。

导读:本篇文章讲解 Shell学习-06-内建命令,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

2.13 Shell内建命令

  • Shell 内置命令,就是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件。如:用于进入或者切换目录的 cd 命令,虽然我们一直在使用它,但如果不加以注意很难意识到它与普通命令的性质是不一样的:该命令并不是某个外部文件,只要在 Shell 中你就一定可以运行这个命令。

  • 可以使用 type 来确定一个命令是否是内建命令:

[root@localhost teststringfile]# type cd
cd 是 shell 内嵌
[root@localhost teststringfile]# type ip
ip 是 /usr/sbin/ip
[root@localhost teststringfile]# type ps
ps 是 /usr/bin/ps

由此,cd 是一个 Shell 内建命令,而 ip 是一个外部文件,它的位置是/usr/sbin/ip,ps命令同样也是

  • 系统变量$PATH 包含的目录中几乎聚集了系统中绝大多数的可执行命令,它们都是外部命令。

  • 通常来说,内建命令会比外部命令执行得更快,执行外部命令时不但会触发磁盘 I/O,还需要 fork 出一个单独的进程来执行,执行完成后再退出。而执行内建命令相当于调用当前 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 等待指定的进程完成,并返回退出状态码

2.14 Shell alias命令

  • alisa 用来给命令创建一个别名。直接输入该命令且不带任何参数,则列出当前 Shell 进程中使用了哪些别名。可以看出ll这样的命令与ls -l的效果是一样的。
[root@localhost teststringfile]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
。。。

为了使用方便,Shell 会给某些命令默认创建别名。

  • 使用 alias 命令自定义别名的语法格式为:
alias new_name='command'
#一般的关机命令是shutdown-h now,写起来比较长,这时可以重新定义一个关机命令
[root@localhost teststringfile]# alias myshutdown='shutdown -h now'
#通过 date 命令可以获得当前的 UNIX 时间戳,具体写法为date +%s,命令太长可以定义一个别名
[root@localhost teststringfile]# alias timestamp='date +%s'
[root@localhost teststringfile]# alias timestamp='date +%s'
[root@localhost teststringfile]# timestamp
1669565057

  • 之前使用date +%s计算脚本的运行时间,现在学了 alias,就可以简化代码了。
#!/bin/bash

alias timestamp='date +%s'
begin=`timestamp`  
sleep 5s
finish=$(timestamp)
#difference=$finish-$begin
difference=$((finish - begin))
echo "run time: ${difference}s"

#运行脚本,5秒后看到输出结果:
run time: 5s
  • 别名只是临时的:在代码中使用 alias 命令定义的别名只能在当前 Shell 进程中使用,在子进程和其它进程中都不能使用。当前 Shell 进程结束后,别名也随之消失。要想让别名对所有的 Shell 进程都有效,就得把别名写入 Shell 配置文件。Shell 进程每次启动时都会执行配置文件中的代码做一些初始化工作,将别名放在配置文件中,那么每次启动进程都会定义这个别名。

  • 使用 unalias 内建命令可以删除当前 Shell 进程中的别名:unalias 有两种使用方法:

    • 第一种用法是在命令后跟上某个命令的别名,用于删除指定的别名。
    • 第二种用法是在命令后接-a参数,删除当前 Shell 进程中所有的别名。
  • 同样,这两种方法都是在当前 Shell 进程中生效的。要想永久删除配置文件中定义的别名,只能进入该文件手动删除。

# 删除 ll 别名
[root@localhost teststringfile]# unalias timestamp
# 再次运行该命令时,报“找不到该命令”的错误,说明该别名被删除了
[root@localhost teststringfile]# timestamp
-bash: timestamp: 未找到命令

2.15 Shell echo命令

  • cho 是一个 Shell 内建命令,用来在终端输出字符串,并在最后默认加上换行符。
#!/bin/bash
arr=(http://www.baidu.com 123 456)
url=www.baidu.com
echo "www.baidu.com"		#直接输出字符串
echo ${arr[*]}
echo $url		 			#输出变量
echo "网址为:${url}"		 #双引号包围的字符串中可以解析变量
echo '网址为:${url}'		 #单引号包围的字符串中不能解析变量
运行结果:
www.baidu.com
http://www.baidu.com 123 456
www.baidu.com
网址为:www.baidu.com
网址为:${url}
  • **不换行:**echo 命令输出结束后默认会换行,如果不希望换行,可以加上-n参数,如下所示:
#!/bin/bash
arr=(http://www.baidu.com 123 456)
url=www.baidu.com

echo -n ${arr[*]}
echo -n $url		 			#输出变量
运行结果:
http://www.baidu.com 123 456 www.baidu.com
  • **输出转义字符:**默认情况下,echo 不会解析以反斜杠\开头的转义字符。比如,\n表示换行,echo 默认会将它作为普通字符对待。
[root@localhost teststringfile]# echo hello \n world
hello n world
[root@localhost teststringfile]# echo "hello \n world"
hello \n world
  • 可以添加-e参数来让 echo 命令解析转义字符。
[root@localhost teststringfile]# echo -e hello \n world
hello n world
[root@localhost teststringfile]# echo -e "hello \nworld"
hello 
world
  • \c 转义字符-e参数,我们也可以使用转义字符\c来强制 echo 命令不换行了。
#!/bin/bash
url=www.baidu.com
echo -e "hello \n world \c"
echo -e "${url} \c"
echo "END!"
echo "END!"
运行结果:
hello 
 world www.baidu.com END!
echo "END!" #中文!号,英文!是命令符号

2.16 Shell read命令

  • read 是 Shell 内置命令,用来从标准输入中读取数据并赋值给变量。如果没有进行重定向,默认就是从键盘读取用户输入的数据;如果进行了重定向,那么可以从文件中读取数据。read 命令的用法为:
read [-options] [variables]

options表示选项,如下表所示;variables表示用来存储数据的变量,可以有一个,也可以有多个。

optionsvariables都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量 REPLY 中。

选项 说明
-a array 把读取的数据赋值给数组 array,从下标 0 开始。
-d delimiter 用字符串 delimiter 指定读取结束的位置,而不是一个换行符(读取到的数据不包括 delimiter)。
-e 在获取用户输入的时候,对功能键进行编码转换,不会直接显式功能键对应的字符。
-n num 读取 num 个字符,而不是整行字符。
-p prompt 显示提示信息,提示内容为 prompt。
-r 原样读取(Raw mode),不把反斜杠字符解释为转义字符。
-s 静默模式(Silent mode),不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这是很有必要的。
-t seconds 设置超时时间,单位为秒。如果用户没有在指定时间内输入完成,那么 read 将会返回一个非 0 的退出状态,表示读取失败。
-u fd 使用文件描述符 fd 作为输入源,而不是标准输入,类似于重定向。
  • 使用 read 命令给多个变量赋值。
[root@localhost testshell]# touch test.sh & vim test.sh
#!/bin/bash
read -p "Enter some info > " name age
echo "名字:${name}"
echo "年龄:${age}"

#运行
[root@localhost testshell]# . test.sh
Enter some info > zk 8
名字:zk
年龄:8

注意,必须在一行内输入所有的值,不能换行,否则只能给第一个变量赋值,后续变量都会赋值失败。

[root@localhost testshell]#  touch test.sh & vim test2.sh
[root@localhost testshell]#  cat test2.sh
#!/bin/bash
read -n 5 -p "Enter some info >" str1
printf "\n"
echo "${str1}"
#运行结果:
[root@localhost testshell]# . test2.sh
Enter some info >hello
hello

-n 5表示只读取5个字符。运行脚本后,只要用户输入5个字符,立即读取结束,不用等待用户按下回车键。

printf "\n"语句用来达到换行的效果,否则 echo 的输出结果会和用户输入的内容位于同一行,不容易区分。

  • 在指定时间内输入密码。
#!/bin/bash
if

#一次输入密码
read -t 60 -sp "Enter pwd in 1 mins of first! >" pwd1 && printf "\n" &&
#二次输入密码
reed -t 60 -sp "Enter pwd in 1 mins of second! >" pwd2 && printf "\n" && 

[ $pwd1 == $pwd2 ]		#判断两次输入的密码是否相等

then
 echo "valid pwd"
else
 echo "invalid pwd"

fi

这段代码中,我们使用&&组合了多个命令,这些命令会依次执行,并且从整体上作为 if 语句的判断条件,只要其中一个命令执行失败(退出状态为非 0 值),整个判断条件就失败了,后续的命令也就没有必要执行了。

  • 运行结果
[root@localhost testshell]# . test1.sh
#如果两次输入密码不同,运行结果为:
Enter pwd in 1 mins of first! >
Enter pwd in 1 mins of second! >
-bash: [123456: 未找到命令
invalid pwd

#如果两次输入密码相同,运行结果为:
[root@localhost testshell]# . test1.sh
Enter pwd in 1 mins of first! >
Enter pwd in 1 mins of second! >
valid pwd

如果第一次输入超时,运行结果为:
Enter pwd in 1 mins of first!  > Invalid password

2.17 Shell exit 命令

  • exit 是一个 Shell 内置命令,用来退出当前 Shell 进程,并返回一个退出状态;使用$?可以接收这个退出状态。
  • exit 命令可以接受一个整数值作为参数,代表退出状态。如果不指定,默认状态值是 0。一般情况下,退出状态为 0 表示成功,退出状态为非 0 表示执行失败(出错)了。exit 退出状态只能是一个介于 0~255 之间的整数,其中只有 0 表示成功,其它值都表示失败。
  • Shell 进程执行出错时,可以根据退出状态来判断具体出现了什么错误,比如打开一个文件时,我们可以指定 1 表示文件不存在,2 表示文件没有读取权限,3 表示文件类型不对。例如运行以下脚本:
#!/bin/bash
echo "befor exit"
exit 4
echo "after exit"
#运行该脚本:
[root@localhost testshell]# chmod +x test4.sh
#在新进程中运行 test4.sh
[root@localhost testshell]# ./test4.sh
befor exit
[root@localhost testshell]# bash test4.sh
befor exit

#可以看到,"after exit"并没有输出,这说明遇到 exit 命令后,test3.sh 执行就结束了。

注意,exit 表示退出当前 Shell 进程,我们必须在新进程中运行 test4.sh,否则当前 Shell 会话(终端窗口)会被关闭,就无法看到输出结果了。

  • 同时使用$?来获取 test.sh 的退出状态:
[root@localhost testshell]# echo $?
4

2.18 Shell declare和typeset命令

  • declare 和 typeset 都是 Shell 内建命令,它们的用法相同,都用来设置变量的属性。不过 typeset 已经被弃用了,建议使用 declare 代替。declare 命令的用法如下所示:
declare [+/-] [aAfFgilprtux] [变量名=变量值]

其中,-表示设置属性,+表示取消属性,aAfFgilprtux都是具体的选项,它们的含义如下表所示:

选项 含义
-f [name] 列出之前由用户在脚本中定义的函数名称和函数体。
-F [name] 仅列出自定义函数名称。
-g name 在 Shell 函数内部创建全局变量。
-p [name] 显示指定变量的属性和值。
-a name 声明变量为普通数组。
-A name 声明变量为关联数组(支持索引下标为字符串)。
-i name 将变量定义为整数型。
-r name[=value] 将变量定义为只读(不可修改和删除),等价于 readonly name。
-x name[=value] 将变量设置为环境变量,等价于 export name[=value]。
  • 例如:
#将变量声明为整数并进行计算。
[root@localhost testshell]# touch test5.sh && vi test5.sh
#!/bin/bash
declare -i x y z
x=6
y=6
z=$x*$y
echo $z
#运行该脚本
[root@localhost testshell]# . test5.sh
36

#将变量定义为只读变量。
[root@localhost testshell]# declare -r x=8
[root@localhost testshell]# x=9
-bash: x: 只读变量

#显示变量的属性和值。
[root@localhost testshell]# declare -p x
declare -ir x="8"

参考文献:
Shell内建命令(内置命令)

下一篇:Shell学习-07-数学运算

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123687.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!