当前位置: 首页 > news >正文

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

相关文章:

Linux-理解shell

文章目录 5. 理解shell5.1 shell的类型5.2 交互shell和系统默认shell5.3 安装zsh shell程序5.4 shell的父子关系5.5 命令列表5.6 命令分组5.7 使用命令分组创建子shell5.8 子shell用法5.9 shell的非内建命令和内建命令5.9.1 非内建命令5.9.2 内建命令5.9.3 history和alias命令介…...

FutureTask详解

目录 FutureTask详解1、FutureTask简介2、FutureTask内部结构继承结构类属性构造方法内部类WaitNode 3、Runnable、Callable、Future、RunnableFuture接口①、Runnable接口②、Callable接口③、Future接口④、RunnableFuture接口总结对比 4、FutureTask的使用示例普通Thread使用…...

javase综合案例4 -- 考试系统

文章目录 一&#xff0c;项目要求二&#xff0c;创建实体类ExamItem三&#xff0c;创建考试服务类ExamService3.1 全局变量 考题列表itemList(List< ExamItem >类型)&#xff0c;答案数组answerArr (String[]类型)&#xff0c;得分score3.2 初始化方法init()3.3 打印菜单…...

Logistic回归

Logistic回归模型&#xff1a; 适用于二分类或多分类问题&#xff0c;样本特征是数值型&#xff08;否则需要转换为数值型&#xff09; 策略&#xff1a;极大似然估计 算法&#xff1a;随机梯度 或 BFGS算法&#xff08;改进的拟牛顿法&#xff09; 线性回归表达式&#xf…...

Langchain-Chatchat+Xinference集成部署

Langchain-ChatchatXinference集成部署 安装环境&#xff1a; 系统&#xff1a;Anolis OS 8.9 python版本&#xff1a;Python 3.9.19 Langchain-Chatchat版本&#xff1a;0.3.1.3 Xinference版本&#xff1a;v0.13.3 模型选择&#xff08;下载时需要科学上网&#xff09;&#…...

江协科技51单片机学习- p33 PWM呼吸灯和直流驱动电机调速

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…...

使用Jetbrains.Rider反编译Unity的DLL文件看源码

直接将dll文件的打开方式用Rider打开即可&#xff0c;打开BattleSeqGenertor.dll文件的效果如下&#xff1a;...

【学习笔记】决策单调性优化DP

背景 GDCPC还在发力&#xff0c;清华出题组出的牛客还是 4 题。 这次没有min25筛&#xff0c;不然我能5题&#xff08;bushi 除了一道用 prufer 序列的恶心 DP 外&#xff0c;还有一道DP题是一个状态难想&#xff0c;并且还需要决策单调性优化的DP&#xff0c;被认为是偏简单…...

【每日一题】【二分图最大匹配】【经典板子题】有大家喜欢的零食吗 河南萌新联赛2024第(一)场:河南农业大学 C题 C++

河南萌新联赛2024第&#xff08;一&#xff09;场&#xff1a;河南农业大学 C题 有大家喜欢的零食吗 题目描述 在某幼儿园中共有 n n n个小朋友&#xff0c;该幼儿园的老师为这 n n n 个小朋友准备了 n n n 份不一样的零食大礼包。每个小朋友只能选择一个&#xff0c;但老…...

【python】OpenCV—Image Colorization

文章目录 1、CIELAB 色彩空间2、作色问题定义3、Caffe 模型4、代码实现——Image5、代码实现——Video6、参考 1、CIELAB 色彩空间 Lab颜色空间&#xff0c;也称为Lab色彩空间或CIELAB色彩空间&#xff0c;是一种基于人类视觉感知特性的颜色模型。它是在1931年国际照明委员会&…...

vue 学习笔记

模板语法 1. 插值语法 用于解析标签体内容 { { 表达式 } } &#xff0c;可以直接读取到 data 中的所有属性 2. 指令语法 解析标签&#xff08;标签属性&#xff0c; 标签内容&#xff0c; 绑定事件&#xff09; v-bind : href " url " 或 : href &…...

