Skip to content
Published at:

Shell命令解释器

作用:交互式地解释、执行用户输入的命令,将用户的操作翻译成机器可以识别的语言,完成相应功能 大白话: 和电脑交互的一个解释器

常见的Shell:

  • sh: sh 由Steve Bourne开发,是Bourne Shell的缩写,sh 是Unix 标准默认的shell。
  • bash: bash是Linux系统默认使用的Shell,它由Brian Fox 和Chet Ramey共同完成,是BourneAgain Shell的缩写
  • zsh: 一种结合了bash、tcsh和korn的特性,同时提供高级编程特性、共享历史文件和主题化提示符的高级 shell
  • fish: https://github.com/fish-shell/fish-shell

查看电脑上安装的Shell

bash
$  cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/bin/rbash
/bin/dash
/bin/zsh

查看当前电脑使用的shell

bash
$ echo $SHELL

内部命令外部命令

内部命令:

是shell程序的一部分,其中包含的是一些比较简单的linux系统命令,这些命令由shell程序识别并在shell程序内部完成运行,通常在linux系统加载运行时shell就被加载并驻留在系统内存中。内部命令是写在bash源码里面的,其执行速度比外部命令快,因为解析内部命令shell不需要创建子进程。比如:exit,history,cd,echo等。

外部命令:

是linux系统中的实用程序部分,因为实用程序的功能通常都比较强大,所以其包含的程序量也会很大,在系统加载时并不随系统一起被加载到内存中,而是在需要时才将其调用内存。通常外部命令的实体并不包含在shell中,但是其命令执行过程是由shell程序控制的。shell程序管理外部命令执行的路径查找、加载存放,并控制命令的执行。外部命令是在bash之外额外安装的,通常放在/bin,/usr/bin,/sbin,/usr/sbin......等等。可通过“echo $PATH”命令查看外部命令的存储路径,比如:ls、vi等。

bash
$ type pwd
pwd is a shell builtin

$ type ps
ps is /bin/ps

$ which pwd
pwd: shell built-in command

$ which ps
/bin/ps

环境变量

env命令:打印环境当前的变量

bash
$ env

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

PATH变量:

当你敲一个命令的时候,Shell解释器看这个是内部命令,还是外部命令,如果是内部命令,就直接执行了, 如果是外部命令,会去PATH变量目录下一个一个找,找到了就执行,找不到就返回"找不到命令"

bash
# 变量赋值
PATH="/usr/local/opt"

# 相当于:PATH=/usr/local/opt:/usr/local/opt/sqlite/bin
PATH=$PATH:/usr/local/opt/sqlite/bin

# 变量的范围:加了export了,导出, 外部也能用了
export PATH=$PATH:/usr/local/opt/sqlite/bin

终端在启动的时候会加载/执行的文件:

和登录方式有关, 不全是这种方式和这几个文件

img

两个核心目录,更改配置也会去这里

  • /etc/profile: 一般全局配置目录
  • ~/.bashrc: 一般用户配置目录

修改shell

修改vim /etc/passwd文件

bash
$ sudo vim /etc/passwd

shibin:x:1000:1000:shibin,,,:/home/shibin:/bin/bash
sshd:x:122:65534::/run/sshd:/usr/sbin/nologin

通过chsh命令修改:

bash
$ chsh -s /bin/sh

命令行帮助

  • man(manual手册)
  • -h/-help
  • info

man手册:

该手册分成很多章节(section); man 中各个 section 意义如下:**

1.Standard commands(标准命令)

2.System calls(系统调用,如open,write)

3.Library functions(库函数,如printf,fopen)

4.Special devices(设备文件的说明,/dev下各种设备)

5.File formats(文件格式,如passwd)

6.Games and toys(游戏和娱乐)

7.Miscellaneous(杂项、惯例与协定等,例如Linux档案系统、网络协定、ASCII 码;environ全局变量)

8.Administrative Commands(管理员命令,如ifconfig)

man命令

bash
$ man printf		# 打开第一个找到的
$ man -a printf	# 打开所有找到的printf,一个一个打开
$ man -k printf # 在man手册描述简介和手册名中搜索"printf", 然后打印出来
$ man -w printf # 打印命令的man手册位置
$ man 3 printf  # 打开每3个章节的printf手册

man手册命令

  • h: help帮助
  • q: quit退出
  • e ^E j ^N CR: 向下滚动一行
  • y ^Y k ^K ^P: 向上流动一行
  • f ^F ^V SPACE: 向下滚动一个窗口
  • b ^B ESC-v 向上滚动一个窗口

man手册中的语法大纲详解:

bash
$ git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
            [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
            [-u | --set-upstream] [-o <string> | --push-option=<string>]
            [--[no-]signed|--signed=(true|false|if-asked)]
            [--force-with-lease[=<refname>[:<expect>]]]
            [--no-verify] [<repository> [<refspec>...]]
  • []: 可选参数
  • |: 多选一
  • <>: 如果设置了相应的选项,<>中的内容必填
  • ...: 可变参数,一个或多个参数
  • ---的区别:一般-后面加单词简写,--后面加单词全拼, 比如: [-f | --force] [-d | --delete] [-v | --verbose]

常用命令

  • 文件
  • 文本
  • 打包
  • 进程

文件

  • touch:创建新文件
  • ln:命令主要用于创建链接文件(link)
  • mkdir:创建一个新的目录(make directory)
  • rmdir:命令删除一个目录(remove directory)
  • rm:删除文件或目录(remove)
  • cp:将给出的文件或目录复制到另一个文件或目录中(copy)
  • mv:移动文件或目录,也可以给文件或目录重命名(move)
  • chmod:修改文件权限有两种使用格式:字母法与数字法
  • chown:用于修改文件所有者
  • chgrp:用于修改文件所属组

touch:创建新文件

bash
# 创建普通文件,文件不存在就创建
$ touch file_name

ln:用于创建链接文件

链接文件分为软链接和硬链接:

  • 软链接:软链接不占用磁盘空间,源文件删除则软链接失效。

  • 硬链接:硬链接只能链接普通文件,不能链接目录。

bash
# 创建硬链接语法:ln 源文件 链接文件
# 创建软链接语法:ln -s 源文件 链接文件

mkdir:创建一个新的目录

bash
$ mkdir dir_name

# 创建多级目录
$ mkdir -p a/b/c/d

rmdir:命令删除一个目录

Note:目录必须为空目录,鸡肋; 一般会用rm

rm:删除文件或目录

bash
$ rm -rf file_name/dir_name

cp:将给出的文件或目录复制到另一个文件或目录中(copy)

bash
$ cp file_name dir_name/file_name
$ cp -r dir_name dir_name

mv:移动文件或目录,也可以给文件或目录重命名(move)

bash
$ mv file_name1 file_name2
$ mv -f dir_name1 dir_name2

chmod:修改文件权限

有两种使用格式:字母法与数字法

[ u/g/o/a ]含义
uuser 表示该文件的所有者
ggroup 表示与该文件的所有者属于同一组( group )者,即用户组
oother 表示其他以外的人
aall 表示这三者皆是
[ +-= ]含义
+增加权限
-撤销权限
=设定权限
rwx含义*
rread 表示可读取,对于一个目录,如果没有r权限,那么就意味着不能通过ls查看这个目录内部的内容。
wwrite 表示可写入,对于一个目录,如果没有w权限,那么就意味着不能在目录下创建新的文件。
xexcute 表示可执行,对于一个目录,如果没有x权限,那么就意味着不能通过cd进入这个目录。
bash
$ chmod u+x file_name
$ chmod u+r file_name
$ chmod a+x file_name

数字法:

r读取权限,数字代号为 "4"
w写入权限,数字代号为 "2"
x执行权限,数字代号为 "1"
-不具任何权限,数字代号为 "0"
bash
$ chmod 777 file_name
# 修改目录的所有权限
$ chmod -R 777 dir_name

chown:用于修改文件所有者

bash
# 语法: chown 所属人:所属组 文件名
$ chown shibin:shibin file_name
# 修改目录所有历文件所属人:所属组
$ chown -R shibin:shibin dir_name

chgrp:用于修改文件所属组

用的少, 用chown就可以了

文本

  • cat:查看文件全部内容
  • tail:查看文件尾部的内容

cat:查看文件全部内容

bash
$ cat file_name

tail:查看文件尾部的内容

bash
# 查看文件尾部n行内容
$ tail -n 10 .zshrc

# 监控文件尾部的内容
$ tail -f .zshrc

打包

  • tar:归档压缩和解压缩
  • zip和unzip:zip格式压缩和解压缩

tar:归档压缩和解压缩

bash
# 压缩
$ tar -zcvf xxx.tar.gz file1 file2 file3

# 解压
$ tar -zxvf xxx.tar.gz

# 选项详解;
# 	-z: gzip压缩
# 	-c: 创建(create)
# 	-v: 打印详情(verbose)
# 	-f: 指定档案文件名称(file)
# 	-x: 解压(Extract)˙

zip和unzip:zip格式压缩和解压缩

bash
# install
$ sudo apt-get install zip
$ sudo apt-get install unzip

# 压缩和解压缩
$ zip -r compressed_filename.zip folder_name
$ unzip compressed_filename.zip -d destination_folder

进程

  • ps:查看进程的详细状况process status
  • top:动态显示运行中的进程
  • kill:发送一个信号给指定的进程
  • killall:通过名字kill进程

ps:查看进程的详细状况(process status)

bash
$ ps aux
$ ps ajx

#   -a  显示终端上的所有进程,包括其他用户的进程
#   -u  显示进程的详细状态
#   -x  显示没有控制终端的进程
#   -w  显示加宽,以便显示更多的信息
#   -r  只显示正在运行的进程run
#   -j  列出与作业控制相关的信息

top:动态显示运行中的进程

bash
$ top

# 退出q或ctrl-c

kill:发送一个信号给指定的进程

bash
# 查看所有的信号
$ kill -l

# 给进程号为10000的进程发送9信号:打死进程
$ kill -9 10000

killall:通过名字kill进程

bash
$ killall process_name

其它符号

  • >:输出重定向(会覆盖原来的内容)
  • >>:输出重定向(会追加到文件的尾部)
  • |:管道;将前面执行的结果传给下一个命令去处理

> >>:输出重定向

bash
# 将ls -ahl的输出写入到a.txt(不存在就创建文件,存在就覆盖内容),
$ ls -ahl > a.txt

# 将a.out的输出写入到a.txt(不存在就创建文件,存在就覆盖内容)
$ ./a.out > a.txt

# 将ls -ahl的输出追加到到a.txt尾部(不存在就创建文件)
$ ls -ahl >> a.txt

# 将a.out的输出追加到到a.txt尾部(不存在就创建文件)
$ ./a.out >> a.txt

|:将前面执行的结果传给下一个命令去处理

bash
$ ls -ahl | grep "a.out"
$ ps -aux | grep "a.out"

其它命令

  • sudo:让后面的命令以超级用户的权限去执行(superuser do)
  • exit:退出
  • alias:命令别名
  • find:查找文件
  • locate:查找文件
  • file:查看文件及文件属性
  • nautilus:用文件管理器打开当前目录

sudo:让后面的命令以超级用户的权限去执行(superuser do)

bash
# 这些命令会copy文件到root用户权限的目录,普通用户是没有权限的,需要加sudo
$ sudo apt-get install tree
$ sudo make install

exit:退出

  • 退出bash
  • 退出vim
  • ...

alias:给命令行起一个别名

猜下面名字人是谁?

巴勃罗.迭戈.荷瑟.山迪亚哥.弗朗西斯科.德.保拉.居安.尼波莫切诺.克瑞斯皮尼亚诺.德.罗斯.瑞米迪欧斯.西波瑞亚诺.德.拉.山迪西玛.特立尼达.玛利亚.帕里西奥.克里托.瑞兹.布拉斯科.毕加索

命令行也一样,当一个命令很多,而且经常用, 这时候就可以给它用一个别名来替代

bash
# 查看当前环境的所有别名
$ alias

# 配置:在终端启动会加载的目录中配置~/.bashrc
alias c="code"
alias ll='ls -hal'
alias open='nautilus' # 从终端打开文件管理器

find:查找文件

bash
# 语法:find   路径  -name  file_name
$ find /home -name*.c”
$ find . -type f

locate:查找文件

去数据库查找,速度比较快,数据库是定时更新,有时间限制,最近增加/删除的文件会找不到

bash
# 语法: locate file_name
$ locate stdlib.h
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/stdlib.h
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/xlocale/_stdlib.h
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/xlocale/_stdlib.h
/Library/Developer/CommandLineTools/usr/include/c++/v1/stdlib.h
/usr/local/Cellar/freetype/2.10.2/include/freetype2/freetype/config/ftstdlib.h
/usr/local/Cellar/llvm/10.0.1/Toolchains/LLVM10.0.1.xctoolchain/usr/include/c++/v1/stdlib.h
/usr/local/Cellar/llvm/10.0.1/include/c++/v1/stdlib.h

file:查看文件及文件属性

Windows 后缀名决定他是什么文件: mp4,zip, png

bash
$ file .bashrc
.bashrc: ASCII text

$ file a.out
a.out: Mach-O 64-bit executable x86_64

nautilus:用文件管理器打开当前目录(Ubuntu)

bash
$ nautilus

第三方命令

  • tree:显示树目录和文件
  • nmap:查看端口号占用
  • fzf:模糊搜索工具(文件,命令history,进程 ...)
  • cheat:命令行小抄
  • neofetch:系统信息工具
  • ...

tree:显示树目录和文件

bash
# install
$ sudo apt-get install tree

# use
$ tree					# 显示当前所在目录树结构
$ tree dir			# 显示dir目录的树结构
$ tree -L 2 dir # 显示dir下面2层目录结构

nmap:查看端口号占用

bash
$ nmap 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-16 00:34 CST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00031s latency).
Not shown: 961 closed ports, 35 filtered ports
PORT     STATE SERVICE
5432/tcp open  postgresql
8080/tcp open  http-proxy
8088/tcp open  radan-http
9090/tcp open  zeus-admin

