第五讲 命令行环境

课程视频地址:https://www.bilibili.com/video/BV1Dy4y1a7BW

课程讲义地址:https://missing-semester-cn.github.io/2020/command-line/

本机学习使用平台:wsl1 + ubuntu20.04

任务控制

我们来看如何结束进程、暂停进程和切换进程。

you can see the difference-between-job-task-and-process here.

最简单的方法——快捷键

  • <ctrl + c>:发送SIGINT信号,中断进程;
  • <ctrl + z>:发送SIGTSTP信号,暂停进程;
  • <ctrl + \>:发送SIGQUIT信号,退出进程;(和SIGINT差不多)

优雅的方法——kill命令

SIGKILL 是一个特殊的信号,它不能被进程捕获并且它会马上结束该进程。不过这样做会有一些副作用,例如留下孤儿进程。

SIGTERM 则是一个更加通用的、也更加优雅地退出信号。

为了发出这个信号我们需要使用 kill 命令, 它的语法是: kill -TERM <PID>或 %{{job ID}}

关于kill的信号选择我们可以通过kill -l来查看。

PID的获取

  • jobs -l来查看job的详细信息(包括PID)

  • pgrep <name>来直接获取进程的PID。

后台进程

  • jobs指令查看进程。jobs 命令会列出当前终端会话中尚未完成的全部任务,可以使用百分号 + 任务编号(jobs 会打印任务编号)来选取该任务。如果要选择最近的一个任务,可以使用 $! 这一特殊参数。

  • 命令中的 & 后缀可以让命令在直接在后台运行,不过它此时还是会使用 shell 的标准输出,这种情况可以使用 shell 重定向处理。

  • 使用 fgbg 命令恢复暂停的工作。它们分别表示在前台继续或在后台继续。

    • fg指令使最近转进后台的 job 转回前台,用fg %{{job ID}}来将特定的 job 转回前台执行。
    • bg指令使最近暂停的 job 转回后台,用bg %{{job ID}}来将特定的 job 转回后台执行。
  • 让已经在运行的进程转到后台运行,您可以键入Ctrl-Z ,然后紧接着再输入bg

注意,后台的进程仍然是您的终端进程的子进程,一旦您关闭终端(会发送另外一个信号SIGHUP),这些后台的进程也会终止。为了防止这种情况发生,您可以使用 nohup (一个用来忽略 SIGHUP 的封装) 来运行程序。针对已经运行的程序,可以使用disown

演示例子

$ sleep 1000
# output: ^Z
# output: [1] + 18653 suspended sleep 1000
$ nohup sleep 2000 &
# output: [2] 18745
appending output to nohup.out
$ jobs
# output: [1] + suspended sleep 1000
# output: [2] - running nohup sleep 2000
$ bg %1
# output: [1] - 18653 continued sleep 1000
$ jobs
# output: [1] - running sleep 1000
# output: [2] + running nohup sleep 2000
$ kill -STOP %1
# output: [1] + 18653 suspended (signal) sleep 1000
$ jobs
# output: [1] + suspended (signal) sleep 1000
# output: [2] - running nohup sleep 2000
$ kill -SIGHUP %1
# output: [1] + 18653 hangup sleep 1000
$ jobs
# output: [2] + running nohup sleep 2000
$ kill -SIGHUP %2
$ jobs
# output: [2] + running nohup sleep 2000
$ kill %2
# output: [2] + 18745 terminated nohup sleep 2000
$ jobs

终端多路复用 TMUX

会话 Session

每个会话都是一个独立的工作区,其中包含一个或多个窗口。

  • tmux 开始一个新的会话;
  • tmux new -s NAME 以指定名称开始一个新的会话;
  • tmux ls 列出当前所有会话;
    • tmux 中输入 <C-b> d ,将当前会话分离;
  • tmux a 重新连接最后一个会话。您也可以通过 -t 来指定具体的会话;
  • tmux kill-session -t <name>关闭指定会话 ;

窗口 Window

