1. shell 类型

只要用户登录到某个虚拟控制台终端或是在 GUI 中启动终端仿真器,默认的 shell 程序就会开始运行。

默认的交互 shell 会在用户登录某个虚拟控制台终端或在 GUI 中运行终端仿真器时启动。不过还有另外一个默认 shell 是 /bin/sh,它作为默认的系统 shell,用于那些需要在启动时使用的系统 shell脚本。

$ cat /etc/passwd
[...]
christine:x:1000:1000:Christine,,,:/home/christine:/bin/bash
$
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Apr 22 12:33 /bin/sh -> dash

可以看到,用户 christine 默认的交互 shell 是 /bin/bash,也就是 bash shell。但是作为默认系统shell 的 /bin/sh 被设置为 dash shell。

2. shell 的父子关系

用于登录某个虚拟控制器终端或在 GUI 中运行终端仿真器时所启动的默认的交互 shell,是一个父shell。父 shell 提供 CLI 提示符,然后等待命令输入。

在 CLI 提示符后输入 /bin/bash 命令或其他等效的 bash 命令时,会创建一个新的 shell 程序。这个shell 程序被称为子 shell(child shell)。子 shell 也拥有 CLI 提示符,同样会等待命令输入。

$ ps -f
UID PID PPID C STIME TTY TIME CMD
501 1841 1840 0 11:50 pts/0 00:00:00 -bash
501 2429 1841 4 13:44 pts/0 00:00:00 ps -f
$
$ bash
$
$ ps -f
UID PID PPID C STIME TTY TIME CMD
501 1841 1840 0 11:50 pts/0 00:00:00 -bash
501 2430 1841 0 13:44 pts/0 00:00:00 bash
501 2444 2430 1 13:44 pts/0 00:00:00 ps -f

注意:进程就是正在运行的程序。bash shell 是一个程序,当它运行的时候,就成为了一个进程。一个运行着的 shell 就是某种进程而已。

子 shell 的父进程 ID(PPID)是 1841,指明了这个父 shell 进程就是该子 shell 的父进程。

子 shell(child shell,也叫 subshell)可以从父 shell 中创建,也可以从另一个子 shell 中创建。

$ ps -f
UID PID PPID C STIME TTY TIME CMD
501 1841 1840 0 11:50 pts/0 00:00:00 -bash
501 2532 1841 1 14:22 pts/0 00:00:00 ps -f
$
$ bash
$
$ bash
$
$ bash
$
$ ps --forest
PID TTY TIME CMD
1841 pts/0 00:00:00 bash
2533 pts/0 00:00:00 \_ bash
2546 pts/0 00:00:00 \_ bash
2562 pts/0 00:00:00 \_ bash
2576 pts/0 00:00:00 \_ ps

bash 命令被输入了三次。这实际上创建了三个子 shell。ps -forest 命令展示了这些子 shell 间的嵌套结构。

可以利用 exit 命令有条不紊地退出子 shell。exit 命令不仅能退出子 shell,还能用来登出当前的虚拟控制台终端或终端仿真器软件。只需要在父 shell 中输入 exit,就能够从容退出 CLI 了。

2.1 进程列表

在一行中输入多个命令,只需要在命令之间加入分号 ; 即可:

$ pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls
/home/Christine
Desktop Downloads Music Public Videos
Documents junk.dat Pictures Templates
/etc
/home/Christine
Desktop Downloads Music Public Videos
Documents junk.dat Pictures Templates

命令列表要想成为进程列表,这些命令必须包含在括号里。

$ (pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls)
/home/Christine
Desktop Downloads Music Public Videos
Documents junk.dat Pictures Templates
/etc
/home/Christine
Desktop Downloads Music Public Videos
Documents junk.dat Pictures Templates
$

在 shell 脚本中,经常使用子 shell 进行多进程处理。但是采用子 shell 的成本不菲,会明显拖慢处理速度。在交互式的 CLI shell 会话中,子 shell 同样存在问题。它并非真正的多进程处理,因为终端控制着子 shell 的 I/O。

