Linux-理解shell

文章目录

    • 5. 理解shell
      • 5.1 shell的类型
      • 5.2 交互shell和系统默认shell
      • 5.3 安装zsh shell程序
      • 5.4 shell的父子关系
      • 5.5 命令列表
      • 5.6 命令分组
      • 5.7 使用命令分组创建子shell
      • 5.8 子shell用法
      • 5.9 shell的非内建命令和内建命令
        • 5.9.1 非内建命令
        • 5.9.2 内建命令
        • 5.9.3 history和alias命令介绍

5. 理解shell

shell不单单是一种CLI,它是一个时刻都在运行的复杂交互式程序。

输入命令并利用shell来运行脚本会出现一些既有趣又令人困惑的问题。搞清楚shell进程以及它与系统之间的关系能够帮助你解决这些难题,或是完全避开它们。

在本文章中,你会了解到如何创建子shell以及父shell与子shell之间的关系。探究各种用于创建子进程的命令和内建命令。

5.1 shell的类型

系统启动什么样的shell程序取决于你个人的用户ID配置。在/etc/passwd文件中,在用户ID记录的第7个字段中列出了默认的shell程序。只要用户登录到某个虚拟控制台终端或是在GUI中启动终端仿真器,默认的shell程序就会开始运行。

# 1. 在现代Linux系统中,bash shell程序(bash)通常位于/usr/bin目录或者/bin目录,which bash命令可以帮助我们找出bash shell的位置。
[root@Fedora-Desktop ~]# which bash
/usr/bin/bash
[root@Fedora-Desktop ~]# # 2. 从/usr/bin目录中,可以看到bash shell是一个程序。
[root@Fedora-Desktop ~]# ls -lF /usr/bin/bash
-rwxr-xr-x. 1 root root 1406608  29日 08:00 /usr/bin/bash*
[root@Fedora-Desktop ~]# # 3. root用户使用bash shell作为默认shell程序。
[root@Fedora-Desktop ~]# head -n 1 /etc/passwd
root:x:0:0:Super User:/root:/bin/bash
[root@Fedora-Desktop ~]# # 4. 用户可以将这些shell程序中的某一个作为自己的默认shell。不过由于bash shell的广为流行,很少有人使用其他的shell作为默认的交互式shell。
[root@Fedora-Desktop ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
[root@Fedora-Desktop ~]# 

除了Bash(Bourne Again SHell)和sh(Bourne Shell)之外,还有多种其他的shell,它们各有特色,适用于不同的场景和需求。以下是一些常见的shell:

1. C Shell (csh) & Turbo C Shell (tcsh):
C Shell 的语法类似于C编程语言,提供了命令历史、别名等功能。tcsh 是 csh 的增强版本,增加了命令行编辑、自动完成等便利功能。

2. Korn Shell (ksh):
由David Korn设计,是Bourne Shell的一个扩展,支持更高级的编程结构,如函数、数组等,同时兼容sh脚本。

3. Z Shell (zsh):
功能强大,是bash的一个超集,拥有丰富的插件系统、高级自动补全功能、主题支持等,近年来因其高度可定制性和用户体验而在开发者中变得非常流行。

4.Fish (Friendly Interactive Shell):
设计用于提供更好的用户体验,有着出色的命令补全和颜色高亮特性,以及友好的交互界面,适合新手。

5. Debian Almquist Shell (dash):
一个轻量级的shell,专为速度优化,主要用于系统的初始化脚本,是Debian和Ubuntu等系统中的/bin/sh的默认实现。

6. BusyBox Ash:
通常在嵌入式Linux系统中使用,是一个小型化的Almquist Shell,旨在减少资源占用。

7. PowerShell:
虽然起源于Microsoft Windows平台,但现在也有Linux和macOS版本,它是一种面向对象的shell,专为系统管理和自动化任务设计,支持.NET框架和CMDLETs。

这些shell各有优劣,选择哪种shell往往取决于用户的特定需求、习惯以及系统环境的要求。



5.2 交互shell和系统默认shell

默认的交互shell (bash)会在用户登录某个虚拟控制台终端或在GUI中运行终端仿真器时启动。

默认的系统shell(sh)用于那些需要在启动时使用的系统shell脚本。

1.某些发行版使用软链接将默认的系统shell指向bash shell,比如Fedora发行版:

[root@Fedora-Desktop ~]# which sh
/usr/bin/sh
[root@Fedora-Desktop ~]# ls -lF /usr/bin/sh
lrwxrwxrwx. 1 root root 4  79日 08:00 /usr/bin/sh -> bash*
[root@Fedora-Desktop ~]# 
  1. 在有些发行版中,默认的系统shell并不指向bash shell,比如Ubuntu发行版:
[root@Ubuntu-Desktop ~]# which sh
/usr/bin/sh
[root@Ubuntu-Desktop ~]# ls -lF /usr/bin/sh
lrwxrwxrwx 1 root root 4  79日 08:01 /usr/bin/sh -> dash*
[root@Ubuntu-Desktop ~]# 
  1. 使用不同的shell。
# 使用echo $0显示当前所用shell的做法仅限在shell命令行中使用。如果在shell脚本中使用,则显示的是该脚本的名称。 "-bash"中的 "-"
[root@Fedora-Desktop ~]# echo $0
-bash                  -bash中的 "-"表示它是交互式shell
[root@Fedora-Desktop]~## 输入命令exit就可以退出sh程序
[root@Fedora-Desktop]~# sh
sh-5.2# exit
exit
[root@Fedora-Desktop ~]# zsh[root@Fedora-Desktop]~# echo $0 
zsh
[root@Fedora-Desktop]~#


5.3 安装zsh shell程序

# 1. 在Fedora 40-1.14系统上安装zsh
[root@Fedora-Desktop ~]# dnf install zsh -y# 2. 将zsh设置为当前系统的默认shell
[root@Fedora-Desktop ~]# chsh -s $(which zsh)
Changing shell for root.
Shell changed.
[root@Fedora-Desktop ~]# # 3. 查看root用户现在使用的默认shell。
[root@Fedora-Desktop ~]# head -n 1 /etc/passwd
root:x:0:0:Super User:/root:/usr/bin/zsh
[root@Fedora-Desktop ~]# echo $PATH
/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@Fedora-Desktop ~]# # 4. 重新打开一个终端执行exec zsh 或者重启生效
[root@Fedora-Desktop]~# exec zsh
[root@Fedora-Desktop]~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@Fedora-Desktop]~# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/usr/bin/zsh
/bin/zsh
[root@Fedora-Desktop]~# # 5. 改回原来的shell:   chsh -s [原来shell的完整路径]
[root@Fedora-Desktop]~# chsh -s /bin/bash
Changing shell for root.
Shell changed.
[root@Fedora-Desktop]~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin# 6. 重新打开一个终端执行exec bash 或者重启生效
[root@Fedora-Desktop]~# exec bash
[root@Fedora-Desktop ~]# echo $PATH
/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@Fedora-Desktop ~]# 

