Linux-理解shell

news2024/11/15 17:26:31

文章目录

    • 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 --forest
    PID TTY          TIME CMD
   1860 pts/0    00:00:00 bash
   1909 pts/0    00:00:00  \_ bash
   1943 pts/0    00:00:00      \_ bash
   2016 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 --forest
    PID TTY          TIME CMD
   1860 pts/0    00:00:00 bash
   2055 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 ~]# ls
 documents  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 --forest
    PID TTY          TIME CMD
   1305 pts/0    00:00:00 bash
   2253 pts/0    00:00:00  \_ bash
   2254 pts/0    00:00:00  |   \_ sleep
   2255 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
总计 32
  6034 -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.coloradmin.cn/o/1982635.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cornerstone加载本地Dicom文件第二弹 - Blob篇

🍀 引言 当我们刚接触Cornerstone或拿到一组Dicom文件时,如果没有ImageID和后台接口,可能只是想简单测试Cornerstone能否加载这些Dicom文件。在这种情况下,可以使用本地文件加载的方法。之前我们介绍了通过node启动服务器请求文件…

cuda pytorch安装详细教程 GPU版

1.先安装anaconda Anaconda 1.1这里用了最简单的方法,后面将pytorch直接安装到base配置下面了。 1.2下载安装,全部勾选。 一定添加文件夹到path中去,否则后面下载pytorch,无法传输。 1.3 通过cmd,输入conda --versio…

CSP-J 模拟题2

如果x大于45&#xff0c;则输出-1 设定一个整数now&#xff0c;他的初始值为9&#xff1b; 当x>now&#xff0c;就x-now&#xff0c;并且now--; 根据解析写代码1&#xff1a; #include <bits/stdc.h> using namespace std; int a[101010]; int main(){int x;cin>…

设计师必备网站,素材、灵感一手抓

设计师都在哪些地方找素材&#xff0c;找灵感&#xff1f;分享8个设计师必备网站&#xff0c;素材免费下载&#xff0c;还能看到很多国内外大神的设计之作&#xff0c;赶紧收藏起来吧~ 1、baotu 包图网_专注原创商用设计图片下载&#xff0c;会员免费设计素材模板独家图库 国内…

QChart笔记7:基于QPolarChart的雷达图、能力图

六边形战士这个词经常听说&#xff0c;用来描述这个词的是六边形雷达图/能力图。在网上搜索如何用QChart实现没有找到&#xff0c;于是就自己研究出一种写法。 先看看效果&#xff1a; 可以用这个图表示游戏中的人物属性&#xff0c;看看我的几个不太厉害的NPC。 在QT自带的实…

STL—容器—list【list的介绍和基本使用】【list的迭代器失效问题】

STL—容器—list list的使用并不难&#xff0c;有了之前使用string和vector的基础后&#xff0c;学习起来并不难。因此这里不在详细的讲解如何使用&#xff0c;而是大致的将其基本接口都熟悉一下 1.list介绍 list的文档介绍 list是可以在常数范围内在任意位置进行插入和删除…

解决App推广难题,Xinstall带你实现一键唤起,提升用户转化率!

在移动互联网时代&#xff0c;App的推广和运营成为了开发者们面临的一大挑战。如何让用户在各种场景下快速、便捷地唤起你的App&#xff0c;提升用户转化率和活跃度呢&#xff1f;今天&#xff0c;就让我们一起来了解一下Xinstall这一神奇的助手&#xff0c;它将如何解决这些痛…

基于YOLOv10和半监督学习的小麦麦穗检测算法:YOLOv10_ssod

基于YOLOv10和半监督学习的小麦麦穗检测算法&#xff1a;YOLOv10_ssod 1.引言2.数据集2.1 公共数据集2.2 自制数据集 3.YOLOv10算法及改进3.1 YOLOv10原版算法3.2 YOLOv10算法改进3.3 对比实验 4.半监督学习方法5.训练效果5.1最终检测效果5.2YOLOv10的精度曲线图5.3 半监督YOLO…

【Material-UI】Button 组件中的图标和标签按钮(Buttons with Icons and Label)详解

文章目录 一、基础用法1. 左侧图标&#xff08;startIcon&#xff09;2. 右侧图标&#xff08;endIcon&#xff09; 二、图标与标签的搭配三、高级用法和最佳实践1. 自定义图标2. 视觉一致性3. 动态图标 四、总结 在现代用户界面设计中&#xff0c;图标在提高用户体验&#xff…

如何礼貌且高效地应对工作中的无关问题