2.2 子 shell 的其它用法

后台模式: 在后台模式中运行命令可以在处理命令的同时让出 CLI,以供他用,要想将命令置入后台模式,可以在命令末尾加上字符 &

$ sleep 3000&
[1] 2396
$ ps -f
UID PID PPID C STIME TTY TIME CMD
christi+ 2338 2337 0 10:13 pts/9 00:00:00 -bash
christi+ 2396 2338 0 10:17 pts/9 00:00:00 sleep 3000
christi+ 2397 2338 0 10:17 pts/9 00:00:00 ps -f
$

jobs 命令可以显示出当前运行在后台模式中的所有用户的进程(作业)。

$ jobs
[1]+ Running sleep 3000 &
$

jobs 命令在方括号中显示出作业号(1)。它还显示了作业的当前状态(running)以及对应的命令(sleep 3000 &)

利用 jobs 命令的 -l(字母L的小写形式)选项还能够显示出命令的 PID

$ jobs -l
[1]+ 2396 Running sleep 3000 &
$
[1]+ Done sleep 3000 &
$

生成子shell的成本不低,而且速度还慢。创建嵌套子shell更是火上浇油!

3. 理解 shell 的内建命令

3.1 外部命令

外部命令: 有时候也被称为文件系统命令,是存在于 bash shell 之外的程序。它们并不是 shell程序的一部分。

外部命令程序通常位于 /bin、/usr/bin、/sbin或 /usr/sbin中。

ps 就是一个外部命令。你可以使用 which 和 type 命令找到它。

$ which ps
/bin/ps
$
$ type -a ps
ps is /bin/ps
$
$ ls -l /bin/ps
-rwxr-xr-x 1 root root 93232 Jan 6 18:32 /bin/ps
$

当外部命令执行时,会创建出一个子进程。这种操作被称为衍生(forking)。外部命令 ps 很方便显示出它的父进程以及自己所对应的衍生子进程。

$ ps -f
UID PID PPID C STIME TTY TIME CMD
christi+ 2743 2742 0 17:09 pts/9 00:00:00 -bash
christi+ 2801 2743 0 17:16 pts/9 00:00:00 ps -f
$

3.2 内建命令

内建命令和外部命令的区别在于前者不需要使用子进程来执行。它们已经和 shell 编译成了一体,作为 shell 工具的组成部分存在。不需要借助外部程序文件来运行。

cd 和 exit 命令都内建于 bash shell。可以利用 type 命令来了解某个命令是否是内建的。

$ type cd
cd is a shell builtin
$
$ type exit
exit is a shell builtin
$

因为既不需要通过衍生出子进程来执行,也不需要打开程序文件,内建命令的执行速度要更快,效率也更高。

要查看命令的不同实现,使用 type 命令的 -a 选项

$ type -a echo
echo is a shell builtin
echo is /bin/echo
$
$ which echo
/bin/echo
$
$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd
$
$ which pwd
/bin/pwd
$

命令type -a显示出了每个命令的两种实现。注意,which命令只显示出了外部命令文件。