其他shell的安装方法类似,不过多介绍了。



5.4 shell的父子关系

[root@Fedora-Desktop ~]# echo $0
-bash
[root@Fedora-Desktop ~]# bash
[root@Fedora-Desktop ~]# echo $0
bash
[root@Fedora-Desktop ~]# exit
exit
[root@Fedora-Desktop ~]# echo $0
-bash
[root@Fedora-Desktop ~]# 
# 好像什么并没有改变什么,但是bash程序已经退出了。

为了理解这个过程,我们接下来将探究登录shell程序与新启动的shell程序之间的关系。

# 1. 用户登录某个虚拟控制台终端或在GUI中运行终端仿真器时所启动的默认的交互式shel(登录shell)是一个父shell。
[root@Fedora-Desktop ~]# ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
root        2636    2621  0 17:07 pts/1    00:00:00 -bash
root        2713    2636 99 17:28 pts/1    00:00:00 ps -f
[root@Fedora-Desktop ~]# # 2. 当你在CLI提示符处输入/usr/bin/bash或者bash命令(或是其他shell程序名)时,会创建新的shell程序。这是一个子shell。子shell也拥有CLI提示符,同样会等待命令输入。
[root@Fedora-Desktop ~]# bash
[root@Fedora-Desktop ~]# ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
root        2636    2621  0 17:07 pts/1    00:00:00 -bash
root        2714    2636  0 17:29 pts/1    00:00:00 bash  #它的父进程是2636
root        2735    2714  0 17:30 pts/1    00:00:00 ps -f
[root@Fedora-Desktop ~]# 

第一个bash shell程序,也就是父shell进程,其进程PID是2636。
第二个bash shell程序,即子shell进程,其进程PID是2430。

它们之间的关系如下图:

在这里插入图片描述

注意:

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

在生成子shell进程时,只有部分父进程的环境被复制到了子shell环境中。这会对包括变量在内的一些东西造成影响。