相当于编辑器或是浏览器中的标签页,从视觉上将一个会话分割为多个部分。

  • <C-b> c 创建一个新的窗口,使用 <C-d>关闭;
  • <C-b> N 跳转到第 N 个窗口,注意每个窗口都是有编号的;
  • <C-b> p 切换到前一个窗口;
  • <C-b> n 切换到下一个窗口;
  • <C-b> , 重命名当前窗口;
  • <C-b> w 列出当前所有窗口;

面板 Pane

像 vim 中的分屏一样,面板使我们可以在一个屏幕里显示多个 shell。

  • <C-b> " 水平分割;
  • <C-b> % 垂直分割;
  • <C-b> <方向> 切换到指定方向的面板,<方向> 指的是键盘上的方向键;
    • 可以在tmux里面的命令模式(按<C-b> : 打开),输入set -g mouse on,就可以启用鼠标点击和滚轮了;
  • <C-b> z 切换当前面板的缩放;
  • <C-b> <空格> 在不同的面板排布间切换;
  • <C-b> [ 开始往回卷动屏幕。您可以按下空格键来开始选择,回车键复制选中的部分(按q退出);
  • <C-b> x 关闭当前的面板/窗口;

别名 Alias

shell 的别名相当于一个长命令的缩写,shell 会自动将其替换成原本的命令。例如,bash 中的别名语法如下:

alias alias_name="command_to_alias arg1 arg2"

注意, =两边是没有空格的,因为 alias 是一个 shell 命令,它只接受一个参数。

演示例子:

# 创建常用命令的缩写
alias ll="ls -lh" # 能够少输入很多
alias gs="git status"
alias gc="git commit"
alias v="vim" # 手误打错命令也没关系
alias sl=ls # 重新定义一些命令行的默认行为
alias mv="mv -i" # -i prompts before overwrite
alias mkdir="mkdir -p" # -p make parent dirs as needed
alias df="df -h" # -h prints human readable format # 别名可以组合使用
alias la="ls -A"
alias lla="la -l" # 在忽略某个别名
\ls
# 或者禁用别名
unalias la # 获取别名的定义
alias ll
# 会打印 ll='ls -lh'

在默认情况下 shell 并不会保存别名。为了让别名持续生效,您需要将配置放进 shell 的启动文件里,像是.bashrc.zshrc

配置文件(Dotfiles)

很多程序的配置都是通过纯文本格式的被称作点文件的配置文件来完成的(之所以称为点文件,是因为它们的文件名以 . 开头,例如 ~/.vimrc。也正因为此,它们默认是隐藏文件,ls并不会显示它们)。

shell 的配置也是通过这类文件完成的。在启动时,您的 shell 程序会读取很多文件以加载其配置项。根据 shell 本身的不同,您从登录开始还是以交互的方式完成这一过程可能会有很大的不同。关于这一话题,这里 有非常好的资源。

对于 bash来说,在大多数系统下,您可以通过编辑 .bashrc.bash_profile 来进行配置。在文件中您可以添加需要在启动时执行的命令,例如上文我们讲到过的别名,或者是您的环境变量。

一些其他的工具也可以通过点文件进行配置:

  • bash - ~/.bashrc, ~/.bash_profile
  • git - ~/.gitconfig
  • vim - ~/.vimrc~/.vim 目录
  • ssh - ~/.ssh/config
  • tmux - ~/.tmux.conf

配置文件中需要放些什么?您可以通过在线文档和帮助手册了解所使用工具的设置项。另一个方法是在网上搜索有关特定程序的文章,作者们在文章中会分享他们的配置。还有一种方法就是直接浏览其他人的配置文件:您可以在这里找到无数的dotfiles 仓库 —— 其中最受欢迎的那些可以在这里找到(我们建议您不要直接复制别人的配置)。这里 也有一些非常有用的资源。

本课程的老师们也在 GitHub 上开源了他们的配置文件: Anish, Jon, Jose.

配置文件的一个常见的痛点是它可能并不能在多种设备上生效。例如,如果您在不同设备上使用的操作系统或者 shell 是不同的,则配置文件是无法生效的。或者,有时您仅希望特定的配置只在某些设备上生效。

有一些技巧可以轻松达成这些目的。如果配置文件 if 语句,则您可以借助它针对不同的设备编写不同的配置。例如,您的 shell 可以这样做:

if [[ "$(uname)" == "Linux" ]]; then {do_something}; fi

# 使用和 shell 相关的配置时先检查当前 shell 类型
if [[ "$SHELL" == "zsh" ]]; then {do_something}; fi # 您也可以针对特定的设备进行配置
if [[ "$(hostname)" == "myServer" ]]; then {do_something}; fi

如果配置文件支持 include 功能,您也可以多加利用。例如:~/.gitconfig 可以这样编写:

[include]
path = ~/.gitconfig_local

然后我们可以在日常使用的设备上创建配置文件 ~/.gitconfig_local 来包含与该设备相关的特定配置。您甚至应该创建一个单独的代码仓库来管理这些与设备相关的配置。(相当于对文件进行映射,你不必要对本地的点文件做太多的写入。)

如果您希望在不同的程序之间共享某些配置,该方法也适用。例如,如果您想要在 bashzsh 中同时启用一些别名,您可以把它们写在 .aliases 里,然后在这两个 shell 里应用:

# Test if ~/.aliases exists and source it
if [ -f ~/.aliases ]; then
source ~/.aliases
fi

一些遇到的麻烦

为什么在WSL ubuntu的环境下,执行笨笨py代码过程中按ctrl+\没有发出SIGQUIT信号?


实际上为:WSL其实收到了SIGQUIT的信号,但没有实现对这个信号的处理,并不是信号没有发出。

可以看这些链接帮助理解:https://github.com/microsoft/WSL/issues/169,https://www.zhihu.com/question/338541555

课后习题

任务控制

  1. 我们可以使用类似 ps aux | grep 这样的命令来获取任务的 pid ,然后您可以基于pid 来结束这些进程。但我们其实有更好的方法来做这件事。在终端中执行 sleep 10000 这个任务。然后用 Ctrl-Z 将其切换到后台并使用 bg来继续允许它。现在,使用 pgrep 来查找 pid 并使用 pkill 结束进程而不需要手动输入pid。(提示:: 使用 -af 标记)。

    -a, --list-full	#List the full command line as well as the process ID.  (pgrep only.)
    -f, --full #The pattern is normally only matched against the process name. When -f is set, the full command line is used.
    # 可以用pkill直接全沙掉
    gfcat030@DESKTOP-KUSC3EH:~$ jobs [1] Running sleep 200 & [2]- Running sleep 2000 & [3]+ Running sleep 3000 & gfcat030@DESKTOP-KUSC3EH:~$ pkill sleep [1] Terminated sleep 200 [2]- Terminated sleep 2000 [3]+ Terminated sleep 3000
    # 这样操作
    gfcat030@DESKTOP-KUSC3EH:~$ sleep 10000
    # press Ctril-Z
    # output: [1] + 29705 suspended sleep 10000
    gfcat030@DESKTOP-KUSC3EH:~$ bg %1
    # output: [1] + 29705 continued sleep 10000
    gfcat030@DESKTOP-KUSC3EH:~$ pgrep -af "sleep"
    # output: 29705
    gfcat030@DESKTOP-KUSC3EH:~$ pkill -af "sleep"
    # output: [1] + 29705 terminated sleep 10000
  2. 如果您希望某个进程结束后再开始另外一个进程, 应该如何实现呢?在这个练习中,我们使用 sleep 60 & 作为先执行的程序。一种方法是使用 wait 命令。尝试启动这个休眠命令,然后待其结束后再执行 ls 命令。

    但是,如果我们在不同的 bash 会话中进行操作,则上述方法就不起作用了。因为 wait 只能对子进程起作用。之前我们没有提过的一个特性是,kill 命令成功退出时其状态码为 0 ,其他状态则是非0。kill -0 则不会发送信号,但是会在进程不存在时返回一个不为0的状态码。请编写一个 bash 函数 pidwait ,它接受一个 pid 作为输入参数,然后一直等待直到该进程结束。您需要使用 sleep 来避免浪费 CPU 性能。

    # 用wait可以这样做
    gfcat030@DESKTOP-KUSC3EH:~/missingsem$ sleep 60 &
    gfcat030@DESKTOP-KUSC3EH:~/missingsem$ pgrep "sleep" | wait && ls
    #用脚本就这样
    gfcat030@DESKTOP-KUSC3EH:~/missingsem$ cat pidw.sh
    #!usr/bin/env bash
    dwait() {
    while kill -0 $1 2>/dev/null # catch stderr to /dev/null
    do
    sleep 1
    done
    ls
    }
    gfcat030@DESKTOP-KUSC3EH:~/missingsem$ source pidwait.sh
    gfcat030@DESKTOP-KUSC3EH:~/missingsem$ sleep 60 &
    gfcat030@DESKTOP-KUSC3EH:~/missingsem$ pidwait $(pgrep "sleep")

终端多路复用

请完成这个 tmux 教程 参考这些步骤来学习如何自定义 tmux

别名

  1. 创建一个 dc 别名,它的功能是当我们错误的将 cd 输入为 dc 时也能正确执行。

    gfcat030@DESKTOP-KUSC3EH:~$ alias dc=cd
  2. 执行 history | awk '{$1="";print substr($0,2)}' | sort | uniq -c | sort -n | tail -n 10 来获取您最常用的十条命令,尝试为它们创建别名。注意:这个命令只在 Bash 中生效,如果您使用 ZSH,使用history 1 替换 history

配置文件

让我们帮助您进一步学习配置文件:

  1. 为您的配置文件新建一个文件夹,并设置好版本控制
  2. 在其中添加至少一个配置文件,比如说您的 shell,在其中包含一些自定义设置(可以从设置 $PS1 开始)。
  3. 建立一种在新设备进行快速安装配置的方法(无需手动操作)。最简单的方法是写一个 shell 脚本对每个文件使用 ln -s,也可以使用专用工具
  4. 在新的虚拟机上测试该安装脚本。
  5. 将您现有的所有配置文件移动到项目仓库里。
  6. 将项目发布到GitHub。

The Missing Semester - 第五讲 学习笔记的更多相关文章

  1. The Missing Semester - 第一讲 学习笔记

    The Missing Semester - 第一讲 学习笔记 第一讲 课程概览与 shell 课程视频地址: https://www.bilibili.com/video/BV1Eo4y1d7KZ/ ...

  2. The Missing Semester - 第三讲 学习笔记

    第三讲 Vim 课程视频地址:https://www.bilibili.com/video/BV1Dy4y1a7BW 课程讲义地址:https://missing-semester-cn.github ...

  3. The Missing Semester - 第二讲 学习笔记

    第二讲 Shell 工具和脚本 课程视频地址: https://www.bilibili.com/video/BV1Vv411v7FR 本机学习使用平台:虚拟机ubuntu18.04.6 主题一:Sh ...

  4. Android M Permission 运行时权限 学习笔记

    Android M Permission 运行时权限 学习笔记 从Android 6.0开始, 用户需要在运行时请求权限, 本文对运行时权限的申请和处理进行介绍, 并讨论了使用运行时权限时新老版本的一 ...

  5. 【工作笔记】BAT批处理学习笔记与示例

    BAT批处理学习笔记 一.批注里定义:批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD,这些命令统称批处理命令. 二.常见的批处理指令: 命令清单: 1.RE ...

  6. python学习笔记整理——字典

    python学习笔记整理 数据结构--字典 无序的 {键:值} 对集合 用于查询的方法 len(d) Return the number of items in the dictionary d. 返 ...

  7. gulp学习笔记3

    gulp系列学习笔记: 1.gulp学习笔记1 2.gulp学习笔记2 3.gulp学习笔记3 4.gulp学习笔记4 1.编译sass Sass 是一种 CSS 的开发工具,提供了许多便利的写法,大 ...

  8. VSTO学习笔记(一)VSTO概述

    原文:VSTO学习笔记(一)VSTO概述 接触VSTO纯属偶然,前段时间因为忙于一个项目,在客户端Excel中制作一个插件,从远程服务器端(SharePoint Excel Services)上下载E ...

  9. 《SAS编程和数据挖掘商业案例》学习笔记# 19

    继续<SAS编程与数据挖掘商业案例>学习笔记,本文側重数据处理实践.包含:HASH对象.自己定义format.以及功能强大的正則表達式 一:HASH对象 Hash对象又称散列表,是依据关键 ...

  10. Python Click 学习笔记(转)

    原文链接:Python Click 学习笔记 Click 是 Flask 的团队 pallets 开发的优秀开源项目,它为命令行工具的开发封装了大量方法,使开发者只需要专注于功能实现.恰好我最近在开发 ...

随机推荐

  1. GoLang 指针初探

    1. 内置类型和引用类型 Go 中内置类型包括数值类型,字符串类型和布尔类型.引用类型包括切片,映射,通道,接口和函数类型.其中,引用类型表示创建的变量包含一个指向底层数据结构的指针和一组管理底层数据 ...

  2. 使用Docker部署java项目时遇到的几个错误

    0.简介 本文主要是在学习黑马程序员Docker快速入门到项目部署过程中, 对遇到的问题进行了相关的总结梳理 1.本地已存在mysql服务占用3306端口 问题 当我使用docker run -d - ...

  3. CS2打开可以听到声音,但黑屏问题?

    1.问题 我这里原先是可以启动CS2的,但是后来在CS2中重新调整了分辨率等等,之后由于某种原因又调整了屏幕分辨率,导致后面一进入CS2登录界面,橙色登陆界面就会缩在左上角一小块,并且之后就会陷入黑屏 ...

  4. 2023-SWPU NSS秋季招新赛(校外赛道)Misc—我要成为原神高手WP

    1.题目信息 我是神里绫华的狗!!! 2.解题方法 有个genshin.h文件夹,打开看看发现里面是一堆文件夹0 1A 1A0等等,而且每个文件夹里面都有文件,0 1A 1A0...看着很眼熟,我们用 ...

  5. [转帖]Kubernetes-18:Dashboard安装及使用

    https://www.cnblogs.com/v-fan/p/13950268.html Helm安装Dashboard 简介 Dashboard 是 kubernetes 的图形化管理工具,可直观 ...

  6. [转帖]3.3.7. 自动诊断和建议报告SYS_KDDM

    https://help.kingbase.com.cn/v8/perfor/performance-optimization/performance-optimization-6.html#sys- ...

  7. 【转帖】JVM 内存模型与垃圾回收

    文章目录 1. JVM内存模型 1.1. 程序计数器 (线程私有) 1.2. Java 虚拟机栈 (线程私有) 1.3. 本地方法栈 (线程私有) 1.4. Java 堆 (线程共享) 1.5. 方法 ...

  8. [转帖]​Linux开源存储漫谈(2)IO性能测试利器fio

    fio(Flexible I/O Tester)正是非常常用的文件系统和磁盘 I/O 性能基准测试工具.提供了大量的可定制化选项,可以用来测试,裸盘.一个单独的分区或者文件系统在各种场景下的 I/O ...

  9. 【转帖】一文解析ethtool 命令的使用

    命令简介 ethtool命令用于查询和控制网络设备驱动程序和硬件设置,尤其是有线以太网设备,devname网卡的名称.网卡就像是交换机的一个端口,正常使用我们只是配置网卡IP地址等信息,网卡的速率.双 ...

  10. Linux下面sysstat的安装与简介

    https://blog.51cto.com/smoke520/2160073   在Linux系统下获取sysstat-10.0.5.tar.gz的两种方式: 方式一: 下载sysstat-10.0 ...