End

bash 教程-1 shell 基础 快捷键 目录堆栈 操作历史

本文地址


目录

Bash 教程

本文改编自 网道的 Bash 教程,主要为了精简大量本人不感兴趣的内容。

Bash 简介

Bash 是 Unix 系统和 Linux 系统的一种 Shell(命令行环境),是目前绝大多数 Linux 发行版的默认 Shell。

Shell 的原意是 外壳,跟 kernel(内核)相对应。

Shell 提供了一个与用户对话的命令行环境(command line interface,CLI),通过 CLI 将用户从键盘输入的命令送入操作系统执行,并将结果返回给用户。

Shell 有很多种,只要能给用户提供命令行环境的程序,都可以看作是 Shell。

Bash 基础命令

wsl             # 启动后显示的【bqt@BQT-X】代表【user@host】,【$】代表普通用户,【#】代表 root 用户
uname -a        # 显示电脑以及操作系统的相关信息【Linux BQT-X 4.19.128... GNU/Linux】
cat /etc/shells # 查看当前的 Linux 系统安装的所有 Shell
bash            # 如果当前运行的 Shell 不是 Bash,可以输入 bash 命令启动 Bash
exit            # 退出 Bash 环境
echo $SHELL     # 【/bin/bash】,查看当前运行的 Shell
bash --version  # 【echo $BASH_VERSION】,查看本机的 Bash 版本
  • cd:change directory 改变目录
    • 不带参数的 cd 命令默认会进入 /home/当前用户/c/Users/当前用户 目录
    • cd -:回到前一个目录
    • cd ..:回到父目录
    • cd aaa:进入指定目录,可以是相对目录或绝对目录
  • pwd:打印工作目录路径
  • lsll:列出当前目录中的所有文件
  • touch aaa.txt:在当前目录下新建一个文件
  • cat aaa.txt:打印文件内容
  • mkdir aaa:在当前目录下新建一个目录
  • rm:remove 删除文件
    • rm aaa.txt:删除指定的文件
    • rm -r aaa:删除指定的目录,参数 r 是递归(recusive)的意思
  • rmdir:remove dir 删除文件夹
  • mv aaa.txt bbb:移到文件
  • q:quit 结束一个命令
  • explorer:导航
    • explorer .:打开当前目录
    • explorer aa:使用文件管理器打开目录,或使用默认程序打开文件

Bash 基本语法

命令格式

# 基本格式
command [arg1...argN] # command 是具体的命令,或者一个可执行文件
echo foo  bar         # 【foo bar】,Bash 使用空格或 Tab 分割参数,多个连续的空格会被当做一个空格

# 组合命令
Command1; Command2    # 先执行 Command1,结束后再继续执行 Command2
Command1 && Command2  # 先执行 Command1,如果 Command1 运行成功,则继续运行 Command2
Command1 || Command2  # 先执行 Command1,如果 Command1 运行失败,则继续运行 Command2

注释

Bash 中的 # 表示注释,可以放在行首,也可以放在行尾。

# 本行是注释
echo 'Hello World' # 井号后面的部分也是注释

# 下面是多行注释
:<<EOF
这里面都是注释内容...
这里的 EOF 也可以使用其他符号
EOF

echo 命令

echo 白 "白" '白'   # 【白 白 白】,字符串可以使用双引号、单引号包裹,也可以省略引号
echo               # 【(换行)】,默认情况下,输出的文本末尾会有一个回车符
echo -n a; echo b  # 【ab】,取消末尾的回车符

type 命令

# type 命令用来判断命令的来源(内置命令、外部程序)
type echo     # 【echo is a shell builtin】,内置命令
type ls       # 【ls is aliased to `ls --color=auto'】,别名
type bash     # 【bash is /usr/bin/bash】,文件

type -a echo  # 查看一个命令的所有定义
type -t bash  # 【file】,返回一个命令的类型:alias,keyword,function,builtin,file

Bash 快捷键