# bash命令被输入了两次,这实际上创建了两个子shell。
[root@Fedora-Desktop ~]# ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
root        1860    1846  0 21:17 pts/0    00:00:00 -bash
root        1894    1860 25 21:17 pts/0    00:00:00 ps -f
[root@Fedora-Desktop ~]# bash
[root@Fedora-Desktop ~]# bash
[root@Fedora-Desktop ~]# ps --forestPID TTY          TIME CMD1860 pts/0    00:00:00 bash1909 pts/0    00:00:00  \_ bash1943 pts/0    00:00:00      \_ bash2016 pts/0    00:00:00          \_ ps
[root@Fedora-Desktop ~]# # 使用exit可以退出子shell
[root@Fedora-Desktop ~]# exit
exit
[root@Fedora-Desktop ~]# exit
exit
[root@Fedora-Desktop ~]# ps --forestPID TTY          TIME CMD1860 pts/0    00:00:00 bash2055 pts/0    00:00:00  \_ ps
[root@Fedora-Desktop ~]# 

bash 主页:http://www.gnu.org/software/bash

使用 GNU 软件的通用帮助:http://www.gnu.org/gethelp/

# 获取更多帮助信息
[root@Fedora-Desktop ~]# bash --help
[root@Fedora-Desktop ~]# 
[root@Fedora-Desktop ~]# man bash


5.5 命令列表

  • 是一系列由分号(;)、换行符或空格分隔的命令集合,它们在shell中按顺序执行。
  • 每个命令独立运行,它们共享当前shell的环境(包括变量、工作目录等)。
  • 命令之间互不影响,前一个命令的输出、错误或状态不会直接影响后续命令的执行,除非通过重定向或命令替换等方式显式地传递数据或状态。
# 命令列表 (用 ;)
[root@Fedora-Desktop ~]# pwd; ls; cd /var/log; pwd; echo $BASH_SUBSHELL 
/root
anaconda-ks.cfg  zy.txt
/var/log
0
[root@Fedora-Desktop log]# # 命令列表 (用 \)
[root@Fedora-Desktop log]# virt-install \
--boot hd \
--name=mysql-EC3 \
--os-type=linux \
--os-variant=fedora18 \
--cpu host \
--vcpus 2,maxvcpus=2 \
--memory 2048 \
--disk=/var/lib/libvirt/images/LinuxImage.qcow2 \
--network network=ovs01_network,target=if01,mac=02:01:01:01:01:01 \
--graphics vnc,listen=0.0.0.0,port=60001
bash: virt-install: 未找到命令...
安装软件包“virt-install”以提供命令“virt-install”? [N/y] 

如果 echo $BASH_SUBSHELL该命令返回0,表明没有子shell;返回其他数字,则表明存在子shell。



5.6 命令分组

命令分组是指在执行复杂操作或需要将多个命令组合以实现特定逻辑时,对这些命令进行的一种逻辑上的组织。这通常涉及使用shell的结构化特性。

  • 利用括号 ()、大括号 {}(需配合;&或换行符)或特定语法(如$(command)用于命令替换)来组织命令。
  • 当使用 () 时,会创建一个新的子shell环境来执行括号内的命令组。这意味着在子shell中对环境的修改(如变量赋值、工作目录变更)不会影响到外部的父shell。
  • 当时用{}时,不会创建新的子shell,不过,它们通常需要配合分号或换行以及命令执行符(如;&)来正确执行。
  • 使用复杂逻辑如&&(前一命令成功后执行后一命令)、||(前一命令失败后执行后一命令)、;(无论前一命令成功与否都执行后一命令)等来进行命令的串联或并行执行。

命令分组可以实现:

  1. 逻辑分组:使得一组命令作为单一单元处理,比如在条件语句或循环中。
  2. 流程控制:控制命令的执行顺序和条件,比如基于前一个命令的成功或失败来决定是否执行下一个命令。
  3. 环境隔离:在子shell中执行命令组,可以保持或隔离环境变量和状态,不影响外部shell环境。
  4. 资源共享:在同一个子shell内的命令可以更容易地共享输出或状态信息,例如使用管道|连接的命令组,前一个命令的输出直接作为后一个命令的输入。

简而言之,命令列表关注的是Linux提供的所有独立命令及其功能,而命令分组则侧重于如何通过逻辑组织这些命令来实现更复杂的操作流程和任务自动化。



5.7 使用命令分组创建子shell

不使用bash shell命令和运行shell脚本,你也可以生成子shell。一种方法就是使用命令分组 。

# 1.使用圆括号生成了一个子shell来执行这些命令。
[root@Fedora-Desktop ~]# (pwd; ls; cd /var/log; pwd; echo $BASH_SUBSHELL) 
/root
anaconda-ks.cfg  zy.txt
/var/log
1    # 存在子shell
[root@Fedora-Desktop ~]# # 2.使用包围起来的一组命令,它能够创建出子shell来执行这些命令。甚至可以在命令列表中嵌套括号来创建子shell的子shell。
[root@Fedora-Desktop ~]# echo $BASH_SUBSHELL
0
[root@Fedora-Desktop ~]# (pwd; echo $BASH_SUBSHELL)
/root
1
[root@Fedora-Desktop ~]# (pwd; (echo $BASH_SUBSHELL))
/root
2
[root@Fedora-Desktop ~]# # 3. 使用花括号进行命令分组并不会像进程列表那样创建子shell。
[root@Fedora-Desktop ~]#  { pwd ; echo $BASH_SUBSHELL; }
/root
0
[root@Fedora-Desktop ~]# 