目录 礼貌而简洁地回应引导至相关资源设置边界利用自动回复工具委婉地拒绝建议通过正式渠道提问引导至相关资源的详细例子设置边界的详细例子深入探讨如何应对无关问题1. 培养对方的自主学习能力2. 利用团队合作3. 利用技术工具提高效率4. 定期培训和分享 具体的案例分析案例一…

初始Spring与SpringIOC容器

一、 Spring框架的基本理解 Spring框架是一款轻量级的开发框架&#xff0c; 核心思想是IOC (控制反转) 和AOP (面向切面编程)&#xff0c; 为Java 应用程序开发提供组件管理服务&#xff0c;用于组件之间的解耦&#xff0c;以及简化第三方JavaEE中间件技术的使用( JMS、任务调度…

python XML2SRS

step 1:练习XPATH 选取text-property标签具有nametext 属性值的标签的值 //text-property[nametext] import os import lxml.etree as etree dir "E:\\" for file in os.listdir(dir):if file.endswith(.rptdesign):with open(dirfile,r,encodingutf-8) as f:firs…

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(五)卡尔曼滤波器一:认知卡尔曼滤波器;协方差矩阵与方差;

卡尔曼滤波器 为了研究卡尔曼&#xff0c;我阅读了大量博文。不敢说完全吃透&#xff0c;但是在做一件什么事&#xff0c;可以通过下面这文章来理解&#xff0c;我读了不下五遍。并整理标准重点&#xff0c;添加自己的一些见解。 自动驾驶传感器融合算法 - 自动驾驶汽车中的激…

mprpc框架的应用示例

一、注册 有一个本地服务&#xff0c;我想把它发布成远程服务&#xff0c;首先在user.proto中定义rpc方法的描述&#xff0c;定义参数和响应的消息类型 然后在userservice.cc文件中通过继承UserServiceRpc这个类&#xff0c;重写一下响应的方法&#xff08;打四个动作&#xf…

深入了解Synchronized原理

深入了解Synchronized原理 第一章&#xff1a;并发编程中的三个问题1.1 可见性1.2 原子性1.3 有序性 第二章&#xff1a;Java内存模型(JMM)2.1 计算机结构简介2.2 Java内存模型 Java Memory Molde 第三章&#xff1a;synchronized保证三大特性3.1 synchronized保证原子性3.2 sy…

收藏!AIGC创业者必备,AI绘画商业变现保姆级全攻略

随着AI爆火后&#xff0c;AI绘画也随之兴起&#xff0c;每次都有人问我&#xff0c;AI绘画如何变现。来&#xff0c;既然大家对商业赚钱这一块还是很关心的&#xff0c;那今天给大家分享我正在做的AI绘画的商业项目保姆级攻略&#xff0c;重点会偏向于术。全程很干&#xff0c;…

六、8 TIM编码器计数和测速代码

&#xff08;1&#xff09;所用函数 &#xff08;2&#xff09; 1&#xff09; 上拉输入和下拉输入选择&#xff1a;与外部模块保持一致 若外部模块空闲默认输出高电平&#xff0c;就选择上拉输入&#xff0c;默认输入高电平&#xff1b;若外部模块空闲默认输出低电平&#x…

sql注入——二次注入

二次注入 简介工具环境具体实施 简介 二次注入是一种较为隐蔽的 SQL 注入攻击方式。它并非直接在输入时进行攻击&#xff0c;而是先将恶意数据存储到数据库中&#xff0c;这些数据看似正常。随后&#xff0c;应用程序在后续的操作中&#xff0c;再次使用或处理这些之前存储的恶…

黑马微服务—Docker

Docker 文章目录 Docker1 快速入门1.1 部署MySQL1.2 命令解读 2 Docker基础2.1 常见命令2.2 数据卷2.2.1 数据卷**2.2.2 数据卷命令**2.2.3 挂在本地目录或文件 2.3 自定义镜像2.3.1 镜像结构2.3.2 Dockerfile2.3.3 构建镜像 2.4 容器网络 3 项目部署3.1 部署java项目3.2 部署前…

MySQL 实战 45 讲(01-05)

本文为笔者学习林晓斌老师《MySQL 实战 45 讲》课程的学习笔记&#xff0c;并进行了一定的知识扩充。 sql 查询语句的执行流程 大体来说&#xff0c;MySQL 可以分为 Server 层和存储引擎层两部分。 Server 层包括连接器、查询缓存、分析器、优化器和执行器。 连接器负责接收客…