基础操作快捷键

  • 复制内容:选中即复制(勾选了"选择时复制"),或【Ctrl + Insert】
  • 粘贴内容:点击中键粘贴,或【Shift + Insert】
  • 搜索内容:【Alt + F3】
    • 按【Enter】选中下一个匹配的内容
    • 按【Shift + Enter】选中上一个匹配的内容
  • 缩放文字:【Ctrl + +/-】
  • 清除内容
    • 【Ctrl + L】,将当前行移到屏幕的第一行,不清除任何内容,通过滚轮可以查看滑出屏幕的内容
    • 【clear】,清除屏幕内容,cmd 下的命令是【cls】
    • 【Alt + F8】,重置后之前的内容就找不回来了
  • 窗口全屏:Alt + F11,再按一次还原
  • 中止命令
    • 【Ctrl + C】,中止命令
    • 【Ctrl + D】,关闭会话
    • 【exit】,退出输入模式
  • 历史记录:【↑/↓】浏览已执行命令的历史记录
  • 滚动屏幕:【Shift + PgUp/PgDn】
  • 插入参数:【Alt + .】,插入上一个命令的最后一个词

自定义快捷键

  • 全局的键盘绑定文件默认为 /etc/inputrc
  • 用户自定义键盘绑定文件为 ~/.inputrc

千万不要加这个,否则很容易出现各种快捷键不能用的问题

$include /etc/inputrc   # 需要加入这行,保证全局绑定不会被遗漏
"\C-t":"pwd\n"          # 表示将【Ctrl + T】绑定为运行【pwd】命令
"\C-e":"explorer .\n"   # 表示将【Ctrl + E】绑定为运行【explorer .】命令

行操作

Bash 内置了 Readline 库,具有这个库提供的很多行操作功能。这个库默认采用 Emacs 快捷键,也可以改成 Vi 快捷键。

set -o vi          # 使用 Vi 快捷键
set -o emacs       # 使用默认的 Emacs 快捷键
bash --noediting   # 启动一个不带行操作功能的 Bash

如果想永久性更改编辑模式,可以将命令 set editing-mode vi 写在 Readline 的配置文件 ~/.inputrc 中。

移动光标

  • 移动到当前单词的词首/词尾:【Alt + B/F】,或【Ctrl + ←/→】
  • 移动到行首/行尾:【Ctrl + A/E】,或【HOME/END】
  • 左/右移动一个字符:【Ctrl + B/F】,或【←/→】

修改内容

下文的 BackSpace 缩写为 BS

通过命令剪切的内容只能通过【Ctrl + Y】粘贴,注意不是传统的【Ctrl + V】

  • 剪切光标左/右侧的所有内容:【Ctrl + U/K】
  • 剪切光标左/右侧的单词:【Ctrl + W/Del】或【Alt + BS/D】
  • 删除光标左/右侧的字符:【Ctrl + H/D】或【BS/Del】
  • 将光标位置的与它前面一位的词交换位置:【Alt + T】
  • 将光标位置的字符与它前面一位的字符交换位置:【Ctrl + T】
  • 将光标位置至词尾的所有字母转为大/小写:【Alt + U/L】

Tab 自动补全

  • Tab:命令或路径自动补全
    • 命令或路径输入到一半的时候,按一次 Tab 键,会自动补全剩下的部分
    • 如果符合条件的有多个,就需要连续按两次 Tab 键,Bash 会提示所有符合条件的命令或路径
    • 如果以 $ 开头,则自动补全变量名,例如 $US -> $USER
    • 如果以 ~ 开头,则自动补全用户名,例如 ~bq -> ~bqt/
    • 如果以 @ 开头,则自动补全主机名(主机名以列在 /etc/hosts 文件里面的主机为准)
  • Alt + /:尝试文件路径补全,即使没有输入任何内容,连续点击两次,也会把当前目录所有文件/文件夹列出来
  • 几个特殊的快捷键:非常适用于在不输入任何前缀内容时,打印所有信息
    • 以下几个快捷键一般没法用,因为没法在快捷键中输入这几个符号(需要在按下 Shift 键的同时才能输入)
    • 以下几个快捷键等价于:先按 Ctrl + X,再按 $~@!/
    • Alt + $:变量名
    • Alt + ~:用户名
    • Alt + @:主机名
    • Alt + !:命令
    • Alt + ?:列出可能的补全,等价于先按 Ctrl + X,再按/(注意不是?)
  • Alt + *:在命令行一次性插入所有可能的补全 --- 不知道怎么用
  • Alt + Tab:尝试用.bash_history里面以前执行命令,进行补全 --- 不常用