子shell在shell脚本中经常用于多进程处理。但是,创建子shell要消耗更多的资源,比如内存和计算能力,会明显拖慢任务进度。在交互式CLI shell会话中,子shell同样存在问题,它并非真正的多进程处理,原因在于终端与子shell的I/O绑定在了一起。



5.8 子shell用法

在交互式shell中,一种高效的子shell用法是后台模式。

# 1. 探究后台模式                                                                          
在后台模式运行命令可以在处理命令的同时让出CLI,以供他用sleep命令会接受一个参数作为希望进程等待(睡眠)的秒数。该命令在shell脚本中常用于引入一段暂停时间。
[root@Fedora-Desktop ~]# sleep 10
[root@Fedora-Desktop ~]# 
# 2. 要想将命令置入后台模式,可以在命令末尾加上字符 &
第一条信息是方括号中的后台作业号(1)。第二条信息是后台作业的进程ID(2162)。
[root@Fedora-Desktop ~]# sleep 5000&
[1] 2162
[root@Fedora-Desktop ~]# ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
root        1305    1298  0 08:58 pts/0    00:00:00 -bash
root        2162    1305  0 10:30 pts/0    00:00:00 sleep 5000
root        2163    1305  0 10:31 pts/0    00:00:00 ps -f
[root@Fedora-Desktop ~]# # 3. jobs命令能够显示当前运行在后台模式中属于你的所有进程(作业)
[root@Fedora-Desktop ~]# jobs -l
[1]+  2162 运行中               sleep 5000 &
[root@Fedora-Desktop ~]# 

需要提醒的是:后台作业的结束状态可未必会一直等待到合适的时候才现身。当作业结束状态突然出现在屏幕上的时候,你可别吃惊啊。

后台模式非常方便,它可以让我们在CLI中创建出有实用价值的子shell。

将分组列表置入后台

通过将分组列表置入后台,可以在子shell中进行大量的多进程处理。由此带来的一个好处是终端不再和子shell的I/O绑定在一起。

# 4. 分组列表前台运行
在分组列表中加入sleep命令并显示BASH_SUBSHELL变量,结果不出所料:
[root@Fedora-Desktop ~]# (sleep 2 ; echo $BASH_SUBSHELL ; sleep 2)
1
[root@Fedora-Desktop ~]# # 5. 将同样的进程列表置入后台会产生些许不同的命令输出:
[root@Fedora-Desktop ~]# (sleep 2 ; echo $BASH_SUBSHELL ; sleep 2)&
[2] 2183
[root@Fedora-Desktop ~]# 1
^C
[2]+  已完成               ( sleep 2; echo $BASH_SUBSHELL; sleep 2 )
[root@Fedora-Desktop ~]# # 6. tar 创建备份文件有效利用后台进程列表的一个实用例子
[root@Fedora-Desktop ~]# lsdocuments  music 
[root@Fedora-Desktop ~]# (tar -cf doc.tar documents/ ; tar -cf music.tar music/)&
[2] 2211
[root@Fedora-Desktop ~]# ls *.tar
doc.tar  music.tar
[2]+  已完成               ( tar -cf doc.tar documents/; tar -cf music.tar music/ )
[root@Fedora-Desktop ~]# ls
doc.tar  documents  music  music.tar  
[root@Fedora-Desktop ~]# 

协程