武汉流星汇聚:‘中国制造’闪耀欧洲站,体育赛事成亚马逊增长点

随着2024年的欧洲体育赛事激情四溢&#xff0c;欧洲杯与奥运会的双重盛会不仅点燃了全球体育迷的热情&#xff0c;更为亚马逊欧洲站带来了前所未有的发展机遇。在这场体育盛宴的推动下&#xff0c;欧洲站正展现出其无限的发展潜力和广阔的市场前景&#xff0c;为中国卖家乃至全…...

RPA是什么?探讨RPA发展的最新趋势 | RPA研究

随着人工智能和自动化技术的飞速发展&#xff0c;机器人流程自动化&#xff08;Robotic Process Automation&#xff0c;简称RPA&#xff09;正逐渐成为企业数字化转型的关键工具。RPA通过模拟人类用户的操作行为&#xff0c;自动化执行重复性高、规则性强的任务&#xff0c;从…...

sqlalchemy时间范围查询

1、sqlalchemy时间范围查询 在 SQLAlchemy 中,进行时间范围查询可以通过比较日期或时间字段来实现。假设你有一个模型 Event,它包含一个 timestamp 字段,你想查询在某个时间范围内的所有事件。以下是如何使用 SQLAlchemy 来实现这个查询的示例。 首先,确保你有 SQLAlchem…...

电脑不小心删除的文件怎么恢复?教你文件恢复的绝招

在日常使用电脑的过程中&#xff0c;我们有时会因为误操作或不小心而删除了重要的文件。面对这种情况&#xff0c;很多人可能会感到焦虑和无助。但其实&#xff0c;通过一些专业的方法和工具&#xff0c;我们有可能恢复这些被误删的文件。本文将介绍两种常见的恢复方法&#xf…...

stm32:使用和学习--硬件和程序

一硬件 1. GPIO 1.FT, TT功能 ft&#xff1a;five tolerate tt&#xff1a;three tolerate 1. FT&#xff08;Five-Volt Tolerant&#xff09;引脚 FT 引脚能够容忍高于 VDD 的输入电压&#xff08;例如 5V&#xff09;。这些引脚通常不具有连接到 VDD 的保护二极管&…...

ARM知识点二

一、指令 指令的生成过程 指令执行过程示例 if (a 0) {x 0; } else {x x 3; } //翻译为 cmp r0,#0 MOVEQ R1,#0 ADDGT R1,R1,#3指令获取&#xff1a;从Flash中读取 CMP R0, #0&#xff0c;控制器开始执行。 指令解码&#xff1a;解码器解析 CMP 指令&#xff0c;ALU比较R…...

C# ?的使用

栏目总目录 可空类型标记符&#xff08;?&#xff09; 说明&#xff1a; 可空类型标记符?用于指示某个值类型&#xff08;如int、float等&#xff09;可以为null。这是C# 2.0引入的一个特性&#xff0c;用于处理数据库查询、JSON解析等场景中可能出现的空值。 示例代码&am…...

【unity小技巧】unity性能优化以及如何进行性能测试

文章目录 前言GPU性能优化打包素材 CPU性能优化代码执行优化 性能测试Vector2.Distance 和 sqrMagnitude哪个好&#xff1f;动画切换优化shader属性优化 URP渲染器资产优化对象池优化删除没必要的空函数图片、音乐音效、贴图等素材压缩ScriptableObject优化参数参考完结 前言 …...

算法参考改进点/知识点

1、clip文章中改进点 图像编码器image encoder&#xff1a; 将全局平均池化层替换为注意力池化机制。注意力池化机制&#xff1a;通过一个单层的“transformer式”多头QKV注意力&#xff0c;其中查询query是基于图像的全局平均池表示。改进VIT&#xff08;Vision Transformer…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...