其他快捷键

  • Ctrl + V:注意,这不是粘贴快捷键,而是将下一个输入的特殊字符变成字面量,比如将回车变成 ^M
  • Alt + .:插入上一个命令的最后一个词,这个命令有时会非常方便
  • Ctrl + O:等同于【先回车,再 ↑】,重复执行某个序列的命令时很有用
  • Ctrl + [:等同于 ESC

Bash 目录堆栈

  • 为了方便用户在不同目录之间切换,Bash 提供了目录堆栈功能
  • 默认情况下,Bash 只记忆前一次所在的目录,可以使用 cd - 命令返回前一次的目录
  • 如果希望记忆多重目录,可以使用 pushd/popd 命令操作目录堆栈

pushd popd 命令

  • 使用 pushd dirname 命令可以进入指定的目录,类似 cd 命令
  • 第一次使用 pushd 命令时,会将当前目录先放入堆栈,然后将所要进入的目录也放入堆栈,位置在前一个记录的上方
  • 以后每次使用 pushd 命令,都会将所要进入的目录,放在堆栈的顶部
  • 使用 popd 命令会移除堆栈当前的顶部记录,并进入堆栈新的顶部目录
pwd          # 当前处在主目录【/home/me】,堆栈为空
pushd ~/foo  # 当前堆栈为【/home/me/foo /home/me】
dirs         # 显示目录堆栈的内容
pushd /etc   # 当前堆栈为【/etc /home/me/foo /home/me】
popd         # 当前堆栈为【/home/me/foo /home/me】
popd         # 当前堆栈为【/home/me】
popd         # 目录不变,当前堆栈为空

pushd popd 参数

  • 目录参数:表示将该目录放到堆栈顶部,并进入该目录
  • 参数 -n:表示仅操作堆栈,执行完当前命令后还停留在当前目录
  • 整数参数:表示仅操作堆栈中指定位置(从0开始计算)的记录,不改变目录
pushd dir    # 将该目录放到堆栈顶部,并进入该目录。popd 没有这个参数
pushd -n dir # 将该目录放到堆栈顶部,执行完成后还停留在当前目录
popd -n      # 删除堆栈顶部的记录,执行完成后还停留在当前目录

pushd +3     # 将从栈顶算起的3号目录,移动到栈顶
pushd -3     # 将从栈底算起的3号目录,移动到栈顶

popd +0      # 删除从栈顶算起的0号目录,即删除第一个目录
popd -0      # 删除从栈底算起的0号目录,即删除最后一个目录
popd +3      # 删除从栈顶算起的3号目录,即删除第 4 个目录
popd -3      # 删除从栈底算起的3号目录,即删除倒数第 4 个目录

dirs 命令

dirs 命令可以显示目录堆栈的内容,一般用来查看 pushdpopd 操作后的结果。

  • -c:清空目录栈
  • -p:每行一个条目打印目录栈,默认是打印在一行
  • -l:用户主目录不显示波浪号前缀,而是打印完整的目录
  • -v:每行一个条目,每个条目之前显示位置编号(从0开始)
  • +N:表示显示堆顶算起的第 N 个目录(从0开始)
  • -N:表示显示堆底算起的第 N 个目录(从0开始)
dirs
dirs -v
dirs -p -l

Bash 命令操作历史

基本用法

  • Bash 会保留用户的操作历史,用户输入的每一条命令都会被记录。可以使用方向键 ↑/↓ 快速浏览上/下一条命令。
  • Bash 会将用户在当前 Shell 的操作历史写入 ~/.bash_history 文件,该文件默认最多储存最近的 500 个操作。
  • 通过快捷键 Ctrl + R 可以搜索操作历史
    • 键入命令的开头部分,Shell 就会自动在历史文件中查询并显示 最近 一条匹配的结果
    • 有匹配结果后,按下回车键就会执行那条命令,按下 Esc 或 Tab 键会将匹配结果保留在输入光标处
echo $HISTFILE # 【/home/bqt/.bash_history】
history        # 以【特定格式】输出这个文件的全部内容,每条命令之前都有行号,越近的命令,排在越后面

!string 语法

!string 语法可以快速执行以前执行过的命令。

echo Hello
echo World
!e           # 【echo World】找出操作历史之中,最近的那一条以 e 开头的命令,并立即执行
!echo H      # 【echo World H】只匹配命令,不会匹配参数

shopt -s histverify  # 打开确认选项,打开后使用【!】快捷键产生的命令,会先打印出来,等用户按回车键后再执行

由于 !string 语法会扩展成以前执行过的命令,所以含有 ! 的字符串放在双引号里面必须非常小心,如果它后面有 非空格的字符,就很有可能报错。

echo "!ee"   # 【bash: !ee: event not found】Bash 会尝试寻找以前执行过的、以 ee 开头的命令,找不到就会报错
echo Hello
echo "!ec"   # 【echo "echo Hello"】找到了【echo Hello】
echo "\!ec"  # 【\!ec】解决方法就是在感叹号前面,加上反斜杠转义

history 命令

export HISTTIMEFORMAT='%F %T ' # 设置显示每个操作的时间格式
export HISTSIZE=10000          # 设置保存历史操作的数量,数量设为 0 表示不保存本次操作的历史
export HISTIGNORE='ls:exit'    # 设置哪些命令不写入操作历史

history              # 【306  2022-01-08 16:38:29 history】
history | grep echo  # 配合 grep 命令搜索操作历史
!285                 # 用【感叹号 + 编号】执行记录中指定编号的命令
history -c           # 清除操作历史
  • 时间格式中的 %F 相当于 %Y - %m - %d%T 相当于 %H : %M : %S
  • HISTSIZE=0 写入 ~/.bashrc 中,那么就不会保留该用户的操作历史
  • HISTSIZE=0 写入 /etc/profile 中,那么整个系统都不会保留操作历史

相关快捷键

  • Ctrl + P/N:显示上/下一个命令,同方向键 ↑/↓
  • 第一/最后一个命令
    • Alt + <:显示第一个命令
    • Alt + >:显示最后一个命令,即当前未执行的命令(也可能是空行)
    • 因为需要在按下 Shift 键的同时才能输入这两个符号,所以实际上的快捷键是 Alt + Shift + </>
  • Ctrl + O:等同于【先回车,再 ↑】,重复执行某个序列的命令时很有用

感叹号快捷键

  • !!:执行上一个命令
  • !n:执行历史文件里面行号为 n 的命令
  • !-n:执行当前命令之前 n 条的命令
  • !string:执行最近一个以指定字符串 string 开头的命令
  • !?string:执行最近一条包含字符串 string 的命令
  • !$:代表上一个命令的最后一个参数
  • !*:代表上一个命令的所有参数,即除了命令以外的所有部分
  • ^s1^s2:执行最近一条包含 s1 的命令,将其替换成 s2
echo a b c
echo !$     # 【echo c】上一个命令的最后一个参数

echo a b c
echo !*     # 【echo a b c】上一个命令的所有参数

echo aaaa
^aa^bb      # 【echo bbaa】将最近一条含有 aa 的命令里面的 aa 替换成 bb

Bash 命令提示符

  • 环境变量 PS1 是用户进入 Bash 以后,显示的命令提示符,用来提示用户在该位置后面输入命令
  • 环境变量 PS2 默认为 > ,是命令行折行输入时,在行首出现的提示符
  • 环境变量 PS3 是使用 select 命令时,系统输入菜单的提示符
  • 环境变量 PS4 默认为+ ,是使用 -x 参数执行脚本时,在行首出现的提示符

命令提示符

  • 命令提示符是由环境变量 PS1 决定的,通常是美元符号(普通用户) $ 或井号(根用户) #
  • 可以在命令行中临时更改环境变量 PS1 的值,也可以在配置文件 .bashrc 里面永久修改
  • 命令提示符的定义中,可以包含特殊的转义字符,表示特定内容
  • 命令提示符默认是显示终端预定义的颜色,也可以自定义提示符颜色
echo $PS1           # 查看当前命令提示符的定义
PS1="\A \h \$ "     # 【13:32 BQT-X $】后面最好跟一个空格,以用来将用户的输入与提示符隔开
PS1="\u@\h \W \$ "  # 【白乾涛@BQT-X 当前目录名 $】定义时使用单引号双引号都可以

PS1="\033[0;31m[\u@\h]\$ "      # 【[白乾涛@BQT-X]$】将提示符设为红色
PS1='\[\033[0;31m\][\u@\h]\$ '  # 通常将颜色代码放在中括号内。注意,提示符后面的文本都会变成红色
PS1='\[\033[0;31m\][\u@\h]\$\[\033[00m\] ' # 添加【\[\033[00m\]】可将后面的文本恢复到默认颜色
PS1='\[\033[0;41m\][\u@\h]\$\[\033[00m\] ' # 带有红色背景的提示符

2021-12-19

posted @ 2021-12-19 19:18  白乾涛  阅读(293)  评论(0编辑  收藏  举报