文章目录

  • 常用文件管理命令
    • 常用命令介绍
    • 创建作业 & 测试作业的正确性
    • 作业
  • tmux和vim
    • tmux教程
    • vim教程
    • 创建作业 & 测试作业的正确性
    • 作业
  • shell
    • shell语法
      • 概论
      • 注释
      • 变量
      • 默认变量
      • 数组
      • expr命令
      • read命令
      • echo命令
      • printf命令
      • test命令与判断符号[]
      • 判断语句
      • 循环语句
      • 函数
      • exit命令
      • 文件重定向
      • 引入外部脚本
    • 创建作业 & 测试作业的正确性
    • 作业
  • ssh
    • ssh教程
      • ssh登录
      • scp传文件
    • 获取ssh教程配套的远程服务器账号的信息
    • 创建作业 & 测试作业的正确性
    • 作业
  • git
    • git教程
      • git基本概念
      • git常用命令
    • 创建作业 & 测试作业的正确性
    • 作业
  • thrift
    • thrift教程
    • 创建作业 & 测试作业的正确性
    • 作业
  • 管道、环境变量与常用命令
    • 知识点
      • 管道
      • 环境变量
      • 常用命令
    • 创建作业 & 测试作业的正确性
    • 作业
  • 租云服务器及配docker环境
    • 知识点
      • 概述
      • 租云服务器及安装docker之阿里云
      • 租云服务器及安装docker之腾讯云
      • 租云服务器及安装docker之华为云
      • docker教程
    • 创建作业 & 测试作业的正确性
    • 作业

文档来自AcWing Linux基础课

常用文件管理命令

常用命令介绍

(1) ctrl c: 取消命令,并且换行
(2) ctrl u: 清空本行命令
(3) tab键:可以补全命令和文件名,如果补全不了快速按两下tab键,可以显示备选选项
(4) ls: 列出当前目录下所有文件,蓝色的是文件夹,白色的是普通文件,绿色的是可执行文件
(5) pwd: 显示当前路径
(6) cd XXX: 进入XXX目录下, cd .. 返回上层目录
(7) cp XXX YYY: 将XXX文件复制成YYY,XXX和YYY可以是一个路径,比如../dir_c/a.txt,表示上层目录下的dir_c文件夹下的文件a.txt
(8) mkdir XXX: 创建目录XXX
(9) rm XXX: 删除普通文件;  rm XXX -r: 删除文件夹
(10) mv XXX YYY: 将XXX文件移动到YYY,和cp命令一样,XXX和YYY可以是一个路径;重命名也是用这个命令
(11) touch XXX: 创建一个文件
(12) cat XXX: 展示文件XXX中的内容
(13) 复制文本windows/Linux下:Ctrl + insert,Mac下:command + c
(14) 粘贴文本windows/Linux下:Shift + insert,Mac下:command + v

创建作业 & 测试作业的正确性

homework 1 create 可以重新创建所有lesson_1的作业
homework 1 create id 可以单独创建lesson_1的第id个作业. e.g.homework 1 create 0 可以只重新创建lesson_1的第0个作业
homework 1 test 可以评测lesson_1的所有作业

作业

创建好作业后,先进入文件夹/home/acs/homework/lesson_1/,然后:
(0) 进入homework_0文件夹,分别创建文件夹dir_a, dir_b, dir_c
(1) 进入homework_1文件夹,将a.txt, b.txt, c.txt 分别复制成: a.txt.bak, b.txt.bak, c.txt.bak
(2) 进入homework_2文件夹,将a.txt, b.txt, c.txt 分别重命名为: a_new.txt, b_new.txt, c_new.txt
(3) 进入homework_3文件夹,将dir_a文件夹下的a.txt, b.txt, c.txt分别移动到文件夹dir_b下
(4) 进入homework_4文件夹,将普通文件a.txt, b.txt, c.txt删除
(5) 进入homework_5文件夹,将文件夹dir_a, dir_b, dir_c删除
(6) 进入homework_6文件夹,查看task.txt的内容,并按其指示进行操作
(7) 进入homework_7文件夹,创建文件夹dir_0, dir_1, dir_2,将a.txt, b.txt, c.txt复制到dir_0下,重命名为a0.txt, b0.txt, c0.txt;将a.txt, b.txt, c.txt复制到dir_1下,重命名为a1.txt, b1.txt, c1.txt;将a.txt, b.txt, c.txt复制到dir_2下,重命名为a2.txt, b2.txt, c2.txt;
(8) 进入homework_8文件夹,分别在dir_a, dir_b, dir_c文件夹下查看task.txt的内容,并分别按照指示进行操作
(9) 进入homework_9文件夹,将其中所有txt类型的文件删除

tmux和vim

tmux教程

功能:(1) 分屏。(2) 允许断开Terminal连接后,继续运行进程。
结构:一个tmux可以包含多个session,一个session可以包含多个window,一个window可以包含多个pane。实例:tmux:session 0:window 0:pane 0pane 1pane 2...window 1window 2...session 1session 2...
操作:(1) tmux:新建一个session,其中包含一个window,window中包含一个pane,pane里打开了一个shell对话框。(2) 按下Ctrl + a后手指松开,然后按%:将当前pane左右平分成两个pane。(3) 按下Ctrl + a后手指松开,然后按"(注意是双引号"):将当前pane上下平分成两个pane。(4) Ctrl + d:关闭当前pane;如果当前window的所有pane均已关闭,则自动关闭window;如果当前session的所有window均已关闭,则自动关闭session。(5) 鼠标点击可以选pane。(6) 按下ctrl + a后手指松开,然后按方向键:选择相邻的pane。(7) 鼠标拖动pane之间的分割线,可以调整分割线的位置。(8) 按住ctrl + a的同时按方向键,可以调整pane之间分割线的位置。(9) 按下ctrl + a后手指松开,然后按z:将当前pane全屏/取消全屏。(10) 按下ctrl + a后手指松开,然后按d:挂起当前session。(11) tmux a:打开之前挂起的session。(12) 按下ctrl + a后手指松开,然后按s:选择其它session。方向键 —— 上:选择上一项 session/window/pane方向键 —— 下:选择下一项 session/window/pane方向键 —— 右:展开当前项 session/window方向键 —— 左:闭合当前项 session/window(13) 按下Ctrl + a后手指松开,然后按c:在当前session中创建一个新的window。(14) 按下Ctrl + a后手指松开,然后按w:选择其他window,操作方法与(12)完全相同。(15) 按下Ctrl + a后手指松开,然后按PageUp:翻阅当前pane内的内容。(16) 鼠标滚轮:翻阅当前pane内的内容。(17) 在tmux中选中文本时,需要按住shift键。(仅支持Windows和Linux,不支持Mac,不过该操作并不是必须的,因此影响不大)(18) tmux中复制/粘贴文本的通用方式:(1) 按下Ctrl + a后松开手指,然后按[(2) 用鼠标选中文本,被选中的文本会被自动复制到tmux的剪贴板(3) 按下Ctrl + a后松开手指,然后按],会将剪贴板中的内容粘贴到光标处

vim教程

功能:(1) 命令行模式下的文本编辑器。(2) 根据文件扩展名自动判别编程语言。支持代码缩进、代码高亮等功能。(3) 使用方式:vim filename如果已有该文件,则打开它。如果没有该文件,则打开个一个新的文件,并命名为filename
模式:(1) 一般命令模式默认模式。命令输入方式:类似于打游戏放技能,按不同字符,即可进行不同操作。可以复制、粘贴、删除文本等。(2) 编辑模式在一般命令模式里按下i,会进入编辑模式。按下ESC会退出编辑模式,返回到一般命令模式。(3) 命令行模式在一般命令模式里按下:/?三个字母中的任意一个,会进入命令行模式。命令行在最下面。可以查找、替换、保存、退出、配置编辑器等。
操作:(1) i:进入编辑模式(2) ESC:进入一般命令模式(3) h 或 左箭头键:光标向左移动一个字符(4) j 或 向下箭头:光标向下移动一个字符(5) k 或 向上箭头:光标向上移动一个字符(6) l 或 向右箭头:光标向右移动一个字符(7) n<Space>:n表示数字,按下数字后再按空格,光标会向右移动这一行的n个字符(8) 0 或 功能键[Home]:光标移动到本行开头(9) $ 或 功能键[End]:光标移动到本行末尾(10) G:光标移动到最后一行(11) :n 或 nG:n为数字,光标移动到第n行(12) gg:光标移动到第一行,相当于1G(13) n<Enter>:n为数字,光标向下移动n行(14) /word:向光标之下寻找第一个值为word的字符串。(15) ?word:向光标之上寻找第一个值为word的字符串。(16) n:重复前一个查找操作(17) N:反向重复前一个查找操作(18) :n1,n2s/word1/word2/g:n1与n2为数字,在第n1行与n2行之间寻找word1这个字符串,并将该字符串替换为word2(19) :1,$s/word1/word2/g:将全文的word1替换为word2(20) :1,$s/word1/word2/gc:将全文的word1替换为word2,且在替换前要求用户确认。(21) v:选中文本(22) d:删除选中的文本(23) dd: 删除当前行(24) y:复制选中的文本(25) yy: 复制当前行(26) p: 将复制的数据在光标的下一行/下一个位置粘贴(27) u:撤销(28) Ctrl + r:取消撤销(29) 大于号 >:将选中的文本整体向右缩进一次(30) 小于号 <:将选中的文本整体向左缩进一次(31) :w 保存(32) :w! 强制保存(33) :q 退出(34) :q! 强制退出(35) :wq 保存并退出(36) :set paste 设置成粘贴模式,取消代码自动缩进(37) :set nopaste 取消粘贴模式,开启代码自动缩进(38) :set nu 显示行号(39) :set nonu 隐藏行号(40) gg=G:将全文代码格式化(41) :noh 关闭查找关键词高亮(42) Ctrl + q:当vim卡死时,可以取消当前正在执行的命令
异常处理:每次用vim编辑文件时,会自动创建一个.filename.swp的临时文件。如果打开某个文件时,该文件的swp文件已存在,则会报错。此时解决办法有两种:(1) 找到正在打开该文件的程序,并退出(2) 直接删掉该swp文件即可

