Shell脚本之四 内建命令

匆匆过客 提交于 2019-12-25 18:12:52

所谓 Shell 内建命令,就是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件。

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

[root@localhost ~]# type cd
cd is a Shell builtin
[root@localhost ~]# type ifconfig
ifconfig is /sbin/ifconfig

由此可见,cd 是一个 Shell 内建命令,而 ifconfig 是一个外部文件,它的位置是/sbin/ifconfig

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

通常来说,内建命令会比外部命令执行得更快,执行外部命令时不但会触发磁盘 I/O,还需要 fork 出一个单独的进程来执行,执行完成后再退出。而执行内建命令相当于调用当前 Shell 进程的一个函数。

接下来的几节我们将重点讲解几个常用的 Shell 内置命令。


一、Shell alias命令

使用 alias 命令自定义别名的语法格式为:

alias new_name='command'

比如,一般的关机命令是shutdown-h now,写起来比较长,这时可以重新定义一个关机命令,以后就方便多了。

alias myShutdown='shutdown -h now'

注意,别名只是临时的,在代码中使用 alias 命令定义的别名只能在当前 Shell 进程中使用,在子进程和其它进程中都不能使用。当前 Shell 进程结束后,别名也随之消失。要想让别名对所有的 Shell 进程都有效,就得把别名写入 Shell 配置文件。


二、Shell echo命令

Shell 的 echo 指令是用于字符串的输出。命令格式:

echo string

您可以使用echo实现更复杂的输出格式控制。注意,echo输出字符串会自动换行。


1. 显示普通字符串

echo "It is a test"

这里的双引号完全可以省略,以下命令与上面实例效果一致:

echo It is a test


2.显示转义字符

echo "\"It is a test\""

结果将是:

"It is a test"

同样,双引号也可以省略。


3.显示变量

read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量。

#!/bin/sh
read name 
echo "$name It is a test"

以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:

$ ./test.sh
OK                     #标准输入
OK It is a test        #输出


4.显示换行

echo -e "OK! \n" # -e 开启转义
echo "It is a test"

输出结果:

OK!

It is a test


5.显示不换行

#!/bin/sh
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"

输出结果:

OK! It is a test


6.显示结果定向至文件

echo "It is a test" > myfile #myfile若不存在,则也会创建myfile文件


7.原样输出字符串,不进行转义或取变量(用单引号)

echo '$name\"'

输出结果:

$name\"


8.显示命令执行结果

echo `date`

注意: 这里使用的是反引号 `, 而不是单引号 '

结果将显示当前日期

Thu Jul 24 10:08:46 CST 2014


echo输出的字符串总结如下表所示:

引号类型 能否引用变量 能否引用符 能否引用文本格式符
单引号
双引号
无引号


三、Shell printf 命令

本章节我们来学习 Shell 的另一个输出命令 printf。printf 命令模仿 C 语言的 printf() 程序。printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。

printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。

printf 命令的语法:

printf  format-string  [arguments...]

参数说明:

  • format-string: 为格式控制字符串
  • arguments: 为参数列表。


实例1

$ echo "Hello, Shell"
Hello, Shell
$ printf "Hello, Shell\n"
Hello, Shell

接下来,我来用一个脚本来体现printf的强大功能:

#!/bin/bash
 
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876 

执行脚本,输出结果如下所示:

姓名     性别   体重kg
郭靖     男      66.12
杨过     男      48.65
郭芙     女      47.99

%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。%-4.2f 指格式化为小数,其中.2指保留2位小数。


实例2

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
 
# format-string为双引号
printf "%d %s\n" 1 "abc"

# 单引号与双引号效果一样 
printf '%d %s\n' 1 "abc" 

# 没有引号也可以输出
printf %s abcdef

# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def

printf "%s\n" abc def

printf "%s %s %s\n" a b c d e f g h i j

# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n" 

执行脚本,输出结果如下所示:

1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j  
 and 0


四、Shell read命令

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

read 命令的用法为:

read [-options] [variables]

options表示选项,如下表所示;variables表示用来存储数据的变量,可以有一个,也可以有多个。options和variables都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量 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 作为输入源,而不是标准输入,类似于重定向。


实例1

使用 read 命令给多个变量赋值:

#!/bin/bash
read -p "Enter some information > " name url age
echo "网站名字:$name"
echo "网址:$url"
echo "年龄:$age"

运行结果:

Enter some information > 博客园 http://cnblogs.com 7
网站名字:博客园
网址:http://cnblogs.com
年龄:7

本例使用了-p选项,该选项会用一段文本来提示用户输入。注意,必须在一行内输入所有的值,不能换行,否则只能给第一个变量赋值,后续变量都会赋值失败。


实例2

在指定时间内输入密码:

#!/bin/bash
if
    read -t 20 -sp "Enter password in 20 seconds(once) > " pass1 && printf "\n" &&  #第一次输入密码
    read -t 20 -sp "Enter password in 20 seconds(again)> " pass2 && printf "\n" &&  #第二次输入密码
    [ $pass1 == $pass2 ]  #判断两次输入的密码是否相等
then
    echo "Valid password"
else
    echo "Invalid password"
fi

运行结果:

#如果两次输入密码相同,运行结果为:
Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)>
Valid password

#如果两次输入密码不同,运行结果为:
Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)>
Invalid password

#如果第一次输入超时,运行结果为:
Enter password in 20 seconds(once) > Invalid password

#如果第二次输入超时,运行结果为:
Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)> Invalid password

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


五、Shell test 命令

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试,一般搭配 if 命令使用。


1.数值测试

实例演示:

num1=100
num2=100
if test $num1 -eq $num2
then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

输出结果:

两个数相等!


2.字符串测试

实例演示:

num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
    echo '两个字符串相等!'
else
    echo '两个字符串不相等!'
fi

输出结果:

两个字符串不相等!


3.文件测试

实例演示:

cd /bin
if test -e ./bash
then
    echo '文件已存在!'
else
    echo '文件不存在!'
fi

输出结果:

文件已存在!


另外,Shell还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:"!"最高,"-a"次之,"-o"最低。例如:

cd /bin
if test -e ./notFile -o -e ./bash
then
    echo '至少有一个文件存在!'
else
    echo '两个文件都不存在'
fi

输出结果:

至少有一个文件存在!


六、Shell test 命令

Shell中的 exit 命令用来退出当前 Shell 进程,并返回一个退出状态;使用 $? 可以接收这个退出状态。exit 退出状态只能是一个介于 0~255 之间的整数,其中只有 0 表示成功,其它值都表示失败。

实例演示:

#!/bin/bash

echo "befor exit"
exit 8
echo "after exit"

运行该脚本:

$ ./test.sh
befor exit

$ echo $?
8

可以看到,"after exit" 并没有输出,这说明遇到 exit 命令后,test.sh 执行就结束了。另外,我们可以紧接着使用 $? 来获取 test.sh 的退出状态。


七、Shell declare 命令

Shell中的 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]。


实例1

将变量声明为整数并进行计算:

#!/bin/bash

declare -i m n ret  #将多个变量声明为整数
m=10
n=30
ret=$m+$n
echo $ret

运行该脚本:

$ ./test.sh
40


实例2

将变量定义为只读变量:

#!/bin/bash

declare -r n=10
n=20

运行该脚本:

$ ./test.sh
bash: n: 只读变量


参考:

Shell echo命令

Shell printf 命令

Shell test 命令

Shell内建命令(内置命令)


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!