fzf:模糊搜索工具(文件,命令history,进程 ...)

bash
# install
$ sudo apt-get install fzf
  • Ctrl + R: 搜索命令历史记录
  • Ctrl + T: 搜索当前目录下的文件
  • ...

cheat:命令行小抄

bash
# 查看
$ cheat tar
# To extract an uncompressed archive:
tar -xvf /path/to/foo.tar

# To create an uncompressed archive:
tar -cvf /path/to/foo.tar /path/to/foo/

# To extract a .gz archive:
tar -xzvf /path/to/foo.tgz

# 编辑(本质是保存在特定目录的文件内)
$ cheat -e tar

neofetch:系统信息工具

bash
# install安装
$ sudo apt-get install neofetch

# 使用
$ neofetch
                    'c.          Ben@WShiBin.local
                 ,xNMM.          -----------------
               .OMMMMo           OS: macOS Catalina 10.15.6 19G2021 x86_64
               OMMM0,            Host: MacPro6,1
     .;loddo:' loolloddol;.      Kernel: 19.6.0
   cKMMMMMMMMMMNWMMMMMMMMMM0:    Uptime: 31 days, 12 hours, 8 mins
 .KMMMMMMMMMMMMMMMMMMMMMMMWd.    Packages: 87 (brew)
 XMMMMMMMMMMMMMMMMMMMMMMMX.      Shell: zsh 5.7.1
