命令行式Shell
1.1、命令行式Shell简介

命令行式ShellCommand Line InterfaceShell

不同的Shell的本质都是为了给用户提供一个在操作系统下操作的便捷而安全的界面。

为了达到这个目标,每个Shell都提供了基本的功能,它们包括:

  • 环境控制
  • 命令行解释功能
  • 启动指定程序
  • 输入输出重定向
  • 管道连接
  • 文件名置换
  • 变量维护
  • Shell编程
1.2、常见的命令行式Shell
全称简称系统级配置用户级配置系统默认
POSIX Shellsh/etc/profile~/.profileUNIX
Bourne Shellsh/etc/profile~/.profileUNIX
Almquist Shellash/etc/profile~/.profileAlpineLinux
Debian ashdash/etc/profile~/.profileDebian GNU/Linux
C Shellcsh/etc/csh.cshrc~/.cshrcBSD
TC Shelltcsh/etc/csh.cshrc~/.cshrcFreeBSD
Korn Shellksh/etc/profile~/.profileOpenBSD
Public Domain Korn Shellpdksh/etc/profile~/.profile
MirBSD Korn Shellmksh/etc/profile~/.profile

MirBSD

Android

Bourne Again Shellbash/etc/profile

~/.bashrc

~/.bash_profile

GNU/Linux

macOS

Z Shellzsh/etc/zprofile~/.zshrc
Friendly Interactive SHellfish/etc/fish/config.fish~/.config/fish/config.fish
1.3、操作系统中已经存在的命令行式Shell

一般的,在/etc/shells配置文件中记录了操作系统中已经存在了哪些命令行式Shell

示例:

这里记录了操作系统中已经存在的这些命令行式Shell的位置。

一个操作系统中通常预装了不止一个Shell,为啥要安装那么多的Shell呢?原因如下:

  • 不同的Shell能干的事情不一样,有的Shell能力大,有的Shell能力小。 有时候,还要限制某些Shell的功能,不能让它太强大了,比如,游客登、普通用户、管理员这几种用户登录的时候, 用的Shell就可能不一样。
  • 不同的Shell安装文件大小不一样,这个为啥重要呢?因为今天容器化的时代,容器太大的话影响下载速度,不利于快速构建。
  • 不同的Shell运行速度不一样,一些功能很强大的Shell运行速度可能就会降低,对于很在乎启动速度的系统, 就会使用极简的Shell(启动的时候,会加载大量的配置文件,这些配置文件通常是Shell脚本)。
1.4、切换登录Shell

GNU/LinuxmacOS等系统默认使用的登录Shellbash,我们也可以切换到其他的命令行式Shell

通过chsh命令进行切换,示例:

chsh -s $(command -v zsh)

重新登录后,Terminal就会使用切换后的Shell

1.5、当前使用的命令行式Shell

登录Shell是你登录系统之后使用的默认Shell,但是你可以零时换成其他的Shell, 只要使用对应的Shell命令即可切换。

环境变量SHELL记录了你使用的是哪个Shell进行登录的, 但是并不会记录你零时切换到哪个Shell了。

如果你是在Terminal中直接执行命令, 而不是通过Shell脚本执行命令, 那么,你可以通过如下命令获得你当前用的是哪个Shell

echo $0

注意$0Shell脚本里是这个脚本的文件名。

Shell脚本中判断当前运行时是哪个Shell

if command -v which > /dev/null && [ "$(type which)" = "which is a shell builtin" ]; then
    echo "this is zsh $ZSH_VERSION";
elif command -v caller > /dev/null && [ "$(type caller)" = "caller is a shell builtin" ]; then
    echo "this is bash $BASH_VERSION";
elif command -v enum > /dev/null && [ "$(type enum)" = "enum is a special shell builtin" ]; then
    echo "this is ksh $KSH_VERSION";
else
    echo "this is ash";
fi

依据:

Shell特有的内部命令特有的环境变量
zshwhichZSH_VERSION
bashcallerBASH_VERSION
kshenumKSH_VERSION
tcshbuiltinsversiontcsh