创建作业 & 测试作业的正确性

homework 2 create 可以重新创建所有lesson_2的作业。
homework 2 create id 可以单独创建lesson_2的第id个作业. e.g.homework 2 create 0 可以只重新创建lesson_2的第0个作业
homework 2 test 可以评测lesson_2的所有作业

作业

创建好作业后,先进入文件夹/home/acs/homework/lesson_2/,然后:
(0) 进入homework_0文件夹,创建文件names.txt,并顺次将下列姓名写入该文件,每个名字占一行。AcWing、yxc、Bob、张强、李明、Alice
(1) 进入homework_1文件夹,打开problem.txt,并依次删除下列字符:[1] 最后一行第101个字符[2] 第3行第8个字符[3] 第1行第30个字符[4] 第16行第55个字符[5] 第9行第80个字符最后保存文件并退出。
(2) 进入homework_2文件夹,打开problem.txt,并依次执行如下操作:[1] 在第1个"two"的后面添加"abc"[2] 在第2个"two"的前面添加"def"[3] 将第3个"two"后面的连续12个字符删掉[4] 将第4个"two"所在的行删掉最后保存文件并退出。
(3) 进入homework_3文件夹,打开problem.txt,并依次执行如下操作:[1] 将第5行至第15行中所有of替换成OF。[2] 将全文中所有的the替换成THE。[3] 将第偶数个is替换成IS,第奇数个is不变。下标从1开始。
(4) 进入homework_4文件夹,打开problem.txt,并依次执行如下操作:[1] 删除第11行[2] 将所删除的行粘贴到文件最后一行的下一行[3] 复制第5行[4] 将所复制的行粘贴到文件当前最后一行的下一行
(5) 进入homework_5文件夹,打开problem.txt,并依次执行如下操作:[1] 删除第11行第15个字符(包含该字符)至第13行第5个字符(包含该字符)[2] 将所删除的内容粘贴到文件末尾(注意不要另起一行)[3] 复制第5行第88个字符(包含该字符)至第7行第6个字符(包含该字符)[4] 将所复制的内容粘贴到当前文件末尾(注意不要另起一行)
(6) 进入homework_6文件夹,并依次执行如下操作:[1] 清空source0.cpp[2] 将source1.cpp中的第1-3行和第12-24行复制到source0.cpp中
(7) 进入homework_7文件夹,格式化source.cpp
(8) 进入homework_8文件夹,打开source.cpp,并依次执行如下操作:[1] 将第15-21行向右缩进2次。[2] 将第22-23行向左缩进1次。
(9) 进入homework_9文件夹,打开链接:https://www.acwing.com/activity/content/code/content/1694465/新建文件source.cpp,将链接中的代码抄进source.cpp文件中。

shell

shell语法

概论

概述

shell是我们通过命令行与操作系统沟通的语言。

shell脚本可以直接在命令行中执行,也可以将一套逻辑组织成一个文件,方便复用。
AC Terminal中的命令行可以看成是一个shell脚本在逐行执行