;MMMMMMMMMMMMMMMMMMMMMMMM:       Resolution: 1920x1080@2x
:MMMMMMMMMMMMMMMMMMMMMMMM:       DE: Aqua
.MMMMMMMMMMMMMMMMMMMMMMMMX.      WM: Quartz Compositor
 kMMMMMMMMMMMMMMMMMMMMMMMMWd.    WM Theme: Blue (Light)
 .XMMMMMMMMMMMMMMMMMMMMMMMMMMk   Terminal: iTerm2
  .XMMMMMMMMMMMMMMMMMMMMMMMMK.   Terminal Font: Monaco 14
    kMMMMMMMMMMMMMMMMMMMMMMd     CPU: Intel Xeon E5-2697 v2 (24) @ 2.70GHz
     ;KMMMMMMMWXXWMMMMMMMk.      GPU: AMD FirePro D300, AMD FirePro D300
       .cooc,.    .,coo:.        Memory: 20936MiB / 32768MiB

oh-my-bash:bash的命令,配置,主题管理器, 安装

Oh-my-zsh:

命令中的常用快捷键:

  • Tab键: 补全
    • 补齐命令
    • 补齐路径
    • 显示当前目录下的所有目录和文件
  • c**l**ear / Ctrl + l: 清除终端上的显示
  • ctlr + c: 作用是中断终端的操作
  • ctrl + p (**↑**): 从当前位置向上遍历(Previous)
  • ctrl + n(**↓**): 从当前位置向下遍历(Next)
  • ctrl + b (←): 光标左移(Backward)
  • ctrl + f (→): 坐标右移(Forward)
  • ctrl + a: 移动到头部(Ahead)
  • ctlr + e: 移动到尾部(End)
  • ctrl + d: 退出
  • ctrl + u: 删除命令
  • ctrl + w: 删除光标前面一个单词

命令的本质?

image-20200916094920394

cat命令实现流程:

c
#include <stdio.h>

// cat home.md
// ./a.out home.md
// argc == 2
// argv == {"cat", "home.md"}
int main(int argc, char* argv[]) {
    // do something with argv ...
  	// ...
		// open file --> read --> printf --> close
  	// ...
    return 0;
}

资料:

命令这么多怎么记?

  • 多用, 多查(man手册, --help)
  • 辅助工具:
    • cheat:查看小抄
    • fzf/history:模糊搜索历史记录
    • man:查看手册
    • tab补全
    • alias改成自己熟悉的
  • 记忆:联想记忆,大多是缩写
  • 站在Shell解释器的角度去思考:解释,翻译

选项常用简写: 一般性

  • -a all
  • -c create/common
  • -d delete/depth
  • -f file/force
  • -h human/
  • -i infomation/install
  • -r recursive递归
  • -p parent
  • -v verbose
  • -z gzip
  • -m message(git commit -m "xixi")
  • etc