🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 简介   shell 是一个交互性命令解释器。   shell 独立于操作系统,Shell 俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器)。它类似于DOS 下的 command 和后来的 cmd.exe。它接收用户命令,然后调用相应的应用程序。 这种设计让用户可以灵活选择适合自己的 shell 。shell 让你在命令行键入命令,经过 shell 解释后传送给操作系统(内核)执行。   **shell是一个命令处理器(command processor)——是一个读入并解释你输入的命令的程序。**除了是一个命令中断器以外,shell 还是一个程序设计语言。你可以编写 shell 可以解释的程序(被称为源程序),这些源程序可以包含 shell 程序设计命令等等。shell 除了解释命令以外,还有其他工作,它也可以配置和编程。   shell 拥有自己的语言允许用户编写程序并以一种复杂方式运行。shell 编程语言具有许多常用的编程语言的特征,例如:循环和控制结构等。用户可以生成像其他应用程序一样复杂的 shell 程序。 ## Linux Shell Shell种类众多,常见的有: **Bourne-Again shell** ( `/bin/bash`) **Bourne shell** (` /usr/bin/sh`或`/bin/sh`,Stephen Bourne,1979年) Korn shell ( usr/bin/ksh,David Korn,80年代中期) POSIX shell ( sh) Shell for Root(/sbin/sh) C shell (包括 /usr/bin/csh and tcsh,Bill Joy,70年代末期) TENEX/TOPS C shell ( tcsh) ... **Bash**,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数 Linux 系统默认的 Shell(GNU Bourne Again Shell)。 > 在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 `#!/bin/sh`,它同样也可以改为`#!/bin/bash`。 > `#!` 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。 # 系统中的 shell 其实 zsh 也是一种 shell ,但是并不是我们系统默认的 shell ,unix 衍生系统的默认 shell 都是 bash 我们看下系统内置了几种 shell: ``` $ cat /etc/shells ``` 使用`bash -version` 命令来查看当前 shell 的版本号 查看当前用的是哪种 shell: ``` $ echo $0 ``` 更换系统的 shell 为 zsh: ~~~shell chsh -s /bin/zsh ~~~ > [linux更换shell为zsh并个性化配置oh my zsh](https://cloud.tencent.com/developer/article/1135521) # bashrc 与 profile 要搞清 bashrc 与 profile 的区别,首先要弄明白什么是交互式 shell 和非交互式 shell,什么是 login shell 和 non-login shell。 交互式模式就是 shell 等待你的输入,并且执行你提交的命令。这种模式被称作交互式是因为 shell 与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当你签退后,shell 也终止了。 shell 也可以运行在另外一种模式:非交互式模式。在这种模式下,shell 不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾,shell 也就终止了。 bashrc 与 profile 都用于保存用户的环境信息,bashrc用于交互式 non-loginshell,而 profile 用于交互式 login shell。 ## 识别 login shell 要识别一个shell是否为login shell,只需在该shell下执行: ``` # echo $0 ``` 如果输出为该 shell 名字,加上一个'-'前缀,则说明该 shell 为 login shell,没有'-'前缀则是 no login。 1. 当 bash 以 login shell 启动时,它会执行`/etc/profile`中的命令,然后`/etc/profile`调用`/etc/profile.d`目录下的所有脚本;然后执行`~/.bash_profile`,`~/.bash_profile`中显式调用`~/.bashrc`,最后`~/.bashrc`又调用`/etc/bashrc`。 2. 非 login 方式启动时,它会调用`~/.bashrc`,随后`~/.bashrc`中调用`/etc/bashrc`,最后`/etc/bashrc`调用所有`/etc/profile.d`目录下的脚本。 ## profile 文件 系统中存在许多 bashrc 和 profile 文件,下面逐一介绍: | 文件 | 描述 | | --- | --- | | `/etc/profile` | 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。并从`/etc/profile.d`目录的配置文件中搜集 shell 的设置。| | `/etc/bashrc` | 为每一个运行`bash` shell的用户执行此文件。当``bash``shell被打开时,该文件被读取。| | `~/.bashrc` | 该文件包含专用于你的 bash shell 的 bash 信息,当登录时以及每次打开新的 shell 时,该文件被读取。 | | `~/.profile`或者`~/.bash_profile` | 用户可以使用该文件输入自己需要使用的 shell 信息,当用户登录时,该文件仅仅执行一次!默认情况下,它设置一些环境变量,执行用户的`.bashrc`文件。| | `~/.bash_logout` | 当每次退出系统(退出``bash``shell)时,执行该文件。 | > 注意:`.profile`是 unix 上才有的;`.bash_profile`是 Linux 下有的(Linux下,用户目录没有`.profile`文件) 。 > 另外,`/etc/profile`中设定的变量(全局)的可以作用于任何用户,而`~/.bashrc`等中设定的变量(局部)只能继承`/etc/profile`中的变量,他们是``"父子"``关系。 > [交互式shell和非交互式shell、登录shell和非登录shell的区别](https://blog.csdn.net/airings/article/details/8756938) > [深入浅出理解交互式shell和非交互式shell、登录shell和非登录shell的区别](https://blog.csdn.net/gui951753/article/details/79154496) ## `.bash_profile`进行个性化设置 每次修改`.bashrc`后,使用`source ~/.bashrc`(或者`. ~/.bashrc`)就可以立刻加载修改后的设置,使之生效。 一般会在`.bash_profile`文件中显式调用`.bashrc`。登陆 linux 启动 bash 时首先会去读取`~/.bash_profile`文件,这样`~/.bashrc`也就得到执行了,你的个性化设置也就生效了。 利用这一特性,可以实现一些个性化设置,如:Linux 系统开机执行自动某个脚本文件等,这在自动化运维方面有一定的用处。 1. 修改`/home/bing/.bashrc`文件: ~~~ sudo vim /home/bing/.bashrc # 在最后添加两句后保存 echo '这句话开机就会启动' # 打印输出 python3 /home/bing/test.py # 执行 test.py 这个脚本,打印输出 hello world! ~~~ 2. 当 Linux 开机后: ```shell 这句话开机就会启动 hello world! ``` 可以看到 Linux 开机后加载了`.bashrc`文件。 > [Linux 中 bashrc 中的 rc 是什么意思](https://blog.csdn.net/u010167269/article/details/52612260) # shell 功能 以下是shell 功能的一个汇总: 查找命令的位置并且执行相关联的程序; 为shell变量赋新值; 执行命令替代; 处理 I/O重定向和管道功能; 提供一个解释性的编程语言界面,包括tests、branches和loops等语句。 当你在命令行中敲入bash命令时,相当于进入bash环境,如果本身就是bash环境,那么就是进入一个子bash环境(相当于开了一个子进程)。 参考:http://bbs.chinaunix.net/thread-2325808-1-1.html # 特殊符号 当我们需要一次执行多个命令的时候,命令之间需要用连接符连接,不同的连接符有不同的效果。下面我们总结一下,加以区分。 (1) `;` 分号,没有任何逻辑关系的连接符。当多个命令用分号连接时,各命令之间的执行成功与否彼此没有任何影响,都会一条一条执行下去。 (2) `||` 逻辑或,当用此连接符连接多个命令时,前面的命令执行成功,则后面的命令不会执行。前面的命令执行失败,后面的命令才会执行。 (3) `&&` 逻辑与,当用此连接符连接多个命令时,前面的命令执行成功,才会执行后面的命令,前面的命令执行失败,后面的命令不会执行,与 || 正好相反。 (4) `|` 管道符,当用此连接符连接多个命令时,前面命令执行的正确输出,会交给后面的命令继续处理。若前面的命令执行失败,则会报错,若后面的命令无法处理前面命令的输出,也会报错。 例`ls | grep *.txt` # 参考 > [第十一章、认识与学习BASH](http://cn.linux.vbird.org/linux_basic/0320bash.php) https://blog.csdn.net/wenlifu71022/article/details/4069929 http://blog.csdn.net/ClementAD/article/details/46793827 http://blog.csdn.net/sinat_30196907/article/details/48436979 http://blog.csdn.net/hack8/article/details/39672145 http://blog.csdn.net/duguduchong/article/details/8486663 http://blog.csdn.net/OldHusband/article/details/69058143 http://blog.csdn.net/sjl110/article/details/72628869 http://blog.csdn.net/China_Guanq/article/details/51726842 http://blog.csdn.net/qq_35242986/article/details/73772212