进程、线程、协程是现代计算中用于实现并发和多任务处理的三种基本概念,它们之间存在显著的区别:

  1. 资源拥有与隔离

    • 进程:是操作系统资源分配的最小单位,每个进程都有自己独立的地址空间,包括代码段、数据段、堆和栈。这意味着进程之间不共享内存,通信通常需要通过IPC(进程间通信)机制。
    • 线程:是进程内的执行单元,线程之间共享所属进程的地址空间,包括代码、数据和文件描述符等资源。线程减少了上下文切换的开销,但增加了资源共享的复杂度,需要同步机制(如锁、信号量)来防止数据竞争。
    • 协程:是一种用户态轻量级线程,运行在单个线程内,共享同一地址空间。协程的调度由程序自身控制,而非操作系统,因此切换更快且无需操作系统介入。协程通过协作而非抢占的方式进行任务切换,降低了同步开销。
  2. 系统开销

    • 进程:创建和销毁进程的开销相对较大,因为需要分配独立的地址空间和其他资源。
    • 线程:相比进程,创建线程的开销较小,但仍需分配栈空间等资源,且线程间的切换由操作系统管理,有一定的开销。
    • 协程:创建和切换协程的开销极小,仅需保存和恢复少量上下文,通常只需几字节到几十字节的栈空间。
  3. 调度方式

    • 进程和线程:通常由操作系统内核调度,可以被中断并由操作系统决定何时恢复执行。
    • 协程:调度责任在于程序本身,程序员通过明确的yield(让出控制权)操作来控制协程的执行流,这使得协程能够避免不必要的调度,提高效率。
  4. 应用场景

    • 进程:适用于需要隔离资源和独立执行环境的任务,如服务器上运行的不同服务。
    • 线程:适用于需要共享资源但又希望保持相对独立执行路径的场景,如Web服务器处理多个请求。
    • 协程:特别适合于I/O密集型应用,如网络请求处理、异步IO、游戏开发等,它们能高效地处理大量的并发请求而无需大量线程。
  5. 资源占用

    • 进程占用资源最多,包括独立的内存空间。
  • 线程相对较少,但仍需分配栈空间。
  • 协程占用资源最少,一般只需要少量栈空间。
  1. 执行顺序

    • 线程:线程的执行顺序由操作系统调度,通常是无序的。
    • 协程:通过程序控制,可以实现按需、有序的执行。

    这篇文章可以大致看一下:一文彻底搞懂协程(coroutine)是什么,值得收藏-CSDN博客

总的来说,进程提供了最高级别的隔离和独立性,但开销大;线程减少了这种开销,实现了更细粒度的并发,但增加了资源共享的复杂性;而协程以其轻量、高效的特性,成为处理高并发I/O密集型任务的理想选择,但需要手动管理调度逻辑。

将进程列表置入后台并不是子shell在CLI中仅有的创造性用法,还有一种方法是协程。
协程同时做两件事:一是在后台生成一个子shell,二是在该子shell中执行命令。

# 1. 要进行协程处理,可以结合使用coproc命令以及要在子shell中执行的命令:
[root@Fedora-Desktop ~]# ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
root        1305    1298  0 08:58 pts/0    00:00:00 -bash
root        2162    1305  0 10:30 pts/0    00:00:00 sleep 5000
root        2237    1305 99 11:05 pts/0    00:00:00 ps -f
[root@Fedora-Desktop ~]# 
[root@Fedora-Desktop ~]# coproc sleep 10
[1] 2238
[root@Fedora-Desktop ~]# jobs -l
[1]+  2238 运行中               coproc COPROC sleep 10 &
[root@Fedora-Desktop ~]# 
[1]+  已完成               coproc COPROC sleep 10
[root@Fedora-Desktop ~]# # 2. COPROC是coproc命令给进程起的名字。你可以使用命令的扩展语法自己设置这个名字
[root@Fedora-Desktop ~]# coproc My_Job { sleep 10; }
[1] 2240
[root@Fedora-Desktop ~]# jobs -l
[1]+  2240 运行中               coproc My_Job { sleep 10; } &
[root@Fedora-Desktop ~]# 

必须确保在第一个花括号{和命令名之间有一个空格。还必须保证命令以分号 ;结尾。另外,分号和闭花括号 }之间也得有一个空格。

协程能够让你尽情发挥想象力,发送或接收来自子shell中进程的信息。只有在拥有多个协程的时候才需要对协程进行命名,因为你得和它们进行通信。否则的话,让coproc命令将其设置成默认的名字COPROC就行了。

# 可以发挥才智,将协程与进程列表结合起来创建嵌套子shell。只需将命令coproc放在进程列表之前即可:
[root@Fedora-Desktop ~]# coproc ( sleep 20; sleep 10)
[1] 2253
[root@Fedora-Desktop ~]# jobs
[1]+  运行中               coproc COPROC ( sleep 20; sleep 10 ) &
[root@Fedora-Desktop ~]# ps --forestPID TTY          TIME CMD1305 pts/0    00:00:00 bash2253 pts/0    00:00:00  \_ bash2254 pts/0    00:00:00  |   \_ sleep2255 pts/0    00:00:00  \_ ps
[root@Fedora-Desktop ~]# 

记住,生成子shell的成本不低,而且速度还慢。创建嵌套子shell更是火上浇油!在命令行中使用子shell能够获得灵活性和便利。要想获得这些优势,重要的是理解子shell的行为方式。对于命令也是如此。



5.9 shell的非内建命令和内建命令

5.9.1 非内建命令

外部命令(有时也称为文件系统命令)是存在于bash shell之外的程序,它并不属于shell程序的一部分。外部命令程序通常位于 /bin/usr/bin/sbin/usr/sbin目录中。

