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 2月 9日 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 7月 9日 08:00 /usr/bin/sh -> bash*
[root@Fedora-Desktop ~]#
- 在有些发行版中,默认的系统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 7月 9日 08:01 /usr/bin/sh -> dash*
[root@Ubuntu-Desktop ~]#
- 使用不同的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,不过,它们通常需要配合分号或换行以及命令执行符(如;
、&
)来正确执行。 - 使用复杂逻辑如
&&
(前一命令成功后执行后一命令)、||
(前一命令失败后执行后一命令)、;
(无论前一命令成功与否都执行后一命令)等来进行命令的串联或并行执行。
命令分组可以实现:
- 逻辑分组:使得一组命令作为单一单元处理,比如在条件语句或循环中。
- 流程控制:控制命令的执行顺序和条件,比如基于前一个命令的成功或失败来决定是否执行下一个命令。
- 环境隔离:在子shell中执行命令组,可以保持或隔离环境变量和状态,不影响外部shell环境。
- 资源共享:在同一个子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 ~]#
协程
进程、线程、协程是现代计算中用于实现并发和多任务处理的三种基本概念,它们之间存在显著的区别:
-
资源拥有与隔离:
- 进程:是操作系统资源分配的最小单位,每个进程都有自己独立的地址空间,包括代码段、数据段、堆和栈。这意味着进程之间不共享内存,通信通常需要通过IPC(进程间通信)机制。
- 线程:是进程内的执行单元,线程之间共享所属进程的地址空间,包括代码、数据和文件描述符等资源。线程减少了上下文切换的开销,但增加了资源共享的复杂度,需要同步机制(如锁、信号量)来防止数据竞争。
- 协程:是一种用户态轻量级线程,运行在单个线程内,共享同一地址空间。协程的调度由程序自身控制,而非操作系统,因此切换更快且无需操作系统介入。协程通过协作而非抢占的方式进行任务切换,降低了同步开销。
-
系统开销:
- 进程:创建和销毁进程的开销相对较大,因为需要分配独立的地址空间和其他资源。
- 线程:相比进程,创建线程的开销较小,但仍需分配栈空间等资源,且线程间的切换由操作系统管理,有一定的开销。
- 协程:创建和切换协程的开销极小,仅需保存和恢复少量上下文,通常只需几字节到几十字节的栈空间。
-
调度方式:
- 进程和线程:通常由操作系统内核调度,可以被中断并由操作系统决定何时恢复执行。
- 协程:调度责任在于程序本身,程序员通过明确的yield(让出控制权)操作来控制协程的执行流,这使得协程能够避免不必要的调度,提高效率。
-
应用场景:
- 进程:适用于需要隔离资源和独立执行环境的任务,如服务器上运行的不同服务。
- 线程:适用于需要共享资源但又希望保持相对独立执行路径的场景,如Web服务器处理多个请求。
- 协程:特别适合于I/O密集型应用,如网络请求处理、异步IO、游戏开发等,它们能高效地处理大量的并发请求而无需大量线程。
-
资源占用:
-
- 进程占用资源最多,包括独立的内存空间。
- 线程相对较少,但仍需分配栈空间。
- 协程占用资源最少,一般只需要少量栈空间。
-
执行顺序:
- 线程:线程的执行顺序由操作系统调度,通常是无序的。
- 协程:通过程序控制,可以实现按需、有序的执行。
这篇文章可以大致看一下:一文彻底搞懂协程(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 5月 4日 12: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 -- 考试系统
文章目录 一,项目要求二,创建实体类ExamItem三,创建考试服务类ExamService3.1 全局变量 考题列表itemList(List< ExamItem >类型),答案数组answerArr (String[]类型),得分score3.2 初始化方法init()3.3 打印菜单…...

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

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

江协科技51单片机学习- p33 PWM呼吸灯和直流驱动电机调速
🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝…...

使用Jetbrains.Rider反编译Unity的DLL文件看源码
直接将dll文件的打开方式用Rider打开即可,打开BattleSeqGenertor.dll文件的效果如下:...

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

【每日一题】【二分图最大匹配】【经典板子题】有大家喜欢的零食吗 河南萌新联赛2024第(一)场:河南农业大学 C题 C++
河南萌新联赛2024第(一)场:河南农业大学 C题 有大家喜欢的零食吗 题目描述 在某幼儿园中共有 n n n个小朋友,该幼儿园的老师为这 n n n 个小朋友准备了 n n n 份不一样的零食大礼包。每个小朋友只能选择一个,但老…...

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

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

武汉流星汇聚:‘中国制造’闪耀欧洲站,体育赛事成亚马逊增长点
随着2024年的欧洲体育赛事激情四溢,欧洲杯与奥运会的双重盛会不仅点燃了全球体育迷的热情,更为亚马逊欧洲站带来了前所未有的发展机遇。在这场体育盛宴的推动下,欧洲站正展现出其无限的发展潜力和广阔的市场前景,为中国卖家乃至全…...

RPA是什么?探讨RPA发展的最新趋势 | RPA研究
随着人工智能和自动化技术的飞速发展,机器人流程自动化(Robotic Process Automation,简称RPA)正逐渐成为企业数字化转型的关键工具。RPA通过模拟人类用户的操作行为,自动化执行重复性高、规则性强的任务,从…...

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

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

stm32:使用和学习--硬件和程序
一硬件 1. GPIO 1.FT, TT功能 ft:five tolerate tt:three tolerate 1. FT(Five-Volt Tolerant)引脚 FT 引脚能够容忍高于 VDD 的输入电压(例如 5V)。这些引脚通常不具有连接到 VDD 的保护二极管&…...

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

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

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

算法参考改进点/知识点
1、clip文章中改进点 图像编码器image encoder: 将全局平均池化层替换为注意力池化机制。注意力池化机制:通过一个单层的“transformer式”多头QKV注意力,其中查询query是基于图像的全局平均池表示。改进VIT(Vision Transformer…...

electron 配置、打包 -报错解决
目录 一、配置途中遇到的问题: 二、 make 配置好后开始打包 三、Electron-builder 打包报错 一、配置途中遇到的问题: 1. 安装 yarn add electron -D 一直卡在这里失败 一直卡可以使用下面这个,然后再重新装依赖 1. 采用新的镜像地址 npm …...

基于STM32设计的智能鱼缸(华为云IOT)(200)
文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】设计实现的功能【3】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置【3】自动换水原理1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献1.4 开发工具的选择【1】设备端开发【2】上位…...

Django与数据库
目录 创建项目app 路由子表 数据库 创建数据库 什么是ORM 定义数据库表 Django Admin 管理数据 过滤条件 代码直接生成HTML 使用模板 前后端分离架构 对资源的增删改查处理 列出客户 添加客户 临时取消 CSRF 校验 修改客户信息 删除客户 Django中ORM的处理 数据模…...

大数据系列之:CentOS7安装R详细步骤
大数据系列之:CentOS7安装R详细步骤 一、下载R二、解压R三、创建安装目录四、指定安装目录五、安装编译依赖六、编译与编译安装七、设置环境变量八、激活环境变量九、执行R命令十、执行demo测试程序 一、下载R wget https://cran.r-project.org/src/base/R-4/R-4.4…...

Linux学习第57天:Linux PWM驱动实验
Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 本章的思维导图如下: 一、PWM驱动简析 1、设备树下的PWM控制节点 8 路 PWM 都属于 I.MX6ULL 的 AIPS-1 域,分为了两部分, PWM1~P…...

git 远程拉取指定文件
指定操作 git init 创建一个空的文件 git remote add orgin 远程仓库地址链接 表示添加远程库的地址 git config core.sparsecheckout true 打开sparsecheckout功能 注意:如果需要分支内所有文件,这个指令可以直接过忽略,则会拉取对应分支所有的文件…...

【css】 CSS3+JS做一个酷炫的仪表进度条3d进度条
创建一个动态进度环组件 在现代网页设计中,进度环是一种常见的视觉元素,用于展示任务的完成度或加载状态。本文将介绍如何使用Vue.js和Less创建一个动态进度环组件,该组件不仅具有美观的视觉效果,还能够根据用户输入动态改变颜色…...

uniapp小程序全局配置分享到朋友和朋友圈功能的实现
文章目录 1.创建/mixins/share.js插件2.全局配置3.编写share.js4.调用5.分享成功 1.创建/mixins/share.js插件 直接创建 2.全局配置 (1)找到main.js在下面引入share.js文件 (2)使用mixins混入vue中,这样就相当于在每一…...

Java优化后台分页
第一种情况:先查询出所有记录,再进行分页处理(分页中可以异步处理) 优化前: List<String> list Arrays.asList("1","2","3","4","5","6","…...

<数据集>电梯内人车识别数据集<目标检测>
数据集格式:VOC格式 图片数量:97张 标注数量(xml文件个数):97 标注类别数:3 标注类别名称: [person, motorcycle, bicycle] 序号类别名称图片数框数1person891322motorcycle78793bicycle2222 使用标注工具&#…...