shell(shell简介)
阅读原文时间:2023年07月08日阅读:1

Shell 是一个 C 语言编写的脚本语言,它是用户与 Linux 的桥梁,用户输入命令交给 Shell 处理,shell是一个命令解释器,是一个工具箱, Shell 将相应的操作传递给内核(Kernel),内核把处理的结果输出给用户。

下面是流程示意图:

1, 在shell中可执行的命令有两类:

第一类:内部命令shell自带的命令,所以执行更快

第二类:外部命令,在文件系统路径下有对应的可执行程序文件,执行需要将硬盘中的文件加载到内存再执行所以比较慢,

help  #查看内部命令列表
enable  #查看可用的内部命令/管理内部命令
enable CMD #启用某CMD
enable -n CMD #禁用某CMD
enable -n #查看所有禁用的命令
type COMMAND  #区分命令为外部还是内部
which CMD #查看命令来源

例子

[root@c43i08102.cloud.i09.amtest90 /root]
#type pwd
pwd is a shell builtin
[root@c43i08102.cloud.i09.amtest90 /root]
#type -a pwd
pwd is a shell builtin
pwd is /usr/bin/pwd
[root@c43i08102.cloud.i09.amtest90 /root]
#type init
init is /sbin/init
[root@c43i08102.cloud.i09.amtest90 /root]
#which pwd
/usr/bin/pwd
[root@c43i08102.cloud.i09.amtest90 /root
#which init
/sbin/init
[root@c43i08102.cloud.i09.amtest90 /root]
#whereis init
init: /usr/sbin/init /etc/init.d /usr/share/man/man1/init.1.gz

2,外部命令的执行--hash缓存表

系统的初始hash表为空,当外部命令执行时,默认会从PATH路径下寻找命令(shell可以看作是工具箱(/usr/local/bin usr/ali/bin等),是通过$PATH变量在多个工具箱来寻找命令,并执行,找不到则报错),找到后会将命令记录到hash表中,当再次使用该命令时,shell解释器会首先查看hash表,存在即执行,不存在则取PATH路径寻找。

[root@c43i08102.cloud.i09.amtest90 /root]
#echo $PATH
/usr/ali/bin:/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/opt/satools:/root/bin


[root@c43i08102.cloud.i09.amtest90 /root]
#hash   #查看hash缓存
hits    command
   1    /usr/bin/whereis

[root@c43i08102.cloud.i09.amtest90 /root]
#hash -l
builtin hash -p /usr/bin/whereis whereis

Shell 是一个程序,一般都是放在/bin或者/user/bin目录下,当前 Linux 系统可用的 Shell 都记录在/etc/shells文件中,可以使用 cat 命令查看它;

╭─root@localhost.localdomain ~
╰─➤  cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/zsh

查看当前 Linux 的默认 Shell,那么可以输出 SHELL 环境变量:

╭─root@localhost.localdomain ~
╰─➤  echo $SHELL
/bin/zsh

执行shell脚本三种方法

source filename

source filename:这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。

bash filename

bash filename 重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell。

./filename

./filename:当shell脚本具有可执行权限时,用bash filename与./filename执行脚本是没有区别的;./filename是因为当前目录没有在PATH中,所以”.”是用来表示当前目录的。

选项:-x 显示执行过程

实例:

╭─root@localhost.localdomain ~
╰─➤  bash -x back.sh
++ date '+\%F_\%T'
+ echo '50 23 * * 7 /usr/bin/tar -czf test_\2019-06-04_\08:21:40'

子shell和父shell

特点:子shell新建变量在父shell中不会生效

╭─root@localhost.localdomain ~
╰─➤  pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
        ├─auditd───{auditd}
        ├─chronyd
        ├─crond
        ├─dbus-daemon
        ├─gssproxy───5*[{gssproxy}]
        ├─login───zsh
        ├─lvmetad
        ├─master─┬─pickup
        │        └─qmgr
        ├─polkitd───5*[{polkitd}]
        ├─rpcbind
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───zsh───pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─tuned───4*[{tuned}]
        └─vmtoolsd───{vmtoolsd}
╭─root@localhost.localdomain ~
╰─➤  bash
[root@localhost ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
        ├─auditd───{auditd}
        ├─chronyd
        ├─crond
        ├─dbus-daemon
        ├─gssproxy───5*[{gssproxy}]
        ├─login───zsh
        ├─lvmetad
        ├─master─┬─pickup
        │        └─qmgr
        ├─polkitd───5*[{polkitd}]
        ├─rpcbind
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───zsh───bash───pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─tuned───4*[{tuned}]
        └─vmtoolsd───{vmtoolsd}
[root@localhost ~]# age=25
[root@localhost ~]# echo $age
25
[root@localhost ~]# exit
exit
╭─root@localhost.localdomain ~
╰─➤  echo $age

命名约定1:见名知意

命令约定2:以.sh 结尾

内容编写:

#!/bin/bash      #1. 声明shell解释器,是shell脚本的第一行,称为释伴(shebang)行。
                 #2. 这里#符号叫做hash,而! 叫做 bang。它的意思是命令通过 /bin/bash 来执行
echo "Hello World"     #执行的command

脚本规范

  1. 第一行一般为调用使用的语言
  2. 程序名,避免更改文件名无法找到正确的文件
  3. 版本号
  4. 更改后的时间
  5. 作者相关信息
  6. 该程序的作用及注意事项
  7. 最后是更版本更新的简要说明

第一种方式:

bash ken.sh &

第二种方式:

nohup bash ken.sh &