Linux中常见的shell脚本有很多种,常见的有:

  • Bourne Shell(/usr/bin/sh/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • zsh

Linux系统中一般默认使用bash,所以接下来讲解bash中的语法。文件开头需要写#! /bin/bash,指明bash为脚本解释器。

学习技巧
不要死记硬背,遇到含糊不清的地方,可以在AC Terminal里实际运行一遍。

脚本示例
新建一个test.sh文件,内容如下:

#! /bin/bash
echo "Hello World!"

运行方式
作为可执行文件

acs@9e0ebfcd82d7:~$ chmod +x test.sh  # 使脚本具有可执行权限
acs@9e0ebfcd82d7:~$ ./test.sh  # 当前路径下执行
Hello World!  # 脚本输出
acs@9e0ebfcd82d7:~$ /home/acs/test.sh  # 绝对路径下执行
Hello World!  # 脚本输出
acs@9e0ebfcd82d7:~$ ~/test.sh  # 家目录路径下执行
Hello World!  # 脚本输出

用解释器执行

acs@9e0ebfcd82d7:~$ bash test.sh
Hello World!  # 脚本输出

注释

单行注释
每行中#之后的内容均是注释。

# 这是一行注释echo 'Hello World'  #  这也是注释

多行注释
格式:

:<<EOF
第一行注释
第二行注释
第三行注释
EOF

其中EOF可以换成其它任意字符串。例如:

:<<abc
第一行注释
第二行注释
第三行注释
abc:<<!
第一行注释
第二行注释
第三行注释
!

变量

定义变量
定义变量,不需要加$符号,例如:

name1='yxc'  # 单引号定义字符串
name2="yxc"  # 双引号定义字符串
name3=yxc    # 也可以不加引号,同样表示字符串

使用变量
使用变量,需要加上$符号,或者${}符号。花括号是可选的,主要为了帮助解释器识别变量边界。

name=yxc
echo $name  # 输出yxc
echo ${name}  # 输出yxc
echo ${name}acwing  # 输出yxcacwing

只读变量
使用readonly或者declare可以将变量变为只读。

name=yxc
readonly name
declare -r name  # 两种写法均可name=abc  # 会报错,因为此时name只读

删除变量
unset可以删除变量。

name=yxc
unset name
echo $name  # 输出空行

变量类型

  • 1、自定义变量(局部变量)
    子进程不能访问的变量
  • 2、环境变量(全局变量)
    子进程可以访问的变量

自定义变量改成环境变量:

acs@9e0ebfcd82d7:~$ name=yxc  # 定义变量
acs@9e0ebfcd82d7:~$ export name  # 第一种方法
acs@9e0ebfcd82d7:~$ declare -x name  # 第二种方法

环境变量改为自定义变量:

acs@9e0ebfcd82d7:~$ export name=yxc  # 定义环境变量
acs@9e0ebfcd82d7:~$ declare +x name  # 改为自定义变量

字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。

单引号与双引号的区别:

  • 单引号中的内容会原样输出,不会执行、不会取变量;

  • 双引号中的内容可以执行、可以取变量;

name=yxc  # 不用引号
echo 'hello, $name \"hh\"'  # 单引号字符串,输出 hello, $name \"hh\"
echo "hello, $name \"hh\""  # 双引号字符串,输出 hello, yxc "hh"

获取字符串长度

name="yxc"
echo ${#name}  # 输出3

提取子串

name="hello, yxc"
echo ${name:0:5}  # 提取从0开始的5个字符

默认变量

文件参数变量
在执行shell脚本时,可以向脚本传递参数。$1是第一个参数,$2是第二个参数,以此类推。特殊的,$0是文件名(包含路径)。例如:

创建文件test.sh

#! /bin/bashecho "文件名:"$0
echo "第一个参数:"$1
echo "第二个参数:"$2
echo "第三个参数:"$3
echo "第四个参数:"$4

然后执行该脚本:

acs@9e0ebfcd82d7:~$ chmod +x test.sh
acs@9e0ebfcd82d7:~$ ./test.sh 1 2 3 4
文件名:./test.sh
第一个参数:1
第二个参数:2
第三个参数:3
第四个参数:4

其它参数相关变量

参数 说明
$# 代表文件传入的参数个数,如上例中值为4
$* 由所有参数构成的用空格隔开的字符串,如上例中值为$1 $2 $3 $4
$@ 每个参数分别用双引号括起来的字符串,如上例中值为"$1" "$2" "$3" "$4"
$$ 脚本当前运行的进程ID
$? 上一条命令的退出状态(注意不是stdout,而是exit code)。0表示正常退出,其他值表示错误
$(command) 返回command这条命令的stdout(可嵌套)
`command| 返回command这条命令的stdout`(不可嵌套)

数组

数组中可以存放多个不同类型的值,只支持一维数组,初始化时不需要指明数组大小。数组下标从0开始

定义
数组用小括号表示,元素之间用空格隔开。例如:

array=(1 abc "def" yxc)

也可以直接定义数组中某个元素的值:

array[0]=1
array[1]=abc
array[2]="def"
array[3]=yxc

读取数组中某个元素的值
格式:

${array[index]}

例如:

array=(1 abc "def" yxc)
echo ${array[0]}
echo ${array[1]}
echo ${array[2]}
echo ${array[3]}

读取整个数组
格式:

${array[@]}  # 第一种写法
${array[*]}  # 第二种写法

例如:

array=(1 abc "def" yxc)echo ${array[@]}  # 第一种写法
echo ${array[*]}  # 第二种写法

数组长度
类似于字符串

${#array[@]}  # 第一种写法
${#array[*]}  # 第二种写法

例如:

array=(1 abc "def" yxc)echo ${#array[@]}  # 第一种写法
echo ${#array[*]}  # 第二种写法

expr命令

expr命令用于求表达式的值,格式为:

expr 表达式

表达式说明:

  • 用空格隔开每一项

  • 用反斜杠放在shell特定的字符前面(发现表达式运行错误时,可以试试转义)

  • 对包含空格和其他特殊字符的字符串要用引号括起来

  • expr会在stdout中输出结果。如果为逻辑关系表达式,则结果为真,stdout为1,否则为0。

  • expr的exit code:如果为逻辑关系表达式,则结果为真,exit code为0,否则为1。

字符串表达式

  • length STRING
    返回STRING的长度

  • index STRING CHARSET
    CHARSET中任意单个字符在STRING中最前面的字符位置,下标从1开始。如果在STRING中完全不存在CHARSET中的字符,则返回0。

  • substr STRING POSITION LENGTH
    返回STRING字符串中从POSITION开始,长度最大为LENGTH的子串。如果POSITIONLENGTH为负数,0或非数值,则返回空字符串。

示例:

str="Hello World!"echo `expr length "$str"`  # ``不是单引号,表示执行该命令,输出12
echo `expr index "$str" aWd`  # 输出7,下标从1开始
echo `expr substr "$str" 2 3`  # 输出 ell

整数表达式
expr支持普通的算术操作,算术表达式优先级低于字符串表达式,高于逻辑关系表达式。

  • + -
    加减运算。两端参数会转换为整数,如果转换失败则报错。

  • / %
    乘,除,取模运算。两端参数会转换为整数,如果转换失败则报错。

  • () 可以该表优先级,但需要用反斜杠转义

示例:

a=3
b=4echo `expr $a + $b`  # 输出7
echo `expr $a - $b`  # 输出-1
echo `expr $a \* $b`  # 输出12,*需要转义
echo `expr $a / $b`  # 输出0,整除
echo `expr $a % $b` # 输出3
echo `expr \( $a + 1 \) \* \( $b + 1 \)`  # 输出20,值为(a + 1) * (b + 1)

逻辑关系表达式

  • |
    如果第一个参数非空且非0,则返回第一个参数的值,否则返回第二个参数的值,但要求第二个参数的值也是非空或非0,否则返回0。如果第一个参数是非空或非0时,不会计算第二个参数。
  • &
    如果两个参数都非空且非0,则返回第一个参数,否则返回0。如果第一个参为0或为空,则不会计算第二个参数。
  • < <= = == != >= >
    比较两端的参数,如果为true,则返回1,否则返回0。”==”是”=”的同义词。”expr”首先尝试将两端参数转换为整数,并做算术比较,如果转换失败,则按字符集排序规则做字符比较。
  • () 可以该表优先级,但需要用反斜杠转义

示例:

a=3
b=4echo `expr $a \> $b`  # 输出0,>需要转义
echo `expr $a '<' $b`  # 输出1,也可以将特殊字符用引号引起来
echo `expr $a '>=' $b`  # 输出0
echo `expr $a \<\= $b`  # 输出1c=0
d=5echo `expr $c \& $d`  # 输出0
echo `expr $a \& $b`  # 输出3
echo `expr $c \| $d`  # 输出5
echo `expr $a \| $b`  # 输出3

read命令

read命令用于从标准输入中读取单行数据。当读到文件结束符时,exit code为1,否则为0。

参数说明

  • -p: 后面可以接提示信息

  • -t:后面跟秒数,定义输入字符的等待时间,超过等待时间后会自动忽略此命令

实例:

acs@9e0ebfcd82d7:~$ read name  # 读入name的值
acwing yxc  # 标准输入
acs@9e0ebfcd82d7:~$ echo $name  # 输出name的值
acwing yxc  #标准输出
acs@9e0ebfcd82d7:~$ read -p "Please input your name: " -t 30 name  # 读入name的值,等待时间30秒
Please input your name: acwing yxc  # 标准输入
acs@9e0ebfcd82d7:~$ echo $name  # 输出name的值
acwing yxc  # 标准输出

echo命令

echo用于输出字符串。命令格式:

echo STRING

显示普通字符串

echo "Hello AC Terminal"
echo Hello AC Terminal  # 引号可以省略

显示转义字符

echo "\"Hello AC Terminal\""  # 注意只能使用双引号,如果使用单引号,则不转义
echo \"Hello AC Terminal\"  # 也可以省略双引号

显示变量

name=yxc
echo "My name is $name"  # 输出 My name is yxc

显示换行

echo -e "Hi\n"  # -e 开启转义
echo "acwing"

输出结果:

Hiacwing

显示不换行

echo -e "Hi \c" # -e 开启转义 \c 不换行
echo "acwing"

输出结果:

Hi acwing

显示结果定向至文件

echo "Hello World" > output.txt  # 将内容以覆盖的方式输出到output.txt中

原样输出字符串,不进行转义或取变量(用单引号)

name=acwing
echo '$name\"'

输出结果

$name\"

显示命令的执行结果

echo `date`

输出结果:

Wed Sep 1 11:45:33 CST 2021

printf命令

printf命令用于格式化输出,类似于C/C++中的printf函数。

默认不会在字符串末尾添加换行符。

命令格式:

printf format-string [arguments...]

用法示例
脚本内容:

printf "%10d.\n" 123  # 占10位,右对齐
printf "%-10.2f.\n" 123.123321  # 占10位,保留2位小数,左对齐
printf "My name is %s\n" "yxc"  # 格式化输出字符串
printf "%d * %d = %d\n"  2 3 `expr 2 \* 3` # 表达式的值作为参数

输出结果:

   123.123.12    .
My name is yxc
2 * 3 = 6

test命令与判断符号[]

逻辑运算符&&和||

  • &&表示与,|| 表示或

  • 二者具有短路原则:
    expr1 && expr2:当expr1为假时,直接忽略expr2
    expr1 || expr2:当expr1为真时,直接忽略expr2

  • 表达式的exit code为0,表示真;为非零,表示假。(与C/C++中的定义相反)

test命令
在命令行中输入man test,可以查看test命令的用法。

test命令用于判断文件类型,以及对变量做比较。

test命令用exit code返回结果,而不是使用stdout。0表示真,非0表示假。

例如:

test 2 -lt 3  # 为真,返回值为0
echo $?  # 输出上个命令的返回值,输出0
acs@9e0ebfcd82d7:~$ ls  # 列出当前目录下的所有文件
homework  output.txt  test.sh  tmp
acs@9e0ebfcd82d7:~$ test -e test.sh && echo "exist" || echo "Not exist"
exist  # test.sh 文件存在
acs@9e0ebfcd82d7:~$ test -e test2.sh && echo "exist" || echo "Not exist"
Not exist  # testh2.sh 文件不存在

文件类型判断
命令格式:

test -e filename  # 判断文件是否存在
测试参数 代表意义
-e 文件是否存在
-f 是否为文件
-d 是否为目录

文件权限判断
命令格式:

test -r filename  # 判断文件是否可读
测试参数 代表意义
-r 文件是否可读
-w 文件是否可写
-x 文件是否可执行
-s 是否为非空文件

整数间的比较
命令格式:

test $a -eq $b  # a是否等于b
测试参数 代表意义
-eq a是否等于b
-ne a是否不等于b
-gt a是否大于b
-lt a是否小于b
-ge a是否大于等于b
-le a是否小于等于b

字符串比较

测试参数 代表意义
test -z STRING 判断STRING是否为空,如果为空,则返回true
test -n STRING 判断STRING是否非空,如果非空,则返回true(-n可以省略)
test str1 == str2 判断str1是否等于str2
test str1 != str2 判断str1是否不等于str2

多重条件判定
命令格式:

test -r filename -a -x filename
测试参数 代表意义
-a 两条件是否同时成立
-o 两条件是否至少一个成立
! 取反。如 test ! -x file,当file不可执行时,返回true

判断符号[]
[]test用法几乎一模一样,更常用于if语句中。另外[[]][]的加强版,支持的特性更多。

例如:

[ 2 -lt 3 ]  # 为真,返回值为0
echo $?  # 输出上个命令的返回值,输出0
acs@9e0ebfcd82d7:~$ ls  # 列出当前目录下的所有文件
homework  output.txt  test.sh  tmp
acs@9e0ebfcd82d7:~$ [ -e test.sh ] && echo "exist" || echo "Not exist"
exist  # test.sh 文件存在
acs@9e0ebfcd82d7:~$ [ -e test2.sh ] && echo "exist" || echo "Not exist"
Not exist  # testh2.sh 文件不存在

注意:

  • []内的每一项都要用空格隔开

  • 中括号内的变量,最好用双引号括起来

  • 中括号内的常数,最好用单或双引号括起来

例如:

name="acwing yxc"
[ $name == "acwing yxc" ]  # 错误,等价于 [ acwing yxc == "acwing yxc" ],参数太多
[ "$name" == "acwing yxc" ]  # 正确

判断语句

if…then形式
类似于C/C++中的if-else语句。

单层if
命令格式:

if condition
then语句1语句2...
fi

示例:

a=3
b=4if [ "$a" -lt "$b" ] && [ "$a" -gt 2 ]
thenecho ${a}在范围内
fi

输出结果:

3在范围内

单层if-else
命令格式

if condition
then语句1语句2...
else语句1语句2...
fi

示例:

a=3
b=4if ! [ "$a" -lt "$b" ]
thenecho ${a}不小于${b}
elseecho ${a}小于${b}
fi

输出结果:

3小于4

多层if-elif-elif-else
命令格式

if condition
then语句1语句2...
elif condition
then语句1语句2...
elif condition
then语句1语句2
else语句1语句2...
fi

示例:

a=4if [ $a -eq 1 ]
thenecho ${a}等于1
elif [ $a -eq 2 ]
thenecho ${a}等于2
elif [ $a -eq 3 ]
thenecho ${a}等于3
elseecho 其他
fi

输出结果:

其他

case…esac形式
类似于C/C++中的switch语句。

命令格式

case $变量名称 in值1)语句1语句2...;;  # 类似于C/C++中的break值2)语句1语句2...;;*)  # 类似于C/C++中的default语句1语句2...;;
esac

示例:

a=4case $a in1)echo ${a}等于1;;  2)echo ${a}等于2;;  3)                                                echo ${a}等于3;;  *)echo 其他;;
esac

输出结果:

其他

循环语句

for…in…do…done
命令格式:

for var in val1 val2 val3
do语句1语句2...
done

示例1,输出a 2 cc,每个元素一行:

for i in a 2 cc
doecho $i
done

示例2,输出当前路径下的所有文件名,每个文件名一行:

for file in `ls`
doecho $file
done

示例3,输出1-10

for i in $(seq 1 10)
doecho $i
done

示例4,使用{1…10} 或者 {a…z}

for i in {a..z}
doecho $i
done

for ((…;…;…)) do…done

命令格式:

for ((expression; condition; expression))
do语句1语句2
done

示例,输出1-10,每个数占一行:

for ((i=1; i<=10; i++))
doecho $i
done

while…do…done循环
命令格式:

while condition
do语句1语句2...
done

示例,文件结束符为Ctrl+d,输入文件结束符后read指令返回false。

while read name
doecho $name
done

until…do…done循环
当条件为真时结束。

命令格式:

until condition
do语句1语句2...
done

示例,当用户输入yes或者YES时结束,否则一直等待读入。

until [ "${word}" == "yes" ] || [ "${word}" == "YES" ]
doread -p "Please input yes/YES to stop this program: " word
done

break命令
跳出当前一层循环,注意与C/C++不同的是:break不能跳出case语句。

示例

while read name
dofor ((i=1;i<=10;i++))docase $i in8)break;;*)echo $i;;esacdone
done

