欢迎您的光临,本博所发布之文章皆为作者亲测通过,如有错误,欢迎通过各种方式指正。由于本站位于香港虚拟主机,故速度比较慢。

教程  Shell&Shell脚本基础教程——内置命令

Shell 本站 229 0评论

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


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


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

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


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


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


Shell 的内建命令众多,在 3.2.25 版本的 Bash 中有几十个,如下所示:

bash:.[aliasbgbind
breakbuiltincdcommandcompgencompletecontinue
declaredirsdisownechoenableevalexec
exitexportfcfggetoptshashhelp
historyjobskillletlocallogoutpopd
printfpushdpwdreadreadonlyreturnset
shiftshoptsourcesuspendtesttimestrap
typetypesetulimitumaskunaliasunsetwait

.:执行当前进程环境中的程序。同source。

. file:dot命令从文件file中读取命令并执行。

: 空操作,返回退出状态0。

alias:显示和创建已有命令的别名。

bg:把作业放到后台。

bind:显示当前关键字与函数的绑定情况,或将关键字与readline函数或宏进行绑定。

break:从最内层循环跳出。

builtin [sh-builtin [args]]:运行一个内置Shell命令,并传送参数,返回退出状态0。当一个函数与一个内置命令同名时,该命令将很有用。

cd [arg]:改变目录,如果不带参数,则回到主目录,带参数则切换到参数所指的目录。

command comand [arg]:即使有同名函数,仍然执行该命令。也就是说,跳过函数查找。

declare [var]:显示所有变量,或用可选属性声明变量。

dirs:显示当前记录的目录(pushd的结果)。

disown:从作业表中删除一个活动作业。

echo [args]:显示args并换行。

enable:启用或禁用Shell内置的命令。

eval [args]:把args读入Shell,并执行产生的命令。

exec command:运行命令,替换掉当前Shell。

exit [n]:以状态n退出Shell。

export [var]:使变量可被子Shell识别。

fc:历史的修改命令,用于编辑历史命令。

fg:把后台作业放到前台。

getopts:解析并处理命令行选项。

hash:控制用于加速命令查找的内部哈希表。

help [command]:显示关于内置命令的有用信息。如果指定了一个命令,则将显示该命令的详细信息。

history:显示带行号的命令历史列表。

jobs:显示放到后台的作业。

kill [-signal process]:向由PID号或作业号指定的进程发送信号。输入kill-l查看信号列表。

let:用来计算算术表达式的值,并把算术运算的结果赋给变量。

local:用在函数中,把变量的作用域限制在函数内部。

logout:退出登录Shell。

popd:从目录栈中删除项。

pushd:向目录栈中增加项。

pwd:打印出当前的工作目录。

read [var]:从标准输入读取一行,保存到变量var中。

readonly [var]:将变量var设为只读,不允许重置该变量。

return [n]:从函数中退出,n是指定给return命令的退出状态值。

set:设置选项和位置参量。

shift [n]:将位置参量左移n次。

stop pid:暂停第pid号进程的运行。

suspend:终止当前Shell的运行(对登录Shell无效)。

test:检查文件类型,并计算条件表达式。

times:显示由当前Shell启动的进程运行所累计用户时间和系统时间。

trap [arg] [n]:当Shell收到信号n(n为0、1、2或15)时,执行arg。

type [command]:显示命令的类型,例如:pwd是Shell的一个内置命令。

typeset:同declare。设置变量并赋予其属性。

ulimit:显示或设置进程可用资源的最大限额。

umask [八进制数字]:用户文件关于属主、属组和其他用户的创建模式掩码。

unalias:取消所有的命令别名设置。

unset [name]:取消指定变量的值或函数的定义。

wait [pid#n]:等待pid号为n的后台进程结束,并报告它的结束状态。


1.alias:给命令创建别名


alias 用来给命令创建一个别名。若直接输入该命令且不带任何参数,则列出当前 Shell 环境中使用了哪些别名。现在你应该能理解类似ll这样的命令为什么与ls -l的效果是一样的吧。


下面让我们来看一下有哪些命令被默认创建了别名:

[root@localhost ~]# alias
alias cp='cp -i'
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'


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


使用 alias 当然也可以自定义别名,比如说一般的关机命令是shutdown-h now,写起来比较长,这时可以重新定义一个关机命令,以后就方便多了。使用 alias 定义的别名命令也是支持 Tab 键补全的,如下所示:

alias myShutdown='shutdown -h now'


注意,这样定义别名只能在当前 Shell 环境中有效,换句话说,重新登录后这个别名就消失了。为了确保永远生效,可以将该别名手动写入到用户主目录中的.bashrc文件。

将别名写入.bashrc文件后的效果如下所示:

# .bashrc
# User specific aliases and functions
alias myShutdown='shutdown -h now'
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi


unalias:删除别名

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

第一种用法是在命令后跟上某个命令的别名,用于删除指定的别名。

第二种用法是在命令后接-a参数,删除当前 Shell 环境中所有的别名。


同样,这两种方法都是在当前 Shell 环境中生效的。要想永久删除在.bashrc文件中定义的别名,只能进入该文件手动删除。

# 删除 ll 别名

[root@e-bai ~]# unalias ll

# 再次运行该命令时,报“找不到该命令”的错误,说明该别名被删除了

[root@e-bai ~]# ll

-bash: ll: command not found


2.echo命令:输出字符串


用来在终端输出字符串,并在最后默认加上换行符。请看下面的例子:

#!/bin/bash
name="Shell教程"
url="http://c.biancheng.net/shell/"
echo "读者,你好!"  #直接输出字符串
echo $url  #输出变量
echo "${name}的网址是:${url}"  #双引号包围的字符串中可以解析变量
echo '${name}的网址是:${url}'  #单引号包围的字符串中不能解析变量

运行结果:

读者,你好!

http://c.biancheng.net/shell/

Shell教程的网址是:http://c.biancheng.net/shell/

${name}的网址是:${url}


不换行

echo 命令输出结束后默认会换行,如果不希望换行,可以加上-n参数,如下所示:

#!/bin/bash
name="Tom"
age=20
height=175
weight=62
echo -n "${name} is ${age} years old, "
echo -n "${height}cm in height "
echo "and ${weight}kg in weight."
echo "Thank you!"

运行结果:

Tom is 20 years old, 175cm in height and 62kg in weight.

Thank you!


输出转义字符

默认情况下,echo 不会解析以反斜杠\开头的转义字符。比如,\n表示换行,echo 默认会将它作为普通字符对待。请看下面的例子:

[root@localhost ~]# echo "hello \nworld"
hello \nworld


我们可以添加-e参数来让 echo 命令解析转义字符。例如:

[root@localhost ~]# echo -e "hello \nworld"
hello
world


\c 转义字符

有了-e参数,我们也可以使用转义字符\c来强制 echo 命令不换行了。请看下面的例子:

#!/bin/bash
name="Tom"
age=20
height=175
weight=62
echo -e "${name} is ${age} years old, \c"
echo -e "${height}cm in height \c"
echo "and ${weight}kg in weight."
echo "Thank you!"

运行结果:

Tom is 20 years old, 175cm in height and 62kg in weight.

Thank you!


3.exit命令:退出Shell


exit 是一个 Shell 内置命令,用来退出当前 Shell:

如果在终端中直接运行 exit 命令,会退出当前登录的 Shell,并关闭终端;

如果在 Shell 脚本中出现 exit 命令,会停止执行后边的所有代码,立即退出 Shell 脚本。


exit 命令可以接受的参数是一个状态值 n,代表退出时的状态。如果不指定,默认状态值是 0。


以下面的 Shell 脚本(命名为 demo.sh)为例:

#!/bin/bash
echo "befor exit"
exit 8
echo "after exit"

运行该脚本:

[root@localhost ~]# bash ./demo.sh

befor exit


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

注意,必须将 Shell 脚本作为解释器参数来运行,不能将 Shell 脚本作为可执行程序运行。这两种运行方式我们已在《执行Shell脚本》中讲到。

我们可以紧接着使用 $? 来获取 demo.sh 的退出状态:

[root@localhost ~]# echo $?

8


4.ulimit命令:显示并设置进程资源限度


系统的可用资源是有限的,如果不限制用户和进程对系统资源的使用,则很容易陷入资源耗尽的地步,而使用 ulimit 命令可以控制进程对可用资源的访问(ulimit 是一个 Shell 内置命令)。


默认情况下 Linux 系统的各个资源都做了软硬限制,其中硬限制的作用是控制软限制(换言之,软限制不能高于硬限制)。使用ulimit -a可以查看当前系统的软限制,使用命令ulimit -a –H可查看系统的硬限制。


下面是该命令的运行结果,笔者对每行输出都做了注解。

[root@localhost ~]# ulimit -a
#core文件大小,单位是block,默认为0
core file size          (blocks, -c) 0
#数据段大小,单位是kbyte,默认不做限制
data seg size           (kbytes, -d) unlimited
#调度优先级,默认为0
scheduling priority             (-e) 0
#创建文件的大小,单位是block,默认不做限制
file size               (blocks, -f) unlimited
#挂起的信号数量,默认是8192
pending signals                 (-i) 8192
#最大锁定内存的值,单位是kbyte,默认是32
max locked memory       (kbytes, -l) 32
#最大可用的常驻内存值,单位是kbyte,默认不做限制
max memory size         (kbytes, -m) unlimited
#最大打开的文件数,默认是1024
open files                      (-n) 1024
#管道最大缓冲区的值
pipe size            (512 bytes, -p) 8
#消息队列的最大值,单位是byte
POSIX message queues     (bytes, -q) 819200
#程序的实时性优先级,默认为0
real-time priority              (-r) 0
#栈大小,单位是kbyte
stack size              (kbytes, -s) 10240
#最大cpu占用时间,默认不做限制
cpu time               (seconds, -t) unlimited
#用户最大进程数,默认是8192
max user processes              (-u) 8192
#最大虚拟内存,单位是kbyte,默认不做限制
virtual memory          (kbytes, -v) unlimited
#文件锁,默认不做限制
file locks                      (-x) unlimited


5.history命令:查看历史命令


Bash 有完善的历史命令,这对于简化管理操作、排查系统错误都有重要的作用,而且使用简单方便,建议大家多使用历史命令。系统保存的历史命令可以使用 history 命令查询,命令格式如下:

[root@localhost ~]# history [选项] [历史命令保存文件]


选项:

-c:清空历史命令;

-w:把缓存中的历史命令写入历史命令保存文件中。如果不手工指定历史命令保存文件,则放入默认历史命令保存文件 ~/.bash_history 中;


如果 history 命令直接回车,则用于查询系统中的历史命令,命令如下:

[root@localhost ~]# history
…省略部分输出…
421 chmod 755 hello.sh
422/root/sh/hello.sh
423 ./hello.sh
424 bash hello.sh
425 history


这样就可以查询我们刚刚输入的系统命令,而且每条命令都是有编号的。历史命令默认会保存 100 条,这是通过环境变量 HISTSIZE 进行设置的,我们可以在环境变量配置文件 /etc/profile 中进行修改。命令如下:

[root@localhost ~]#vi /etc/profile
…省略部分输出…
HISTSIZE=1000
…省略部分输出…


如果觉得 1000 条历史命令不够曰常管理使用,那么是否可以増加呢?只需修改 /etc/profile 环境变量配置文件中的 HISTSIZE 字段即可,不过我们需要考虑一个问题:这些历史命令是保存在哪里的呢?如果历史命令是保存在文件中的,那么历史命令的保存数量可以放心地增加,因为哪怕有几万条历史命令,也不会占用多大的硬盘空间。但是,如果历史命令是保存在内存当中的,就要小心了。好在历史命令是保存在 ~/.bash_history 文件中的,所以可以放心地把总历史命令条数改大,比如 10 000 条,命令如下:

[root@localhost ~]#vi /etc/profile
…省略部分输出…
HISTSIZE=10000
…省略部分输出…


大家需要注意,每个用户的历史命令是单独保存的,所以每个用户的家目录中都有 .bash_history 这个历史命令文件。


如果某个用户的历史命令总了历史命令保存条数,那么新命令会变成最后一条命令,而最早的命令则被删除。假设系统保存 1000 条历史命令,而我已经保存了 1000 条历史命令,那么我新输入的命令会被保存成第 1000 条命令,而最早的第一条命令会被删除。


6.grep命令:提取符合条件的字符串行


grep 的作用是在文件中提取和匹配符合条件的字符串行。命令格式如下:

[root@localhost ~]# grep [选项] "搜索内容" 文件名

选项:

-A 数字:列出符合条件的行,并列出后续的 n 行;

-B 数字:列出符合条件的行,并列出前面的 n 行;

-c:统计找到的符合条件的字符串的次数;

-i:忽略大小写;

-n:输出行号;

-v:反向査找;

--color=auto:搜索出的关键字用颜色显示;


举几个例子:

[root@localhost ~]# grep "/bin/bash" /etc/passwd
#查找用户信息文件/etc/passwd中有多少可以登录的用户
root:x:0:0:root:/root:/bin/bash
user1:x:500:500::/home/user1:/bin/bash
user2:x:501:501::/home/user2:/bin/bash


grep 是行提取命令,所以只要一行数据中包含"搜索内容",就会列出整行的数据。在这个例子中,会在 /etc/passwd 文件中列出所有包含"/bin/bash"的行,而我们已知只有可登录用户的 Shell 才是"/bin/bash",而伪用户的 Shell 是"/sbin/nologin",所以这条命令会列出当前系统中所有可以登录的用户。


再举几个例子:

[root@localhost ~]# grep -A 3 "root" /etc/passwd
#查找包含"root"的行,并列出后续的3行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@localhost ~]# grep -n "/bin/bash" /etc/passwd
#查找可以登录的用户,并显示行号
1:root:x:0:0:root:/root:/bin/bash
31:user1:x:500:500::/home/user1:/bin/bash 32:user:x:501:501::/home/user:/bin/bash
[root@localhost ~]# grep -v "/bin/bash" /etc/passwd
#查找不包含"/bin/bash"的行,其实就是列出所有的伪用户
bin:x:1:1 :bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin
…省略部分输出…


7.find和grep命令的区别

find 和 grep 同样都是搜索命令,两者有什么区别呢?


find命令

find 命令用于在系统中搜索符合条件的文件名,如果需要模糊査询,则使用通配符进行匹配。搜索时文件名是完全匹配的。


完全匹配是什么意思呢?举个例子:

[root@localhost ~]# touch abc
#建立文件abc
[root@localhost ~]# touch abcd
#建立文件abed
[root@localhost ~]# find. -name "abc"
./abc
#搜索文件名是abc的文件,只会找到abc文件,而不会找到abcd文件
#虽然abcd文件名中包含abc,但是find是完全匹配的,只有和要搜索的数据完全一样,才能找到


完全匹配的意思就是:搜索的内容必须和原始文件一模一样,才能被搜索到。

如果想要找到 abcd 文件,就必须依靠通配符,如 find.-name"abc*"。


注意,find 命令是可以通过 -regex 选项识别正则表达式规则的,也就是说,find 命令可以按照正则表达式规则匹配,而正则表达式是模糊匹配。但是对初学者而言,find 和 grep 命令本身就不好理解,所以在这里只按照通配符规则来进行 find 查询。


grep命令

grep 命令用于在文件中搜索符合条件的字符串,如果需要模糊査询,则使用正则表达式进行匹配。搜索时字符串是包含匹配的。


grep 命令和 find 命令不一样,使用 grep 命令在文件中査找符合条件的字符串时,只要搜索的内容包含在数据行中,就会列出整行内容。举个例子:

[root@localhost ~]# echo abc > test
#在test文件中写入abc数据
[root@localhost ~]# echo abed >> test
#在test文件中追加abcd数据
[root@localhost ~]# grep "abc" test
abc
abcd
#grep命令査找时,只要数据行中包含abc,就会列出
#所以abc和abcd都可以查询到


通过这两个例子,大家就可以知道完全匹配和包含匹配的区别了。


8.source命令:使环境变量配置文件强制生效


source 命令会强制执行脚本中的全部命令,而忽略脚本文件的权限。该命令主要用于让重新配置的环境变量配置文件强制生效。

source 命令格式如下:

[root@localhost ~]# source 配置文件

[root@localhost ~]#.配置文件


举个例子:

[root@localhost ~]# source -/.bashrc


[raot@localhost ~]#. ~/.bashrc

"."就是 source 命令,使用哪种方法都是可以的。原来修改了环境变量配置文件,如果要想让其生效,则必须注销或重启系统。现在只要使用 source 命令就可以省略注销或重启的过程,更加方便。


9.read命令:接收键盘或其它文件描述符的输入


read 命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read 命令将数据放入一个标准变量中。


read 命令格式如下:

[root@localhost ~]# read [选项] [变量名]

选项:

-p "提示信息":在等待read输入时,输出提示信息;

-t 秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间;

-n 字符数:read命令只接收指定的字符数就会执行;

-s: 隐藏输入的数据,适用于机密信息的输入;


变量名:

· 变量名可以自定义。如果不指定变量名,则会把输入保存到默认变量REPLY中;

· 如果只提供了一个变量名,则将整个输入行赋予该变量;

· 如果提供了一个以上的变量名,则输入行分为若干字,一个接一个地赋予各个变量,而命令行上的最后一个变量取得剩余的所有字;


例如:

[root@localhost sh]# vi read.sh
#!/bin/bash
read -t 30 -p "Please input your name:" name
#提示"请输入姓名"并等待30秒,把用户的输入保存到变量name中
echo "Name is $name"
#看看变量"$name"中是否保存了你的输入
read -s -t 30 -p "Please enter your age:" age
#提示"请输入年龄"并等待30秒,把用户的输入保存到变量age中
#年龄是隐私,所以我们用"-s"选项隐藏输入
echo -e "n"
#调整输出格式,如果不输出换行,则一会儿的年龄输出不会换行
echo "Age is $age"
read -n 1 -t 30 -p "Please select your gender[M/F]:" gender
#提示"请选择性别"并等待30秒,把用户的输入保存到变量gender中
#使用"-n 1"选项只接收一个输入字符就会执行(无须按回车键)
echo -e "\n"
echo "Sex is $gender"

执行一下这个脚本:

[root@localhost sh]# chmod 755 read.sh
赋予执行权限
[root@localhost sh]#./read.sh
#执行脚本
Please input your name: zhang san
#在read的提示界面输入姓名
Name is zhang san
#"$name"变量中保存了我们的输入
Please enter your age:
#因为加入了"-s"选项,所以输入不会显示在命令行上
Age is 18
#"$age"变量中保存了我们的输入
Please select your gender[M/F]: M
#因为加入了"-n 1"选项,所以只能输入一个字符
Sex is M
# "$gender"变量中保存了我们的输入


read 命令并不难,却是接收键盘输入的重要方法,要熟练使用。


10.Shell(Bash)多命令顺序执行方法


在 Bash 中,如果需要让多条命令顺序执行,则有这样方法,如表 1 所示。

表 1 多命令顺序执行的方法
多命令执行符格 式作 用
命令1 ; 命令2多条命令顺序执行,命令之间没有任何逻辑关系
&&命令1 && 命令2如果命令1正确执行($?=0),则命令2才会执行
如果命令1执行不正确($?≠0),则命令2不会执行
II命令1 || 命令2如果命令1执行不正确($?≠0),则命令2才会执行
如果命令1正确执行($?=0),则命令2不会执行


";"多命令顺序执行

如果使用";"连接多条命令,那么这些命令会一次执行,但是各命令之间没有任何逻辑关系,也就是说,不论哪条命令报错了,后面的命令仍会依次执行。举个例子:

[root@localhost ~]# ls ; date; cd /user; pwd
anaconda-ks.cfg err.log install.log install.log.syslog list.log out.log
sh
#ls命令正确执行
2013年 10月 21 日星期一 11:35:57 CST
#date命令正确执行
-bash: cd: /user:没有那个文件或目录
#cd命令报错,因为没有/user目录
/root
#虽然cd命令报错,但是并不影响pwd命令的执行

这就是";"的作用,不论前一条命令是否正确执行,都不影响后续命令的执行。再举一个例子:

[root@localhost ~]# date; dd if=/dev/zero of=/root/
testfile bs=1k count=100000;
date
#创建一个大小为100MB的文件,通过";"可以确定需要多长时间
2013 年 10月21日 星期一 11:41:54 CST
#第一条date命令执行
记录了 100000+0的读入
记录了 100000+0的写出
102400000字节(102 MB)已复制,2.09394 秒,48.9 MB/秒
#dd命令执行
2013 年 10月 21 日星期一11:41:56 CST #第二条date命令执行,可以判断dd命令用时2秒
[root@localhost ~]# ll -h testfile
-rw-r--r--. 1 root root 98M 10月21 11:41 testfile
#大小为100MB的testfile文件已经建立

当我们需要一次执行多条命令,而这些命令之间又没有可逻辑关系时,就可以使用";"来连接多条命令。


"&&"逻辑与

如果使用"&&"连接多条命令,那么这些命令之间就有逻辑关系了。只有第一条命令正确执行了,"&&"连接的第二条命令才会执行。那么,命令 2 是如何知道命令 1 正确执行了呢?

这就需要 Bash 的预定义变量 $? 的支持了,如果 $? 返回值是 0,则证明上一条命令正确执行;如果 $? 返回值是非 0,则证明上一条命令执行错误。

举个例子:

[root@localhost ~]# cp /root/test /tmp/test && rm -rf/ root/test && echo yes
cp:无法获取"/rooWest"的文件状态(stat):没有那个文件或目录
#复制/root/test到/tmp/test,如果命令成功则删除原文件,并打印"yes"
#因为/root/test文件不存在,所以第一条命令执行不正确,第二和第三条命令也都不执行
[root@localhost ~]# ls /tmp/
#在/tmp/目录中并没有建立test文件
[root@localhost ~]# touch /root/test
#建立/root/test文件
[root@localhost ~]# cp /root/test /tmp/test && rm -rf/ root/test && echo yes
yes
#第一条命令正确执行后,第二和第三条命令都正确执行
#所以打印了"yes"
[root@localhost ~]# ll /root/test
ls:无法访问/root/test:没有那个文件或目录
#源文件/root/test消失,因为第二条命令rm正确执行
[root@localhost ~]# ll /tmp/test
-rw-r--r--. 1 root root 010月 2113:16/tmp/test
#在/temp/目录中正确建立了test文件

再举一个例子,我们在安装源码包时,需要执行"./configure"、"make"和"make install"命令,但是在安装软件时又需要等待较长时间,那么是否可以利用"&&"同时执行这三条命令呢?当然可以了,命令如下:

[root@localhost ~]# cd httpd-2.2.9
[root@localhost httpd-2.2.9]# ./configure --prefix=/usr/ local/apache2 && make && make install

在这里,"\"代表一行命令没有输入结束,因为命令太长了,所以加入"\"字符,可以换行输入。利用"&&"就可以让这三条命令同时执行,然后我们就可以休息片刻,等待命令结束。


不过大家请思考一下,这里是否可以把"&&"替换为或"ll"呢?当然是不行的,这三条安装命令必须在前一条命令正确执行之后,才能执行后一条命令,如果把"&&"替换为";",则不管前命令是否正确执行,后一条命令都会执行。如果把"&&"替换为"||",则只有前一条命令执行错误,后一条命令才会执行。


"||"逻辑或

如果使用"||"连接多条命令,则只有前一条命令执行错误,后一条命令才能执行。举个例子:

[root@localhost ~]#ls /root/test || mkdir/root/tdir
ls:无法访问/root/test:没有那个文件或目录
#因为已经删除了/root/tesy文件,所以用ls命令查看时报错了
#因为第一条命令执行错误,所以第二条命令才正确执行
[root@localhost ~]#ll -d /root/tdir/
drwxr-xr-x. 2 root root 4096 10月21 13:39/root/tdir/
#把root/tdir/目录已经被建立了


"&&"和"||"非常有意思,如果我们想要判断某条命令是否正确执行,就可以这样来做:

[root@localhost ~]# 命令 && echo "yes" || echo "no"

例如:

[root@localhost ~]#ls /root/test && echo "yes"||echo "no"
ls:无法访问/root/test:没有那个文件或目录
no
#因为/root/test文件不存在,第一条命令报错,所以,第二条命令不能正确执行
#因为第二条命令执行错误,所以第三条命令正确执行,打印"no"
[root@localhost ~]# touch /root/test
[root@localhost ~]# ls /root/test && echo "yes" || echo "no"
/root/test
yes
#因为第一条命令正确执行,所以第二条命令正确执行,打印"yes"
#因为第二条命令正确执行,所以第三条命令执行错误


转载请注明: ITTXX.CN--分享互联网 » Shell&Shell脚本基础教程——内置命令

最后更新:2018-12-25 15:25:17

赞 (2) or 分享 ()
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