# ps命令就是一个外部命令。可以使用which命令和type命令找到其对应的文件名:
[root@Fedora-Desktop ~]# which ps
/usr/bin/ps
[root@Fedora-Desktop ~]# type -a ps
ps 是 /usr/bin/ps
[root@Fedora-Desktop ~]# ls -l /bin/ps
-rwxr-xr-x. 1 root root 120776  1月26日 08:00 /bin/ps
[root@Fedora-Desktop ~]# # 每当执行外部命令时,就会创建一个子进程。这种操作称为衍生(forking)。外部命令ps会显示其父进程以及自己所对应的衍生子进程。
[root@Fedora-Desktop ~]# ps -f
UID          PID    PPID  C STIME TTY          TIME CMD
root        1305    1298  0 08:58 pts/0    00:00:00 -bash
root        2290    1305 99 11:39 pts/0    00:00:00 ps -f
[root@Fedora-Desktop ~]# 

在这里插入图片描述

只要涉及进程衍生,就需要耗费时间和资源来设置新子进程的环境。因此,外部命令系统开销较高。

当进程必须执行衍生操作时,它需要花费时间和精力来设置新子进程的环境。所以说,外部命令多少还是有代价的。

就算衍生出子进程或是创建了子shell,你仍然可以通过发送信号与其沟通,这一点无论是在命令行还是在脚本编写中都是极其有用的。


5.9.2 内建命令

内建命令无须使用子进程来执行。内建命令已经和shell编译成一体,作为shell的组成部分存在,无须借助外部程序文件来执行。cd命令和exit命令都内建于bash shell。可以使用type命令来判断某个命令是否为内建。

[root@Fedora-Desktop ~]# type cd
cd 是 shell 内建
[root@Fedora-Desktop ~]# type exit
exit 是 shell 内建
[root@Fedora-Desktop ~]# # echo和pwd既有内建命令也有外部命令
[root@Fedora-Desktop ~]# type -a echo
echo 是 shell 内建
echo 是 /usr/bin/echo
[root@Fedora-Desktop ~]# which echo
/usr/bin/echo
[root@Fedora-Desktop ~]# 
[root@Fedora-Desktop ~]# type -a pwd
pwd 是 shell 内建
pwd 是 /usr/bin/pwd
[root@Fedora-Desktop ~]# which pwd
/usr/bin/pwd
[root@Fedora-Desktop ~]# 
# type -a命令显示出了每个命令的两种实现(内建和非内建)。注意,which命令只显示外部命令文件。

提示: 对于有多种实现的命令,如果想使用其外部命令实现,直接指明对应的文件即可。例如,要使用外部命令pwd,可以输入/usr/bin/pwd。