该示例每读入非EOF的字符串,会输出一遍1-7
该程序可以输入Ctrl+d文件结束符来结束,也可以直接用Ctrl+c杀掉该进程。

continue命令
跳出当前循环。

示例:

for ((i=1;i<=10;i++))
doif [ `expr $i % 2` -eq 0 ]thencontinuefiecho $i
done

该程序输出1-10中的所有奇数。

死循环的处理方式
如果AC Terminal可以打开该程序,则输入Ctrl+c即可。

否则可以直接关闭进程:

  • 使用top命令找到进程的PID
  • 输入kill -9 PID即可关掉此进程

函数

bash中的函数类似于C/C++中的函数,但return的返回值与C/C++不同,返回的是exit code,取值为0-255,0表示正常结束。

如果想获取函数的输出结果,可以通过echo输出到stdout中,然后通过$(function_name)来获取stdout中的结果。

函数的return值可以通过$?来获取。

命令格式:

[function] func_name() {  # function关键字可以省略语句1语句2...
}

不获取 return值和stdout值
示例

func() {name=yxcecho "Hello $name"
}func

输出结果:

Hello yxc

获取 return值和stdout
不写return时,默认return 0

示例

func() {name=yxcecho "Hello $name"return 123}output=$(func)
ret=$?echo "output = $output"
echo "return = $ret"

输出结果:

output = Hello yxc
return = 123

函数的输入参数
在函数内,$1表示第一个输入参数,$2表示第二个输入参数,依此类推。

注意:函数内的$0仍然是文件名,而不是函数名。

示例:

func() {  # 递归计算 $1 + ($1 - 1) + ($1 - 2) + ... + 0word=""while [ "${word}" != 'y' ] && [ "${word}" != 'n' ]doread -p "要进入func($1)函数吗?请输入y/n:" worddoneif [ "$word" == 'n' ]thenecho 0return 0fi  if [ $1 -le 0 ] thenecho 0return 0fi  sum=$(func $(expr $1 - 1))echo $(expr $sum + $1)}echo $(func 10)

输出结果:

55

函数内的局部变量
可以在函数内定义局部变量,作用范围仅在当前函数内。

可以在递归函数中定义局部变量。

命令格式:

local 变量名=变量值

例如:

#! /bin/bashfunc() {local name=yxcecho $name
}
funcecho $name

输出结果:

yxc

第一行为函数内的name变量,第二行为函数外调用name变量,会发现此时该变量不存在。

exit命令

exit命令用来退出当前shell进程,并返回一个退出状态;使用$?可以接收这个退出状态。

exit命令可以接受一个整数值作为参数,代表退出状态。如果不指定,默认状态值是 0。

exit退出状态只能是一个介于 0~255 之间的整数,其中只有 0 表示成功,其它值都表示失败。

示例:

创建脚本test.sh,内容如下:

#! /bin/bashif [ $# -ne 1 ]  # 如果传入参数个数等于1,则正常退出;否则非正常退出。
thenecho "arguments not valid"exit 1
elseecho "arguments valid"exit 0
fi

执行该脚本:

acs@9e0ebfcd82d7:~$ chmod +x test.sh
acs@9e0ebfcd82d7:~$ ./test.sh acwing
arguments valid
acs@9e0ebfcd82d7:~$ echo $?  # 传入一个参数,则正常退出,exit code为0
0
acs@9e0ebfcd82d7:~$ ./test.sh
arguments not valid
acs@9e0ebfcd82d7:~$ echo $?  # 传入参数个数不是1,则非正常退出,exit code为1
1

文件重定向

每个进程默认打开3个文件描述符:

  • stdin标准输入,从命令行读取数据,文件描述符为0

  • stdout标准输出,向命令行输出数据,文件描述符为1

  • stderr标准错误输出,向命令行输出数据,文件描述符为2

可以用文件重定向将这三个文件重定向到其他文件中。

重定向命令列表

命令 说明
command > file stdout重定向到file
command < file stdin重定向到file
command >> file stdout以追加方式重定向到file
command n> file 将文件描述符n重定向到file
command n>> file 将文件描述符n以追加方式重定向到file

输入和输出重定向

echo -e "Hello \c" > output.txt  # 将stdout重定向到output.txt中
echo "World" >> output.txt  # 将字符串追加到output.txt中read str < output.txt  # 从output.txt中读取字符串echo $str  # 输出结果:Hello World

同时重定向stdin和stdout
创建bash脚本:

#! /bin/bashread a
read becho $(expr "$a" + "$b")

创建input.txt,里面的内容为:

3
4

执行命令:

acs@9e0ebfcd82d7:~$ chmod +x test.sh  # 添加可执行权限
acs@9e0ebfcd82d7:~$ ./test.sh < input.txt > output.txt  # 从input.txt中读取内容,将输出写入output.txt中
acs@9e0ebfcd82d7:~$ cat output.txt  # 查看output.txt中的内容
7

引入外部脚本

类似于C/C++中的include操作,bash也可以引入其他文件中的代码。

语法格式:

. filename  # 注意点和文件名之间有一个空格或source filename

示例
创建test1.sh,内容为:

#! /bin/bashname=yxc  # 定义变量name

然后创建test2.sh,内容为:

#! /bin/bashsource test1.sh # 或 . test1.shecho My name is: $name  # 可以使用test1.sh中的变量

执行命令:

acs@9e0ebfcd82d7:~$ chmod +x test2.sh
acs@9e0ebfcd82d7:~$ ./test2.sh
My name is: yxc

创建作业 & 测试作业的正确性

homework 3 create 可以重新创建所有lesson_3的作业
homework 3 create id 可以单独创建lesson_3的第id个作业. e.g.
homework 3 create 0 可以只重新创建lesson_3的第0个作业
homework 3 test 可以评测lesson_3的所有作业

作业

