bash内置命令

 

linux内置命令

当登陆Linux系统时,会为用户分配一个shell。如果在/etc/passwd中该用户配置的shell为 /bin/bash ,那么就为用户分配一个bash shell,当登陆用户的身份审核通过后,就会加载bash进程,bash进程再加载它的各个配置文件(/etc/profile、/etc/profile.d/*.sh、~/.bashrc等),从而配置好bash的执行环境。

bash内置命令和普通的命令都能在bash环境下执行,并实现它们对应的功能。但它们却有很大区别,最典型的一个区别是ps等工具能捕捉到普通命令的进程,却捕捉不到bash内置命令的进程。

Shell脚本中命令运行时若不用创建子进程则是内置命令;—shell把它们当成脚本中的函数处理; 内置命令在目录列表时是看不见的,它们由Shell本身提供。

内置命令由shell程序识别并在shell程序内部完成运行,通常在linux系统加载运行时shell就被加载并驻留在系统内存中。内部命令是写在bashy源码里面的,其执行速度比外部命令快,因为解析内部命令shell不需要创建子进程

bash内置命令和普通命令不一样。普通命令可以直接执行,不依赖于某种执行环境。例如,sleep命令,可以直接以pid=1的init/systemd为父进程而执行。那些daemon类的服务进程更是如此,它们不依赖于终端,也不依赖于执行环境,只要给它们配置好,就可以直接找init/systemd当爹。

而bash内置命令,既然称之为"bash内置命令",顾名思义是bash内置的。当我们在当前bash环境下执行bash内置命令,经过shell的一轮解析之后,发现这是个bash内置命令,于是直接在当前bash进程的内部调用执行它们。所以bash内置命令自身是没有进程的。

bash内置命令的执行是由bash带着它们执行的。这些bash内置命令无论什么时候执行都必须先找bash为它们提供执行环境

如果是在当前shell中放进后台,则这个爹是新生成的bash进程。这个新的bash进程只负责一件事,就是负责这个后台,为它的孩子们提供它们依赖的bash环境。
如果是在脚本中放进后台,则这个爹就是脚本进程。由于脚本不是内置命令,它能直接负责这个后台(因为脚本进程也算是bash进程的特殊变体,也相当于一个新的bash进程)

作业是指"能选择性地停止、暂停、继续运行某个进程的能力",通俗地说就是作业用来控制谁可以获得终端(前台进程)、谁不能获得终端(后台进程)。

当一个进程的进程组号和当前终端的进程组号相同,则这个进程是前台进程,受键盘影响,可以读、写终端。当一个进程的进程组号和当前终端的进程组号不同时,则这个进程是后台进程,它们不受键盘影响,读、写终端时需要发送特定的信号。

后台任务依赖于当前所在的终端,因为它可能会恢复到前台去运行。但当前终端往往会和一个bash进程关联绑定,该bash进程具有当前终端的控制权。当一个进程是前台进程时,它是在当前bash进程下执行的,此时该bash进程失去控制权,也就是被阻塞。当进程进入后台,意味着它会离开当前bash环境,进入后台执行环境,因为只有离开当前bash环境,才能立刻将终端的控制权还给当前bash进程

bash内置命令要放入后台,放入后台意味着它要离开当前bash环境,所以它在进入后台开始执行前,必须新找一个bash爹为它提供执行环境,所以它新生成了一个bash进程。其实这个新的bash和当前bash进程是不一样的,这个新bash是非交互式的shell,可以直接使用kill -15杀掉这个新bash进程。而交互式shell下,在没有设置任何陷阱(trap)时,默认是忽略TERM信号的,无法直接kill -15杀掉一个当前活动的bash进程。普通命令的进程进入后台时,它不是一定要挂在当前bash进程下的,甚至它不再依赖于终端,之所以还暂时挂在当前bash进程下,是因为它还是个后台任务,还需要被当前bash管理。例如将其放回前台,查看后台任务列表,如果不在当前bash进程下,当前bash进程必然无法管理它。

杀掉终端进程和杀掉当前bash进程对后台任务的影响不一样:杀掉当前bash进程后,后台任务会挂在init/systemd下,而杀掉终端后,后台任务也会中止。后台任务依赖于当前所在的终端。但当前终端往往会和一个bash进程关联绑定,该bash进程具有当前终端的控制权,所以杀掉终端进程和杀掉当前所在bash进程都能结束一个终端。

杀掉终端进程时,终端进程会给自己进程组内的所有进程包括bash进程发送一个SIGHUP信号,正是因为收到这个信号,进程组内的所有进程才会中止。

 

如何让后台进程不依赖于终端:

1.将后台任务放入子shell。

因为将后台任务放入子sh(脚本或者()),当子shell结束后,其内后台任务会立即挂到init/systemd下,这样就脱离了终端。

2.利用bash内置命令disown将任务移出后台或设置为忽略SIGHUP信号

 当进程disown移出后台后,虽然暂时还挂在bash进程下,但结束终端进程时,该进程将挂到init/systemd下。所以,这样做也将脱离终端。或者,disown -h设置后台作业忽略SIGHUP信号。前文说过,当终端进程退出时,将会向终端进程组中的所有进程发送SIGHUP信号,收到这些信号,终端下的所有进程都会终止。然后关闭终端,会发现sleep进程也将挂在init/systemd下。

bash内置命令:bash, :, ., [, alias, bg, bind, break, builtin, caller, cd, command, compgen, complete, compopt, continue, declare, dirs, disown, echo, enable, eval, exec, exit, export, false, fc, fg, getopts, hash, help, history, jobs, kill, let, local, logout, mapfile, popd, printf, pushd, pwd, read, readonly, return, set, shift, shopt, source, suspend, test, times, trap, true, type, typeset, ulimit, umask, unalias, unset, wait】

保留关键字:! case do done elif else esac fi for function if in select then until while { } time [[ ]]

      . 使Shell读入指定的Shell程序文件并依次执行文件中的所有语句
     :空,永远返回为空   
break退出f
bg把作业放到后台
bind显示当前的套接字与函数的绑定情况
cd切换目录   
continue 执行循环的下一步
dirs显示当前记录的目录
echo反馈信息到标准输出 
enable启用或者禁用shell内置命令
exec  当Shell执行到exec语句时,不会去创建新的子进程,而是转去执行指定的命令,当指定的命令执行完时,该进程(也就             是      最初的Shell)就终止了,所以Shell程序中exec后面的语句将不再被执行
 exit退出Shell程序。在exit之后可有选择地指定一个数位作为返回状态
 exportShell可以用export把它的变量向下带入子Shell,从而让子进程继承父进程 中的环境变量。但子Shell不能用export把                     它   的变量向上带入父Shell   
env 显示或者设置用户变量
eval   读取参数,执行结果命令   
help显示所有内置命令列表,或者显示一个具体命令的用法
history查看以往使用的所有命令
kill想由PID 号或作业号指定的进程发送信号,输入kill -l信号列表
pwd  当前目录     
printf显格式字符串,格式:printf   "格式字符串"  参数
read从标准输入读取一行文本
readonly 将一个用户定义的Shell变量标识为不可变。不带任何参数的readonly命令将显示出所有只读的变量
return 返回函数值 
set 用于显示或者清除shell环境变量;set、env、export设置的变量均可用unset来清除;
shift语句按如下方式重新命名所有的位置参数变量,即2成为2成为1,3成为3成为2…在程序中每使用一次shift语句,都使所有的位置参数依次向左移动一个位置,并使位置参数$#减1,直到减到0为止    
test条件测试
times 显示用户脚本或任何系统命令的运行时间,第一行给出shell消耗时间 第二行给出运行命令消耗的时间
trap     当前捕获信号时运行指定命令  ulimit  显示或者设置shell资源
suspend终止当前shell的运行
wait  使Shell等待在后台启动的所有子进程结束。wait的返回值总是真
ulimit显示或者设置进程可用资源的最大限额
unalias取消所有的命名别名设置

注:

 1.在命令前输入command即可以禁止shell函数查找     即command cd  目录

  2.在命令前输入builtin,可以强制bash使用内部命令   即builtin echo -n "builtin command echo" # 使用内置命令echo

  3.使用外部命令的全路径就可以使用外部命令             即/bin/echo hi

  4.使用enable -n将某个/某几个内置bash命令无效化

     enable的影响将一直持续到用户退出shell为止   即  enable -n ls   使ls内置无效                                                                                                                                                                            enable ls ch重新启动ls   

                                                                                      enable  -a列出所有命令状态

 

 

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凤舞飘伶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值