Linux shell 学习笔记(3)— shell 父子关系及内建命令相关推荐

  1. Linux shell 学习笔记(10)— 处理用户输入(命令行读取参数、读取用户输入、超时处理)

    1. 命令行参数 向 shell 脚本传递数据的最基本方法是使用命令行参数.命令行参数允许在运行脚本时向命令行添加数据. $ ./addem 10 30 本例向脚本 addem 传递了两个命令行参数( ...

  2. 鸟书shell 学习笔记(一) shell专注于概念和命令

    变量 variableName=value 等号左右不能有空格 变量内容有空格须要用"或者'括起来,可是 v="hello $name" $保持原有功能,单引號则不行,v ...

  3. Gnome Shell学习笔记——Gnome Shell是什么

    什么是Gnome Shell? Gnome Shell 是 GNOME 3 的主要元件,它改革了 GNOME 桌面环境的操作,包括窗口管理.应用程序启动和工作空间管理的方式,为使用者提供一个全新方便易 ...

  4. 史上最牛最强的linux学习笔记 10.shell基础

    史上最牛最强的linux学习笔记 10.shell基础 写在最前面: 本文是基于某站的视频学习所得,第一个链接如下: https://www.bilibili.com/video/BV1mW411i7 ...

  5. 【Linux】Linux Shell 学习笔记:什么是Linux?

    I Linux 简介 Linux系统简介 (biancheng.net) Linux和UNIX的关系及区别 (biancheng.net) Linux内核_百度百科 (baidu.com) [什么是 ...

  6. shell学习笔记 (2)

    shell学习笔记 (2) ---china.pub.com  linux shell电子书学习笔记 第2章 使用find和xargs find pathname -options [-print - ...

  7. shell学习笔记整理

    Shell编程学习笔记 第一章基础知识 1.脚本格式: 1.1"#!" 这个符号的名称,叫做"Shebang"或者"Sha-bang" &q ...

  8. Nginx学习笔记3:Shell脚本检测Nginx服务状态

    前言 nginx 服务启动后,我们需要对其服务状态进行监控,今天学习过程中了解到一段非常有用的小脚本,不仅可以监控Nginx,也可以用来监控其他服务 脚本 A=`ps -C nginx –no-hea ...

  9. Bash Shell学习笔记四

    1. 几个常用命令和基本知识. set $(commond)          将位置参数设置为后面的命令输出 shell命令中 在-- 后面的语句将会不再解释后面的 - cal 万年历 bc 计算器 ...

最新文章

  1. 宜昌高新区三峡云计算机大楼,【智慧宜昌】CREATOR快捷CS分布式系统成功入驻三峡云计算中心...
  2. leetcode - Same Tree
  3. who whoami who am i的区别
  4. Cocos2D 添加 UIView
  5. 吴恩达机器学习+林轩田机器学习+高等数学和线性代数等视频领取
  6. Oracle实例和Oracle数据库(Oracle体系结构)
  7. OCP-052考试题库汇总(60)-CUUG内部解答版
  8. mybatis 映射成多个list_SSM:Mybatis架构与原理
  9. PSD分层电商促销模板|换季大促销,不怕老板催你做海报了
  10. 统一横轴墨卡托投影(UTM)
  11. 排序系统 c语言程序设计,c语言程序设计(排序算法).docx
  12. Linq的Distinct太不给力了
  13. DLL导出类避免地狱问题的完美解决方案
  14. getch方法_getch()函数
  15. 虚拟机桥接模式下和windows相互ping通
  16. 内存操作函数:memcmp、memcpy、memmove、memset 的使用与模拟。
  17. ML笔记:预训练(pre-training/trained)与微调(fine tuning)
  18. CentOS 安装Nvidia驱动+CUDA+cuDNN+Anaconda3
  19. PHP jQuery微信大转盘抽奖源代码分享
  20. InvokeRequired and Invoke

热门文章

  1. 2022-2028年中国氢化丁晴橡胶行业市场研究及前瞻分析报告
  2. 2022-2028年中国热熔胶产业竞争现状及发展规模预测报告
  3. 2022-2028年中国塑料安瓿瓶行业市场研究及前瞻分析报告
  4. Linux shell 学习笔记(7)— 构建基本脚本(变量、重定向、管道、状态码)
  5. python pandas 如何找到NaN、缺失值或者某些元素的索引名称以及位置,np.where的使用
  6. 手把手教你用Python实现自动特征工程
  7. LeetCode简单题之两个相同字符之间的最长子字符串
  8. 用TVM在硬件平台上部署深度学习工作负载的端到端 IR 堆栈
  9. 保护嵌入式802.11 Wi-Fi设备时需要考虑的10件事
  10. Android布局优化之include、merge、ViewStub