创建好作业后,先进入文件夹/home/acs/homework/lesson_3/,然后:
(0) 进入homework_0文件夹,编写自动完成lesson_1作业的脚本helper.sh。要求:[1] 当前目录下仅包含helper.sh[2] helper.sh具有可执行权限[3] 在任意路径依次执行下列命令后,lesson_1的作业可以得到满分:1) homework 1 create2) /home/acs/homework/lesson_3/homework_0/helper.sh
(1) 进入homework_1文件夹,编写脚本check_file.sh。要求:[1] 当前目录下仅包含check_file.sh。[2] check_file.sh具有可执行权限。[3] check_file.sh接收一个传入参数。格式为 ./check_file.sh file[4] 判断传递参数,分别在标准输出中输出如下内容(不包括双引号):1) 如果传入参数个数不是1,则输出一行:"arguments not valid",然后退出,退出状态等于1。2) 如果file文件不存在,则输出一行:"not exist",然后退出,退出状态等于2。3) 如果file文件存在,则输出分别进行如下5个判断,然后退出,退出状态等于0。1] 如果file为普通文件,则输出一行:"regular file"2] 如果file为目录(文件夹),则输出一行:"directory"3] 如果file具有可读权限,则输出一行:"readable"4] 如果file具有可写权限,则输出一行:"writable"5] 如果file具有可执行权限,则输出一行:"executable"
(2) 进入homework_2文件夹,编写脚本main.sh。要求:[1] 当前目录下仅包含main.sh[2] main.sh具有可执行权限[3] 该文件从stdin(标准输入)中读取一个整数n[4] 在stdout(标准输出)输出斐波那契数列的第n项。即:a[0] = 1, a[1] = 1, a[i] = a[i - 1] + a[i - 2], 求a[n]。[5] 数据保证 0 <= n <= 20,脚本不需要判断n的合法性。
(3) 进入homework_3文件夹,编写脚本main.sh。要求:[1] 当前目录下仅包含main.sh[2] main.sh具有可执行权限[3] 该文件从stdin(标准输入)中读取两行整数n和m[4] 在stdout(标准输出)中输出1~n的按字典序从小到大的顺序数第m个全排列,输出一行,用空格隔开所有数,行末可以有多余空格。[5] 数据保证 1 <= n <= 10, 1 <= m <= min(100, n!),脚本不需要判断数据的合法性。
(4) 进入homework_4文件夹,编写脚本main.sh。要求:[1] 当前目录下仅包含main.sh[2] main.sh具有可执行权限[3] main.sh接收两个传入参数。格式为 ./main.sh input_file output_file[4] 从input_file中读取一个正整数n,然后将前n个正整数的平方和写入output_file中[5] 数据保证 1 <= n <= 100,脚本不需要判断所有数据的合法性。

ssh

ssh教程

ssh登录

基本用法
远程登录服务器:

ssh user@hostname
  • user: 用户名

  • hostname: IP地址或域名

第一次登录时会提示:

The authenticity of host '123.57.47.211 (123.57.47.211)' can't be established.
ECDSA key fingerprint is SHA256:iy237yysfCe013/l+kpDGfEG9xxHxm0dnxnAbJTPpG8.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

输入yes,然后回车即可。
这样会将该服务器的信息记录在~/.ssh/known_hosts文件中。

然后输入密码即可登录到远程服务器中。

默认登录端口号为22。如果想登录某一特定端口:

ssh user@hostname -p 22

配置文件
创建文件 ~/.ssh/config

然后在文件中输入:

Host myserver1HostName IP地址或域名User 用户名Host myserver2HostName IP地址或域名User 用户名

之后再使用服务器时,可以直接使用别名myserver1myserver2

密钥登录
创建密钥:

ssh-keygen

然后一直回车即可。

执行结束后,~/.ssh/目录下会多两个文件:

  • id_rsa:私钥

  • id_rsa.pub:公钥

之后想免密码登录哪个服务器,就将公钥传给哪个服务器即可。

例如,想免密登录myserver服务器。则将公钥中的内容,复制到myserver中的~/.ssh/authorized_keys文件里即可。

也可以使用如下命令一键添加公钥:

ssh-copy-id myserver

执行命令
命令格式:

ssh user@hostname command

例如:

ssh user@hostname ls -a

或者

# 单引号中的$i可以求值ssh myserver 'for ((i = 0; i < 10; i ++ )) do echo $i; done'

或者

# 双引号中的$i不可以求值ssh myserver "for ((i = 0; i < 10; i ++ )) do echo $i; done"

scp传文件

基本用法
命令格式:

scp source destination

source路径下的文件复制到destination

一次复制多个文件:

scp source1 source2 destination

复制文件夹:

scp -r ~/tmp myserver:/home/acs/

将本地家目录中的tmp文件夹复制到myserver服务器中的/home/acs/目录下。

scp -r ~/tmp myserver:homework/

将本地家目录中的tmp文件夹复制到myserver服务器中的~/homework/目录下。

scp -r myserver:homework .

myserver服务器中的~/homework/文件夹复制到本地的当前路径下。

指定服务器的端口号:

scp -P 22 source1 source2 destination

注意scp-r -P等参数尽量加在sourcedestination之前。

使用scp配置其他服务器的vimtmux

scp ~/.vimrc ~/.tmux.conf myserver:

获取ssh教程配套的远程服务器账号的信息

homework 4 getinfo

创建作业 & 测试作业的正确性

homework 4 create 可以重新创建所有lesson_4的作业
homework 4 create id 可以单独创建lesson_4的第id个作业. e.g.
homework 4 create 0 可以只重新创建lesson_4的第0个作业
homework 4 test 可以评测lesson_4的所有作业

作业

创建好作业后,先进入文件夹/home/acs/homework/lesson_4/,然后:
(0) 进入homework_0文件夹,要求:[1] 该文件夹内容为空[2] 配置服务器账号的密钥登陆方式。服务器信息可以通过如下命令获得:homework 4 getinfo将服务器账号的名称(Host)配置成:myserver
(1) 进入homework_1文件夹,下列描述中的“本地”均表示当前文件夹。要求:[1] 在myserver服务器上创建并清空文件夹:~/homework/lesson_4/homework_1/[2] 将本地的main.cpp文件上传到myserver中的~/homework/lesson_4/homework_1/目录中。[3] 在本地创建文件夹dir。[4] 将myserver中的/etc/lsb-release文件复制到dir中。
(2) 进入homework_2文件夹,下列描述中的“本地”均表示当前文件夹,要求:[1] 在myserver服务器上创建并清空文件夹:~/homework/lesson_4/homework_2/[2] 将本地的dir文件夹上传到myserver中的~/homework/lesson_4/homework_2/目录中。
(3) 进入homework_3文件夹,下列描述中的“本地”均表示当前文件夹,要求:[1] 在本地创建文件夹dir。[2] 将myserver中的/var/lib/locales/supported.d文件夹下载到本地dir文件夹中。
(4) 进入homework_4文件夹,编写脚本remote_mkdir.sh和remote_rmdir.sh,要求:[1] 在myserver服务器上创建并清空文件夹:~/homework/lesson_4/homework_4/[2] 本地目录下仅包含remote_mkdir.sh和remote_rmdir.sh[3] remote_mkdir.sh和remote_rmdir.sh具有可执行权限[4] remote_mkdir.sh接收一个传入参数。格式为 ./remote_mkdir.sh directory_name该操作可以在myserver服务器上的~/homework/lesson_4/homework_4/目录下,创建一个名为directory_name的文件夹[5] remote_rmdir.sh接收一个传入传输。格式为 ./remote_rmdir.sh directory_name该操作可以将myserver服务器上的~/homework/lesson_4/homework_4/目录下的名为directory_name的文件夹删掉。[6] 注意:传入的文件参数可能包含空格。两个脚本均不需要判断传入参数的合法性。

git

git教程

代码托管平台:git.acwing.com

git基本概念

  • 工作区:仓库的目录。工作区是独立于各个分支的。
  • 暂存区:数据暂时存放的区域,类似于工作区写入版本库前的缓存区。暂存区是独立于各个分支的。
  • 版本库:存放所有已经提交到本地仓库的代码版本
  • 版本结构:树结构,树中每个节点代表一个代码版本。

git常用命令

1.git config --global user.name xxx:设置全局用户名,信息记录在~/.gitconfig文件中
2.git config --global user.email xxx@xxx.com:设置全局邮箱地址,信息记录在~/.gitconfig文件中
3.git init:将当前目录配置成git仓库,信息记录在隐藏的.git文件夹中

  • git add XX:将XX文件添加到暂存区

4.git add .:将所有待加入暂存区的文件加入暂存区
5.git rm --cached XX:将文件从仓库索引目录中删掉
6.git commit -m "给自己看的备注信息":将暂存区的内容提交到当前分支
7.git status:查看仓库状态
8.git diff XX:查看XX文件相对于暂存区修改了哪些内容
9.git log:查看当前分支的所有版本
10.git reflog:查看HEAD指针的移动历史(包括被回滚的版本)
11.git reset --hard HEAD^ 或 git reset --hard HEAD~:将代码库回滚到上一个版本

  • git reset --hard HEAD^^:往上回滚两次,以此类推

  • git reset --hard HEAD~100:往上回滚100个版本

  • git reset --hard 版本号:回滚到某一特定版本