5.9.3 history和alias命令介绍
1. history是一个有用的内建命令
当输入 !! 时,bash会先显示从shell的历史记录中唤回的命令,然后再执行该命令。命令历史记录被保存在位于用户主目录的隐藏文件.bash_history之中:
[root@Fedora-Desktop ~]# ls .bash_history 
.bash_history
[root@Fedora-Desktop ~]# 在CLI会话期间,bash命令的历史记录被保存在内存中。当shell退出时才被写入历史文件:
以在不退出shell的情况下强制将命令历史记录写入.bash_history文件。为此,需要使用history命令的 -a选项:
[root@Fedora-Desktop ~]# history -a
[root@Fedora-Desktop ~]# 
如 果 你 打 开 了 多 个 终 端 会 话 , 仍 然 可 以 使 用 history -a 命 令 在 打 开 的 会 话 中
向.bash_history文件中添加记录。但是对于其他打开的终端会话,历史记录并不会自动更
新。这是因为.bash_history文件只有在打开首个终端会话时才会被读取。要想强制重新读
取.bash_history文件,更新终端会话的历史记录,可以使用history -n命令。2. 使用命令别名
alias命令是另一个实用的shell内建命令。命令别名允许为常用命令及其参数创建另一个名称,从而将输入量减少到最低。
[root@Fedora-Desktop ~]# alias -p
alias cp='cp -i'
alias egrep='grep -E --color=auto'
alias fgrep='grep -F --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='(alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot'
alias xzegrep='xzegrep --color=auto'
alias xzfgrep='xzfgrep --color=auto'
alias xzgrep='xzgrep --color=auto'
alias zegrep='zegrep --color=auto'
alias zfgrep='zfgrep --color=auto'
alias zgrep='zgrep --color=auto'
[root@Fedora-Desktop ~]# # 命令别名属于内建命令,所以别名仅在其被定义的shell进程中才有效。
在定义好别名之后,你随时都可以在shell中使用它,就算在shell脚本中也没问题。
但要注意,因为命令别名属于内建命令,一个别名仅在它所被定义的shell进程中才有效。
[root@Fedora-Desktop ~]# alias li='ls -li' --color=auto
[root@Fedora-Desktop ~]# li
总计 326034 -rw-------. 1 root root   480  5412:02 anaconda-ks.cfg
406259 -rw-r--r--  1 root root 10240  7月12日 10:56 doc.tar
406255 drwxr-xr-x  1 root root     0  7月12日 10:54 documents
406257 drwxr-xr-x  1 root root     0  7月12日 10:55 music
406260 -rw-r--r--  1 root root 10240  7月12日 10:56 music.tar
406256 -rw-r--r--  1 root root     0  7月12日 10:55 zy.mp4
402585 -rw-r--r--  1 root root    62  7月10日 10:04 zy.txt
[root@Fedora-Desktop ~]# zsh
[root@Fedora-Desktop]~# echo $0
zsh
[root@Fedora-Desktop]~# li
bash: li: 未找到命令...
[root@Fedora-Desktop]~# exit
[root@Fedora-Desktop]~## 取消别名
[root@Fedora-Desktop ~]# unalias li
[root@Fedora-Desktop ~]# echo $0
-bash
[root@Fedora-Desktop ~]# li
bash: li: 未找到命令...
[root@Fedora-Desktop ~]# 

unalias命令的作用通常是临时的,仅在当前shell会话中有效。如果你想永久删除别名,你需要编辑配置文件,如.bashrc, .bash_profile, 或者 .zshrc(取决于你使用的shell),并从文件中删除或注释掉定义该别名的行。然后,你需要重新加载配置文件或新开一个shell会话以使改动生效。例如,如果你使用Bash,可以执行:

[root@Fedora-Desktop ~]# source ~/.bashrc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/392665.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI9-文本识别

本章主要介绍文本识别算法的理论知识,包括背景介绍、算法分类和部分经典论文思路。 通过本章的学习,你可以掌握: 1. 文本识别的目标 2. 文本识别算法的分类 3. 各类算法的典型思想 1 背景介绍 文本识别是OCR(Optical Character Recognition)的一个子任务,其任务为识别一个…

基于 Redis 的分布式信号量 Spring Boot 集成 Redisson 使用 Semaphore 控制并发访问数量

目录 前言 pom yml Controller 演示 注意 前言 工作中开发过一个服务,这里记作A服务,主要功能是配置,部署以及调用云函数。其中配置云函数的功能里,有一个配置项是并发数,意思是同一时间最多能有多少个请求调用…

【MATLAB源码】数学建模基础教程(2)--层次分析法(评价类算法)

系列文章目录在最后面,各位同仁感兴趣可以看看! 层次分析法 引言一、层次分析法的特点二、模型的建立求解过程 (1)问题的提出:实际问题的转化(2)建立层次结构模型(3)构造判断(成对比较)矩阵(4)一致性检验:三、层次分析法的优点与…

Codeforces Round 871 (Div. 4)(A~H)

比赛链接 Dashboard - Codeforces Round 871 (Div. 4) - Codeforces A. Love Story 找到与codeforces 有多少个不同的字符。 #include<bits/stdc.h> #define int long long #define TEST int T; cin >> T; while (T--) #define ios ios::sync_with_stdio(fals…

前端常用的性能优化方案

目录 性能分析工具lighthouseWebpack Bundle分析 开发阶段按需引入路由懒加载 打包阶段打包配置减少包体积配置压缩分包 资源预加载/预请求 部署阶段开启http2静态资源缓存gzip压缩 性能优化主要在三个阶段进行&#xff1a;开发阶段、开发结束后的打包阶段、项目部署上线阶段 首…

提升生产效率:APS高级计划排程系统在车间工序级排程的革命性应用

在制造业的数字化转型浪潮中&#xff0c;APS高级计划排程系统以凭借自身卓越的排程运算能力和应用灵活性&#xff0c;已经成为中大型制造业提升生产效率的关键工具。APS系统的介入&#xff0c;打通了传统ERP和MES等各类业务系统运营平台&#xff0c;并且通过产能均衡规划&#…

为什么我3d模型选择面选不到?---模大狮模型网

在展览3D模型设计行业中&#xff0c;设计师常常面临诸多技术挑战&#xff0c;其中之一是在模型编辑过程中遇到选择面的困难。这不仅影响了设计工作效率&#xff0c;还可能影响最终作品的质量和展示效果。本文将探讨在3D模型设计中为何会遇到“为什么我3D模型选择面选不到?”这…

【MySQL进阶篇】管理

1、系统数据库 MySQL数据库安装完成之后&#xff0c;自带以下四个数据库&#xff0c;具体作用如下&#xff1a; 数据库含义mysql存储MySQL服务器正常运行所需要的各种信息&#xff08;时区、主从、用户、权限等&#xff09;information_schema提供了访问数据库元数据的各种表…

实战OpenCV之环境安装与配置

OpenCV是什么 OpenCV&#xff0c;英文全称为Open Source Computer Vision Library&#xff0c;是一个开源的计算机视觉和机器学习软件库。它设计用于提供一系列功能强大的算法&#xff0c;以帮助开发者处理图像和视频数据&#xff0c;实现各种视觉任务&#xff0c;包括&#xf…

.NET内网实战:模拟Installer关闭Defender

01基本介绍 02编码实现 原理上通过Windows API函数将当前进程的权限提升至TrustedInstaller&#xff0c;从而实现了对Windows Defender服务的控制。通常可以利用Windows API中的OpenSCManager、OpenProcessToken、ImpersonateLoggedOnUser以及ControlService等函数协同工作&am…

从干涉实验、化学反应到晶体管的科学之旅 - 《量子宇宙》读后感

在《量子宇宙》这本书中&#xff0c;作者没有讲述历史和发现的故事&#xff0c;而是从头到尾用公式推导来展示宇宙和现代物理学的壮美。 量子理论处理的是概率&#xff0c;而不是确定性。大自然在某些方面本质上就是由或然率支配的。计算粒子出现的概率是我们能做到的极限。 …

渗透小游戏,各个关卡的渗透实例---步骤简单(含代码)

文章目录 Less-1Less-2Less-5updatexml报错注入&#xff1a; Less-6Less-7Less-8Less-9Less-11Less-13Less-15 Less-1 首先&#xff0c;可以看见该界面&#xff0c;该关卡主要是SQL注入&#xff0c;由于对用户的输入没有做过滤&#xff0c;使查询语句进入到了数据库中&#xff…

springboot电影院线上购票系统-计算机毕业设计源码68220

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统流程分析 2.2.1 添加信息流程 2.2.2 修改信息流程 2.2.3 删除信息流程 2.3 系统功能分析 2.…

synchronized 与 Lock 的区别

synchronized 与 Lock 的区别 1、相同点2、不同点2.1 精确性与灵活性2.2 性能2.3 使用便利性 3、示例3.1 synchronized 示例3.2 Lock 示例 4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java多线程编程中&#xff0c;synchroniz…

智能家居沙盘系统-智慧家居沙盘系统

智能家居和物联网技术是当前科技领域的热门话题&#xff0c;随着各类智能家居产品的不断推出&#xff0c;智能家居市场也逐渐呈现出蓬勃发展的态势。智能家居快速发展&#xff0c;而物联网相关人才供应远远不足。高校开展智能家居工程及设计人才教育培养具有重大意义。 基本介绍…

【stm32】EXTI外部中断

EXTI外部中断 1、中断系统2、中断执行流程3、STM32中断4、NVIC基本结构5、NVIC优先级分组6、EXTI简介&#xff08;引脚电平变化&#xff0c;申请中断&#xff09;7、EXTI基本结构8、AFIO复用IO口9、EXTI框图10、旋转编码器简介11、程序设计&#xff1a;1.使用对射式红外传感器触…

vue3实现商品图片放大镜效果(芋道源码yudao-cloud 二开笔记)

今天开发一个防某商城的商品图片放大镜&#xff0c;鼠标移动到图片位置时&#xff0c;右侧出现一个已放大的图片效果。 示例如下&#xff1a; 下图的图片的放大效果和小图的切换封装成了组件PicShow.vue&#xff0c;可根据需求自行修改&#xff0c;如下&#xff1a; 第一步&…

Html5总结

前端学习 html决定页面的结构css决定页面的样式js决定页面的行为 Html5 1.文本格式化标签&#xff08;熟记&#xff09; 你在网页中&#xff0c;有时需要为文字设置粗体、斜体或下划线效果&#xff0c;这时就需要用到HTML中的文本格式化标记 2.标签属性 例如&#xff1a; …

算法 —— 位运算

目录 位运算常用结论 位运算例题 位1的个数 比特位计算 汉明距离 只出现一次的数字 判定字符是否唯一 丢失的数字 两整数之和 消失的两个数字 进制转换 位运算常用结论 想详细了解位运算的内容可以阅读我的这篇博客&#xff1a;应该背下的位运算 以下我只介绍一些位…

3.特征工程-特征抽取、特征预处理、特征降维

文章目录 环境配置&#xff08;必看&#xff09;头文件引用1.数据集: sklearn代码运行结果 2.字典特征抽取: DictVectorizer代码运行结果稀疏矩阵 3.文本特征抽取(英文文本): CountVectorizer()代码运行结果 4.中文文本分词(中文文本特征抽取使用)代码运行结果 5.中文文本特征抽…