12.git checkout — XX或git restore XX:将XX文件尚未加入暂存区的修改全部撤销
13.git remote add origin git@git.acwing.com:xxx/XXX.git:将本地仓库关联到远程仓库
14.git push -u (第一次需要-u以后不需要):将当前分支推送到远程仓库

  • git push origin branch_name:将本地的某个分支推送到远程仓库

15.git clone git@git.acwing.com:xxx/XXX.git:将远程仓库XXX下载到当前目录下
16.git checkout -b branch_name:创建并切换到branch_name这个分支
17.git branch:查看所有分支和当前所处分支
18.git checkout branch_name:切换到branch_name这个分支
19.git merge branch_name:将分支branch_name合并到当前分支上
20.git branch -d branch_name:删除本地仓库的branch_name分支
21.git branch branch_name:创建新分支
22.git push --set-upstream origin branch_name:设置本地的branch_name分支对应远程仓库的branch_name分支
23.git push -d origin branch_name:删除远程仓库的branch_name分支
24.git pull:将远程仓库的当前分支与本地仓库的当前分支合并

  • git pull origin branch_name:将远程仓库的branch_name分支与本地仓库的当前分支合并

25.git branch --set-upstream-to=origin/branch_name1 branch_name2:将远程的branch_name1分支与本地的branch_name2分支对应
26.git checkout -t origin/branch_name 将远程的branch_name分支拉取到本地
27.git stash:将工作区和暂存区中尚未提交的修改存入栈中
28.git stash apply:将栈顶存储的修改恢复到当前分支,但不删除栈顶元素
29.git stash drop:删除栈顶存储的修改
30.git stash pop:将栈顶存储的修改恢复到当前分支,同时删除栈顶元素
31.git stash list:查看栈中所有元素

创建作业 & 测试作业的正确性

homework 5 create  # 可以重新创建所有lesson_5的作业
homework 5 test  # 可以评测lesson_5的所有作业

作业

注意: 本次作业的10个题目不是独立的,每个题目会依赖于前一个题目,因此评测时如果当前题目错误,则不再评测后续题目。

创建好作业后,先进入文件夹/home/acs/homework/lesson_5/,然后:

  • (0) 在当前目录下创建文件夹homework,并将homework目录配置成git仓库。后续作业均在homework目录下操作;
  • (1) 创建文件readme.txt,内容包含一行:111
    将修改提交一个commit
  • (2) 在readme.txt文件末尾新增一行:222
    将修改提交一个commit
  • (3) 创建文件夹:problem1problem2
    创建文件problem1/main.cpp。文件内容为下述链接中的代码:https://www.acwing.com/problem/content/submission/code_detail/7834813/;
    创建文件problem2/main.cpp。文件内容为下述链接中的代码:https://www.acwing.com/problem/content/submission/code_detail/7834819/;
    将修改提交一个commit
  • (4) 删除文件夹problem2
    创建文件夹problem3
    创建文件problem3/main.cpp。文件内容为下述链接中的代码:https://www.acwing.com/problem/content/submission/code_detail/7834841/;
    readme.txt中最后一行222删掉,然后添加一行333
    将修改提交一个commit
  • (5) 在https://git.acwing.com/上注册账号并创建仓库,仓库名称为homework
    将本地git仓库上传到AC Git云端仓库;
  • (6) 创建并切换至新分支dev
    readme.txt文件中添加一行444
    将修改提交一个commit
    dev分支推送至AC Git远程仓库;
  • (7) 切换回master分支;
    readme.txt文件中添加一行555
    将修改提交一个commit
  • (8) 将dev分支合并到master分支;
    手动处理冲突,使readme文件最终内容包含4行:111333555444
    将修改提交一个commit
  • (9) 将master分支的版本库push到AC Git云端仓库;
    登录myserver服务器(4. ssh作业中配置的服务器);
    创建并清空文件夹:~/homework/lesson_5/
    将AC Git云端仓库clone~/homework/lesson_5/中;

thrift

thrift教程

  • thrift官网
  • 上课代码地址

创建作业 & 测试作业的正确性

homework 6 create  # 可以重新创建所有lesson_6的作业
homework 6 test  # 可以评测lesson_6的所有作业

作业

本次作业为复现课上最后一个版本的内容,课程视频地址
注意:本次作业的2个题目采用整体评测,即如果两个作业同时正确,则得100分;否则如果至少有一个作业错误,则得0分。

创建好作业后,先进入文件夹/home/acs/homework/lesson_6/,当前目录的文件结构如下:

`-- thrift_lesson|-- game|   `-- src|-- match_system|   `-- src |-- readme.md`-- thrift|-- match.thrift`-- save.thrift
  • (0) 进入thrift_lesson/match_system/src/目录,用cpp实现课上的match-serversave-client逻辑。
    接口文件在thrift_lesson/thrift/中。
    实现后启动server,监听端口9090
  • (1) 进入thrift_lesson/game/src/目录,用python3实现课上的match-client逻辑。
    文件名和输入格式与课上内容相同。

管道、环境变量与常用命令

知识点

管道

概念
管道类似于文件重定向,可以将前一个命令的stdout重定向到下一个命令的stdin

要点
管道命令仅处理stdout,会忽略stderr
管道右边的命令必须能接受stdin
多个管道命令可以串联。

与文件重定向的区别
文件重定向左边为命令,右边为文件。
管道左右两边均为命令,左边有stdout,右边有stdin

举例
统计当前目录下所有python文件的总行数,其中findxargswc等命令可以参考常用命令这一节内容。

find . -name '*.py' | xargs cat | wc -l

环境变量

概念
Linux系统中会用很多环境变量来记录配置信息
环境变量类似于全局变量,可以被各个进程访问到。我们可以通过修改环境变量来方便地修改系统配置。

查看
列出当前环境下的所有环境变量:

env  # 显示当前用户的变量
set  # 显示当前shell的变量,包括当前用户的变量;
export  # 显示当前导出成用户变量的shell变量

输出某个环境变量的值:

echo $PATH

修改
环境变量的定义、修改、删除操作可以参考3. shell语法——变量这一节的内容。

为了将对环境变量的修改应用到未来所有环境下,可以将修改命令放到~/.bashrc文件中。
修改完~/.bashrc文件后,记得执行source ~/.bashrc,来将修改应用到当前的bash环境下。

为何将修改命令放到~/.bashrc,就可以确保修改会影响未来所有的环境呢?

  • 每次启动bash,都会先执行~/.bashrc
  • 每次ssh登陆远程服务器,都会启动一个bash命令行给我们。
  • 每次tmux新开一个pane,都会启动一个bash命令行给我们。
  • 所以未来所有新开的环境都会加载我们修改的内容。

常见环境变量

  • 1.HOME:用户的家目录。
  • 2.PATH:可执行文件(命令)的存储路径。路径与路径之间用:分隔。当某个可执行文件同时出现在多个路径中时,会选择从左到右数第一个路径中的执行。下列所有存储路径的环境变量,均采用从左到右的优先顺序
  • 3.LD_LIBRARY_PATH:用于指定动态链接库(.so文件)的路径,其内容是以冒号分隔的路径列表。
  • 4.C_INCLUDE_PATHC语言的头文件路径,内容是以冒号分隔的路径列表。
  • 5.CPLUS_INCLUDE_PATHCPP的头文件路径,内容是以冒号分隔的路径列表。
  • 6.PYTHONPATHPython导入包的路径,内容是以冒号分隔的路径列表。
  • 7.JAVA_HOMEjdk的安装目录。
  • 8.CLASSPATH:存放Java导入类的路径,内容是以冒号分隔的路径列表。

常用命令

Linux命令非常多,本节讲解几个常用命令。其他命令依赖于大家根据实际操作环境,边用边查。

系统状况
1.top:查看所有进程的信息(Linux的任务管理器)

  • 打开后,输入M:按使用内存排序

  • 打开后,输入P:按使用CPU排序

  • 打开后,输入q:退出

2.df -h:查看硬盘使用情况
3.free -h:查看内存使用情况
4.du -sh:查看当前目录占用的硬盘空间
5.ps aux:查看所有进程
6.kill -9 pid:杀死编号为pid的进程

  • 传递某个具体的信号:kill -s SIGTERM pid

7.netstat -nt:查看所有网络连接
8.w:列出当前登陆的用户
9.ping www.baidu.com:检查是否连网

文件权限
1.chmod:修改文件权限

  • chmod +x xxx:给xxx添加可执行权限

  • chmod -x xxx:去掉xxx的可执行权限

  • chmod 777 xxx:将xxx的权限改成777

  • chmod 777 xxx -R:递归修改整个文件夹的权限

文件检索
1.find /path/to/directory/ -name '*.py':搜索某个文件路径下的所有*.py文件
2.grep xxx:从stdin中读入若干行数据,如果某行中包含xxx,则输出该行;否则忽略该行。
3.wc:统计行数、单词数、字节数

  • 既可以从stdin中直接读入内容;也可以在命令行参数中传入文件名列表;

  • wc -l:统计行数

  • wc -w:统计单词数

  • wc -c:统计字节数

4.tree:展示当前目录的文件结构

  • tree /path/to/directory/:展示某个目录的文件结构

  • tree -a:展示隐藏文件

5.ag xxx:搜索当前目录下的所有文件,检索xxx字符串
6.cut:分割一行内容

  • stdin中读入多行数据

  • echo $*PATH | cut -d ':' -f 3,5:输出PATH:分割后第3、5列数据

  • echo *$PATH | cut -d ':' -f 3-5:输出PATH:分割后第3-5列数据

  • echo $PATH | cut -c 3,5:输出PATH的第3、5个字符

  • echo $PATH | cut -c 3-5:输出PATH的第3-5个字符

7.sort:将每行内容按字典序排序

  • 可以从stdin中读取多行数据

  • 可以从命令行参数中读取文件名列表

8.xargs:将stdin中的数据用空格或回车分割成命令行参数

  • find . -name '*.py' | xargs cat | wc -l:统计当前目录下所有python文件的总行数

查看文件内容
1.re:浏览文件内容

  • 回车:下一行

  • 空格:下一页

  • b:上一页

  • q:退出

2.less:与more类似,功能更全

  • 回车:下一行

  • y:上一行

  • Page Down:下一页

  • Page Up:上一页

  • q:退出

3.head -3 xxx:展示xxx的前3行内容
同时支持从stdin读入内容
4.tail -3 xxx:展示xxx末尾3行内容

  • 同时支持从stdin读入内容

用户相关
1.history:展示当前用户的历史操作。内容存放在~/.bash_history

工具
1.md5sum:计算md5哈希值

  • 可以从stdin读入内容

  • 也可以在命令行参数中传入文件名列表;

2.time command:统计command命令的执行时间
3.ipython3:交互式python3环境。可以当做计算器,或者批量管理文件。

  • ! echo "Hello World"!表示执行shell脚本

4.watch -n 0.1 command:每0.1秒执行一次command命令
5.tar:压缩文件

  • tar -zcvf xxx.tar.gz /path/to/file/*****:压缩

  • tar -zxvf xxx.tar.gz:解压缩

6.diff xxx yyy:查找文件xxxyyy的不同点

安装软件

  • sudo command:以root身份执行command命令

  • apt-get install xxx:安装软件

  • pip install xxx --user --upgrade:安装python

创建作业 & 测试作业的正确性

homework 7 create 可以重新创建所有lesson_7的作业
homework 7 create id 可以单独创建lesson_7的第id个作业. e.g.
homework 7 create 0 可以只重新创建lesson_7的第0个作业
homework 7 test 可以评测lesson_7的所有作业

作业

创建好作业后,先进入文件夹/home/acs/homework/lesson_7/,然后:

  • (0) 进入homework_0文件夹,然后:
    [1] 编写可执行shell脚本,文件名为mydu,使得在任意目录执行该脚本后,可以输出当前目录所占用的磁盘空间大小,格式化输出(例如 1K, 234M, 2G)。
    [2] 修改环境变量PATH,使得在任意目录下输入mydu均可执行上述脚本。
  • (1) 进入homework_1文件夹,然后:
    [1] 给当前目录下的所有文件添加可读权限。
    [2] 统计当前目录下共有多少个以.cpp结尾的文件,将结果写入ans.txt中。
  • (2) 进入homework_2文件夹,然后:
    [1] 统计当前目录下所有cpp文件的总行数,将结果写入ans1.txt中。
    [2] 遍历当前目录下所有py文件,统计共有多少行包含字符串thrift,将结果写入ans2.txt中。
  • (3) 进入homework_3文件夹,然后删除当前目录下的所有py文件。
  • (4) 进入homework_4文件夹,然后:
    [1] 当前目录下包含一个文件scores.txt,文件中有若干行数据,每行数据包含用空格隔开的3个字段:姓名、数学成绩、算法成绩。
    [2] 将scores.txt文件的内容以空格为分隔符分隔成3列,将第一列内容写入names.txt,第二列内容写入mathematics.txt,第三列内容写入algorithm.txt
    注意:scores.txt文件本身不要修改。
  • (5) 进入homework_5文件夹,然后:
    [1] 当前目录下包含一个文件scores.txt,文件中有若干行数据,每行数据包含用空格隔开的3个字段:姓名、数学成绩、算法成绩。
    [2] 将scores.txt文件的内容以空格为分隔符分隔成3列,将第一列内容按字典序从小到大排序后写入names.txt
    注意:scores.txt文件本身不要修改。
  • (6) 进入homework_6文件夹,然后将scores.txt文件的前5行写入top.txt,后4行写入bottom.txt
  • (7) 进入homework_7文件夹,计算scores.txt文件的md5sum,将结果写入ans.txt。注意:ans.txt文件中只包含长度为32的md5sum,不包含其他内容。
  • (8) 进入homework_8文件夹,然后:
    [1] 将dir_a文件夹压缩为project_a.tar.gz
    [2] 将project_b.tar.gz压缩文件解压到当前目录。
    注意:不要删除dir_a文件夹和project_b.tar.gz文件。
  • (9) 进入homework_9文件夹,然后计算 2^112+3^78,将结果写入ans.txt中。

租云服务器及配docker环境

知识点

概述

云平台的作用:

存放我们的docker容器,让计算跑在云端。
获得公网IP地址,让每个人可以访问到我们的服务。

任选一个云平台即可,推荐配置:

  • 1核 2GB(后期可以动态扩容,前期配置低一些没关系)
  • 网络带宽采用按量付费,最大带宽拉满即可(费用取决于用量,与最大带宽无关)
  • 系统版本:ubuntu 20.04 LTS(推荐用统一版本,避免后期出现配置不兼容的问题)

租云服务器及安装docker之阿里云

阿里云地址

创建工作用户acs并赋予sudo权限

登录到新服务器。打开AC Terminal,然后:

ssh root@xxx.xxx.xxx.xxx  # xxx.xxx.xxx.xxx替换成新服务器的公网IP

创建acs用户:

adduser acs  # 创建用户acs
usermod -aG sudo acs  # 给用户acs分配sudo权限

配置免密登录方式
退回AC Terminal,然后配置acs用户的别名和免密登录,可以参考4. ssh——ssh登录。

配置新服务器的工作环境
将AC Terminal的配置传到新服务器上:

scp .bashrc .vimrc .tmux.conf server_name:  # server_name需要换成自己配置的别名

安装tmuxdocker
登录自己的服务器,然后安装tmux

sudo apt-get update
sudo apt-get install tmux

打开tmux。(养成好习惯,所有工作都在tmux里进行,防止意外关闭终端后,工作进度丢失)

然后在tmux中根据docker安装教程安装docker即可。

租云服务器及安装docker之腾讯云

腾讯云地址

创建工作用户acs并赋予sudo权限
登录到新服务器。打开AC Terminal,然后:

ssh root@xxx.xxx.xxx.xxx  # 注意腾讯云登录的用户不是root,而是ubuntu

创建acs用户:

adduser acs  # 创建用户acs
usermod -aG sudo acs  # 给用户acs分配sudo权限

配置免密登录方式
退回AC Terminal,然后配置acs用户的别名和免密登录,可以参考4. ssh——ssh登录。

配置新服务器的工作环境
将AC Terminal的配置传到新服务器上:

scp .bashrc .vimrc .tmux.conf server_name:  # server_name需要换成自己配置的别名

安装tmuxdocker
登录自己的服务器,然后安装tmux

sudo apt-get update
sudo apt-get install tmux

打开tmux。(养成好习惯,所有工作都在tmux里进行,防止意外关闭终端后,工作进度丢失)

然后在tmux中根据docker安装教程安装docker即可。

租云服务器及安装docker之华为云

华为云地址

创建工作用户acs并赋予sudo权限
登录到新服务器。打开AC Terminal,然后:

ssh root@xxx.xxx.xxx.xxx  # xxx.xxx.xxx.xxx替换成新服务器的公网IP

创建acs用户:

adduser acs  # 创建用户acs
usermod -aG sudo acs  # 给用户acs分配sudo权限

配置免密登录方式
退回AC Terminal,然后配置acs用户的别名和免密登录,可以参考4. ssh——ssh登录。

配置新服务器的工作环境
将AC Terminal的配置传到新服务器上:

scp .bashrc .vimrc .tmux.conf server_name:  # server_name需要换成自己配置的别名

安装tmuxdocker
登录自己的服务器,然后安装tmux

sudo apt-get update
sudo apt-get install tmux

打开tmux。(养成好习惯,所有工作都在tmux里进行,防止意外关闭终端后,工作进度丢失)

然后在tmux中根据docker安装教程安装docker即可。

docker教程

将当前用户添加到docker用户组
为了避免每次使用docker命令都需要加上sudo权限,可以将当前用户加入安装中自动创建的docker用户组(可以参考官方文档):

sudo usermod -aG docker $USER

镜像(images)
1.docker pull ubuntu:20.04:拉取一个镜像
2.docker images:列出本地所有镜像
3.docker image rm ubuntu:20.04docker rmi ubuntu:20.04:删除镜像ubuntu:20.04
4.docker [container] commit CONTAINER IMAGE_NAME:TAG:创建某个container的镜像
5.docker save -o ubuntu_20_04.tar ubuntu:20.04:将镜像ubuntu:20.04导出到本地文件ubuntu_20_04.tar
6.docker load -i ubuntu_20_04.tar:将镜像ubuntu:20.04从本地文件ubuntu_20_04.tar中加载出来
容器(container)
1.docker [container] create -it ubuntu:20.04:利用镜像ubuntu:20.04创建一个容器。
2.docker ps -a:查看本地的所有容器
3.docker [container] start CONTAINER:启动容器
4.docker [container] stop CONTAINER:停止容器
5.docker [container] restart CONTAINER:重启容器
6.docker [contaienr] run -itd ubuntu:20.04:创建并启动一个容器
7.docker [container] attach CONTAINER:进入容器

  • 先按Ctrl-p,再按Ctrl-q可以挂起容器

8.docker [container] exec CONTAINER COMMAND:在容器中执行命令
9.docker [container] rm CONTAINER:删除容器
10.docker container prune:删除所有已停止的容器
11.docker export -o xxx.tar CONTAINER:将容器CONTAINER导出到本地文件xxx.tar
12.docker import xxx.tar image_name:tag:将本地文件xxx.tar导入成镜像,并将镜像命名为image_name:tag
13.docker export/importdocker save/load的区别:

  • export/import会丢弃历史记录和元数据信息,仅保存容器当时的快照状态

  • save/load会保存完整记录,体积更大

14.docker top CONTAINER:查看某个容器内的所有进程
15.docker stats:查看所有容器的统计信息,包括CPU、内存、存储、网络等信息
16.docker cp xxx CONTAINER:xxxdocker cp CONTAINER:xxx xxx:在本地和容器间复制文件
17.docker rename CONTAINER1 CONTAINER2:重命名容器
18.docker update CONTAINER --memory 500MB:修改容器限制

实战
进入AC Terminal,然后:

scp /var/lib/acwing/docker/images/docker_lesson_1_0.tar server_name:  # 将镜像上传到自己租的云端服务器
ssh server_name  # 登录自己的云端服务器docker load -i docker_lesson_1_0.tar  # 将镜像加载到本地
docker run -p 20000:22 --name my_docker_server -itd docker_lesson:1.0  # 创建并运行docker_lesson:1.0镜像docker attach my_docker_server  # 进入创建的docker容器
passwd  # 设置root密码

去云平台控制台中修改安全组配置,放行端口20000

返回AC Terminal,即可通过ssh登录自己的docker容器:

ssh root@xxx.xxx.xxx.xxx -p 20000  # 将xxx.xxx.xxx.xxx替换成自己租的服务器的IP地址

然后,可以仿照上节课内容,创建工作账户acs

最后,可以参考4. ssh——ssh登录配置docker容器的别名和免密登录。

小Tips
如果apt-get下载软件速度较慢,可以参考清华大学开源软件镜像站中的内容,修改软件源。

创建作业 & 测试作业的正确性

homework 8 create 可以重新创建所有lesson_8的作业
homework 8 create id 可以单独创建lesson_8的第id个作业. e.g.
homework 8 create 0 可以只重新创建lesson_8的第0个作业
homework 8 test 可以评测lesson_8的所有作业

作业

注意: 本次作业的3个题目不是独立的,每个题目会依赖于前一个题目,因此评测时如果当前题目错误,则不再评测后续题目。

创建好作业后,先进入文件夹/home/acs/homework/lesson_8/,然后:

  • (0) 进入homework_0文件夹,然后:
    [1] 租一台云服务器
    [2] 配置服务器别名及免密登录
    [3] 将服务器别名写在当前目录下的server_name.txt文件中
  • (1) 进入homework_1文件夹,然后:
    [1] 在租好的云服务器中安装docker
  • (2) 进入homework_2文件夹,然后:
    [1] 将AC Terminal中的/var/lib/acwing/docker/images/docker_lesson_1_0.tar镜像上传到租好的服务器中
    [2] 登录到租好的服务器
    [3] 将上传的镜像提取出来
    [4] 创建该镜像的容器,设置端口映射:20000:22
    [5] 去云平台控制台中修改安全组配置,放行端口20000
    [6] 进入该容器,创建新账户acs
    [7] 返回AC Terminal。配置容器中acs账户的别名及免密登录。
    [8] 将别名写在当前目录下的server_name.txt文件中

AcWing Linux基础课相关推荐

  1. Acwing - Linux基础课(九)- docker教程

    文章目录 镜像 容器 实操练习 本节课是关于搭建docker环境,使用docker的好处是方便迁移. docker基本概念 镜像(images) 相当于一个模板.每个镜像由(名称+版本号)唯一标识 容 ...

  2. 算法与数据结构模版(AcWing算法基础课笔记,持续更新中)

    AcWing算法基础课笔记 文章目录 AcWing算法基础课笔记 第一章 基础算法 1. 排序 快速排序: 归并排序: 2. 二分 整数二分 浮点数二分 3. 高精度 高精度加法 高精度减法 高精度乘 ...

  3. 背包四讲 (AcWing算法基础课笔记整理)

    背包四讲 背包问题(Knapsack problem)是一种组合优化的NP完全问题.问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高 ...

  4. AcWing算法基础课 第一讲小结(持续更新中)

    目录 前言 一.快速排序法及其扩展 快速排序法 介绍 思路 + 步骤 模拟代入 模板 练习 扩展(求第k个数) 思路 代码 二.归并排序法 归并排序 思路 思路 + 步骤 模拟代入 模板 练习 应用( ...

  5. AcWing 算法基础课第三节基础算法3 双指针、位运算、离散化、区间合并

    1.该系列为ACWing中算法基础课,已购买正版,课程作者为yxc 2.y总培训真的是业界良心,大家有时间可以报一下 3.为啥写在这儿,问就是oneNote的内存不够了QAQ ACwing C++ 算 ...

  6. AcWing 算法基础课第一节基础算法1排序、二分

    1.该系列为ACWing中算法基础课,已购买正版,课程作者为yxc 2.y总培训真的是业界良心,大家有时间可以报一下 3.为啥写在这儿,问就是oneNote的内存不够了QAQ ACwing C++ 算 ...

  7. ACwing算法基础课全程笔记(2021年8月12日开始重写+优化)

    更好的阅读体验 ※基础模板 2021年8月12日开始对基础课笔记进行重写+优化 请大家支持AcWing正版,购买网课能让自己获得更好的学习体验哦~ 链接:https://www.acwing.com/ ...

  8. AcWing算法基础课第一讲(2):高精度加减乘除、前缀和、差分

    文章目录 1. 高精度加法 2. 高精度减法 3. 高精度乘低精度 4. 高精度除以低精度 5. 一维前缀和 6. 二维前缀和 7. 一维差分 8. 二维差分 1. 高精度加法 这里讲解两个大整数的加 ...

  9. 动态规划DP题单 AcWing算法基础课 (详解)

    目录 背包问题 背包问题初始化总结 AcWing 2. 01背包问题 AcWing 3. 完全背包问题 AcWing 4. 多重背包问题 AcWing 5. 多重背包问题 II AcWing 9. 分 ...

最新文章

  1. android之APP模块编译
  2. 如何让 PPT 像 PyeCharts 一样炫酷?
  3. c语言队列ADT 学习总结
  4. 官网下载历史版本的tomcat
  5. 2016奇虎360研发工程师内推笔试编程题 - 题解
  6. WYSE POCKETCLOUD手把手教你如何用手机遥控你的电脑!!(转)
  7. 类和对象10:对象访问方法
  8. Android4.4电池电量命令行查看
  9. 【Vue 4 笔记 】(一)
  10. sw转cad映射文件_SW转CAD图层映射
  11. Lisa新歌破吉尼斯世界纪录,MV播放量7460万,中国粉丝贡献大
  12. 弦振动 matlab,弦振动规律和MATLAB数据处理.doc
  13. idea引入maven依赖飘红解决方法
  14. Linux操作系统核心部分——内核
  15. 干货 | 机器学习模型在携程海外酒店推荐场景中的应用
  16. 啊哈C语言 第六章 【代码】【习题答案】
  17. 8月5日 网工学习 CRC校验码 HDLC协议
  18. 5G时代 ,物联网技术赋能智慧医疗
  19. 逆向破解之160个CrackMe —— 008-009
  20. 在html中打出一条虚线

热门文章

  1. C# Modbus-TCP信捷plc取数应用篇(二)
  2. html5 th左对齐,HTML5 教程之HTML th 标签
  3. v-model的理解
  4. r7 3750h和r5 3550h的差距 r7 3750h和r5 3550h哪个好
  5. 印象笔记如何设置默认笔记本
  6. oracle分区名称能不能相同,Oracle分区介绍
  7. 26日大型招聘会的单位名单·一片茫然加混乱
  8. 易语言高级表格写入MYSQL_易语言数据库与高级表格思路分析.doc
  9. MySQL基础篇(一)-- SQL基础
  10. MySQL-插入、更新与删除数据