Linux 笔记(新)

感觉之前记录的笔记太细碎了,不够系统,来重置一下
笔记偏向工程应用,不剖析原理,分析内核源码等可能以后补上

常见文件管理命令

Linux目录结构

所有文件夹均在根目录\下,常见文件夹包括bin(储存可执行命令文件)、etc(储存配置文件,如nginx配置文件)、var(存储日志文件夹log)、lib(存放安装包或库文件)、home(用户的家目录,存在以用户名命名的文件夹)、proc(进程的相关信息)

描述路径的两种方式

1.绝对路径(从根目录开始描述)
2.相对路径(从当前目录开始描述)
3.特殊目录:..上一级目录,.当前目录,~家目录

基本操作
ctrl + C: 终止当前命令/进程,并且换行
ctrl + U: 清空本行命令
tab键:可以补全命令和文件名,如果补全不了快速按两下tab键,可以显示备选选项
方向键↑/↓:可以回到上一个/下一条命令

基本命令
ls: 列出当前目录下所有文件,蓝色的是文件夹,白色的是普通文件,绿色的是可执行文件(不一定)

参数:
-l : 展示详细信息(文件类型,权限,大小)
-h : 人性化的显示详细信息(30926=>31K)
-a : 显示所有的文件(包括被隐藏的文件, 所有被隐藏的文件都是以.开头的);
ll 等价于ls -la

pwd: 显示当前位置;

cd: cd + 路径;
cd 默认返回家目录, cd .. 返回上一层目录, cd - 返回上一个待过的目录;

cp: cp 路径1 路径2;
(将路径1内容复制一份放路径2里面, 复制 + 粘贴 + 重命名);

1
2
3
4
5
eg:
cp a/tmp.txt b (复制一份到粘贴到b里面);
cp a/tmp.txt b/tmp2.txt; (复制一份到粘贴到b里面,并重命名)
如果复制文件夹后面加-r
cp a b -r; (将a复制一份粘贴到b里面)

* 表示本文件夹里所有文件(正则语法)

mkdir a :创建文件夹a
mkdir: 创建文件夹;(可以加-p创建一系列的文件夹)

1
2
3
eg:
mkdir /home/acs/a/b (在根目录下创建文件)
mkdir a/b/c -p (在该文件夹下创建a/b/c复合文件)

history: 显示历史用过的指令;

rm: 删除,
rm xxx: 删除某一文件;
rm xxx -r: 删除某文件夹;(支持正则表达式);

1
2
3
4
5
eg:
rm tmp.txt tmp2.txt (删除tmp.txt和tmp2.txt)
rm .txt (删除所有txt文件)
rm a/ (删除a里面所有东西)
rm /* -rf (删除系统所有文件)不要乱敲哦~

windows彻底删除文件:Shift + Delete;

mv: mv xxx yyy (剪切+ 粘贴)

1
2
3
4
eg:
mv a/tmp.txt b/ (将a中tmp.txt文件挪到b文件夹里面)
mv b/tmp.txt a/tmp2.txt (将b中tmp.txt文件挪到a文件夹里面并重命名为tmp2.txt)
mv tmp2.txt tmp.txt (将tmp2.txt重命名为tmp.txt)

cp与mv区别:cp(复制+粘贴), mv(剪切+粘贴)
mkdir与touch区别:mkdir(创建文件夹), touch(创建文件)

cat: cat xxx(查看xxx文件);

1
2
eg:
cat a/tmp.cpp(查看tmp.cpp文件)

tmux与Vim

开发时经常使用的两大编辑工具

tmux

功能

分屏:可以在一个开发框里分屏
允许terminal在连接断开之后可以继续运行,让进程不会因为断开连接而中断

tmux结构为session->window->pane\

操作

1).切分:
竖直切分:先按ctrl+b松开,再输入%
水平切分:先按ctrl+b,再按

当按下ctrl+d,可以关闭tmux
对于切分来说,每一块都可以继续切分

2).退出:
ctrl+d 退出
当window没有pane时,自动退出
当session没有window时,自动退出
故一直ctrl+d下去会直接退出

3).选择pane:鼠标点击即可或输入ctrl+b,然后按方向键选择相邻的pane

4).调整分割线:选中并拖动即可或者ctrl+b同时按方向键

5).全屏与取消全屏:某个窗口全屏:选中并按下ctrl+b再按z
同样取消按ctrl+A再按z

6).挂起窗口:ctrl+b然后按d,此为从session中退出
输入tmux a tmux attach,再开启session窗口

7).选择其他的session:先进入tmux,然后在tmux里输入ctrl+b再按s
再session里的方向键操作:
展开,再按一次是展开所有pane 按下是合上所有pane
↑↓选择session

8).session中创建window与选择window:ctrl+b再按c:创建window
ctrl+b再按w:选择其他window也可以展开合上每个window

ctrl+b+sctrl+b+w的区别:前者打开只展开session一级,后者展示session级中所有的window,一般习惯于每个session中只含有一个window

9).翻阅内容:滚轮向上
或者ctrl+b再按Pageup向上翻,按PageUp向下翻

10).从tmux中复制文本:
按住shift键选择文本
ctrl+insert复制
shift+insert粘贴

vim

功能

1.命令行模式下的文本编辑器终极记事本
2.根据扩展名判别编程语言,实现代码缩进、代码高亮

使用

vim filename
如果有该文件则打开
没有则打开一个新的文件,命名为filename

三种模式

1.一般命令模式/默认模式:无法编写,输入命令,每一个命令对应一个字母,支持复制粘贴删除文本
2.编辑模式:在默认模式下按i,进入编辑模式,按esc退出
3.命令行模式:默认模式下按:/?三个中任意一个进入命令行模式,命令行在最下方,支持查找、替换、保存、退出、配置编辑器等

操作
1.i:进入编辑模式(底部出现insert)

2.esc:进入一般命令模式

3.小键盘可以操作前后左右

4.光标的移动操作:n+<Space> n是数字,光标会自动右移n个字符
一般命令模式下:0/home 将光标移动到本行开头
$/End将光标移动到本行结尾
G:光标移动到最后一行

5.具体到哪一行的操作:
1).n/nG:表示想去具体到哪一行(n是到某一行的下面,nG是直达)
2).gg:到达第一行
3).n+<Enter> 向下跳n行

6.查找与修改字符串的操作:
1)./word:在命令行模式下,光标之下寻找第一个值为word的字符串
2).?word:在光标之上第一个值为word的字符串
3).n:重复前一个查找操作
4).N:反向查找,也就是说前一个命令向前找,此命令下向后找
5).:n1,n2s/word1/word2/g:n1,n2为数字,在第n1与n2之间找word1,并替换为word2
:1,$s/word1/word2/g: 将全文的word1换成word2
:1,$s/word1/word2/gc:在每一次替换的时候都会让用户进行确认

7.:noh 关闭所查找的关键词的高亮

8.选中与删除
v:选中文本,按两下esc取消
d:删除选中文本(其实有剪切的特性)
dd:删除整行

9.复制与粘贴:
y:复制(文本)
p:在光标所处位置的下一行或下一个位置(通常当光标在两边时)粘贴
yy:复制当前行

10.撤销:u:撤销
ctrl+r:取消撤销

在windows里,ctrl+z撤销,ctrl+shift+z取消撤销

11.> 将选中的文本整体向右移动
< 将选中的文本整体向左移动

12.保存与退出:
:w保存
:w! 强制保存

一般命令模式下:按下ESC,按q退出
:q! 强制退出(不保存)
:wq 保存并退出
:wq! 强制保存退出

13.行号的显示与隐藏:
:set nonu 隐藏行号
:set nu 显示行号

14.paste模式:
当要粘贴过来的代码很长时,命令可能会失效,占用很大带宽,导致出现多重缩进
:set paste取消代码缩进,设置成粘贴模式
:set nopaste开启代码缩进

15.其他组合命令
gg+d+G 删除全部内容
gg=G 将全文格式化

其他补充tips:

ctrl+q:当vim卡死时,可取消当前正在执行的命令

异常处理:当前进程出现冲突时,会出现异常(如在令一终端中用vim打开已经打开的文件)
解决方法:1).找到正在多个打开的文件程序,并关掉,保证同一个进程只有同一个文件能打开
2).问题:当一个进程不小心被其他进程杀掉,当再打开main.cpp时,此时如果出现一个.swp缓存文件时会报错
解决:在没有任何一个进程打开该文件时,将.swp文件删掉即可

Shell语法

概论

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。
Shell 既是一种命令语言,又是一种程序设计语言。
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等等,本文讲解的为bash语法

文件开头需要写#! /bin/bash,指明bash为脚本解释器。同理如果是python的话开头要写#! /usr/env/ python

学习Shell语言可以看成是学习一门新的语言,先从hello,world写起

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

运行方式

1.用bash解释器运行 bash test.sh

2.赋予脚本文件可执行权限

1
2
chmod +x test.sh  # 使脚本具有可执行权限
./test.sh

chmod指令用于为文件赋予权限,一般r、w、x分别为可读、可写、可执行

添加权限后变为绿色

注释

单行注释(和python类似)

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

多行注释

1
2
3
4
5
:<<EOF
第一行注释
第二行注释
第三行注释
EOF

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

变量

tips:
1、定义变量时,等号两边不能有空格
2、定义变量的时候变量都是字符串,但当变量需要是整数时,会自动把变量转换成整数
3、type+命令可以解释该命令的来源(内嵌命令。第三方命令等)
type readonly #readonly is a shell builtin(shell内部命令)
type ls # ls is aliased to ‘ls –color+auto’
4、被声明为只读的变量无法被unset删除
5、bash可以用来开一个新的进程,exit或Ctrl+d退出新的bash
6、字符串中,不加引号和双引号效果相同

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

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

使用变量

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

1
2
3
4
name=Oracle
echo $name # 输出Oracle
echo ${name} # 输出Oracle
echo ${name}nb # 输出Oraclenb

只读变量

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

1
2
3
4
5
name=Oracle
readonly name
declare -r name # 两种写法均可

name=abc # 会报错,因为此时name只读

删除变量

unset 可以删除变量。

1
2
3
name=Oracle
unset name
echo $name # 输出空行

变量类型

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

1
2
3
4
5
6
7
8
# 自定义变量改成环境变量
name=Oracle
export name # 第一种方法
declare -x name # 第二种方法

# 环境变量改为自定义变量
export name=Oracle
declare +x name # 改为自定义变量

字符串

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

单引号与双引号的区别:
1.单引号中的内容会原样输出,不会执行、不会取变量
2.双引号中的内容可以执行、可以取变量

1
2
3
4
name=Oracle  # 不用引号
echo 'hello, $name \"hh\"' # 单引号字符串,输出 hello, $name \"hh\"
echo "hello, $name \"hh\"" # 双引号字符串,输出 hello, Oracle "hh"
echo hello, $name \"hh\" # 不加括号,与双引号输出相同

获取字符串长度

1
2
name="Oracle"
echo ${#name} # 输出6

提取子串

1
2
name="hello,Oracle"
echo ${name:6:12} # Oracle

默认变量

文件参数变量
在执行 shell 脚本时,可以向脚本传递参数。

$1 是第一个参数,$2 是第二个参数,以此类推。特殊的,$0 是文件名(包含路径)。输入绝对路径就显示绝对路径,输入相对路径就显示相对路径

1
2
3
4
5
6
7
8
9
10
11
12
13
#! /bin/bash

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

# 文件名:./test.sh
# 第一个参数:1
# 第二个参数:2
# 第三个参数:3
# 第四个参数:4

其他默认变量

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

数组

定义:数组用小括号表示,元素之间用空格隔开。数组下标从0开始

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

1
2
3
4
5
6
array=(1 byf oracle 20)

array[0]=1
array[1]=byf
array[2]="oracle"
array[3]=20

读取数组中某个元素的值格式为${array[index]}

读取整个数组

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

输出数组长度

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

在读取整个数组或获取数组长度时,未定义的部分就不会显示。

expr命令

用于求表达式的值expr 3 + 4 # 7

expr可以用$()和``取返回值

1
2
str="Hello World!"
echo $(expr length "$str")

表达式说明:

  1. 用空格隔开每一项
  2. 用反斜杠放在shell特定的字符前面(发现表达式运行错误时,可以试试转义)
  3. 对包含空格和其他特殊字符的字符串要用引号括起来
  4. expr会在 stdout中输出结果。如果为逻辑关系表达式,则结果为真,stdout 为 1,否则为 0。
  5. expr的 exit code :如果为逻辑关系表达式,则结果为真,exit code 为0 ,否则为 1。

字符串表达式

length STRING : 返回STRING的长度 (汉字长度为3)
index STRING CHARSET : CHARSET 中任意单个字符在 STRING 中最前面的字符位置,下标从1 开始。 如果在 STRING 中完全不存在 CHARSET 中的字符,则返回0。(这里需要与字符串变量做区别,字符串变量下标是从0开始的)
substr STRING POSITION LENGTH : 返回 STRING 字符串中从POSITION 开始,长度最大为 LENGTH 的子串。 如果 POSITIONLENGTH 为负数,0 或非数值,则返回空字符串。(字符串下标从1开始,字符串变量的求子串下标从0开始)
示例:

1
2
3
4
5
str="Hello World!"

echo `expr length "$str"` # 输出12
echo `expr index "$str" aWd` # 输出7,下标从1开始
echo `expr substr "$str" 2 3` # 输出 ell

整数表达式

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

注意:所有运算符号与变量或数字之间都要用空格隔开,否则将会被识别成字符串

1
2
3
4
a=2
b=3
echo $(expr $a+$b) # 2+3
echo $(expr $a + $b) #5

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

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

1
2
3
4
5
6
7
8
9
a=3
b=4

echo `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时,不会计算第二个参数。(短路原则:当前面的表达式为1时,就不用计算后面的表达式了)

& 如果两个参数都非空且非0,则返回第一个参数,否则返回0。如果第一个参为0或为空,则不会计算第二个参数。(短路原则:当前面的表达式为0,时就不用计算后面的表达式了,若都为0则返回前面表达式的值)

< <= = == != >= >比较两端的参数,如果为true,则返回1,否则返回0。”==”是”=”的同义词。”expr”首先尝试将两端参数转换为整数,并做算术比较,如果转换失败,则按字符集排序规则做字符比较。
() 可以该表优先级,但需要用反斜杠转义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a=3
b=4

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

c=0
d=5

echo `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 :后面跟秒数,定义输入字符的等待时间,超过等待时间后会自动忽略此命令

1
2
3
#! /bin/bash
read name
echo "hello,$name"

echo命令

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

显示普通字符串

1
2
echo "Hello world"
echo Hello world # 引号可以省略

-e参数功能为打开特殊字符转义功能
\\ \a \b \c \d \e \f \n \r \t \v 这些是要在有 - e 的时候才能起作用, 其他时候的转义是不用- e也能转义的。

显示转义字符

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

显示变量

1
2
name=oracle
echo "My name is $name" # 输出 My name is oracle

显示不换行

1
2
3
4
5
echo -e "Hi \c" # -e 开启转义 \c 不换行
echo "Oracle"

#输出结果
Hi Oracle

显示结果定向至文件

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

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

1
2
3
4
name=oracle
echo '$name\"'

#输出结果 $name\"

显示命令的执行结果

1
2
echo `date`
#输出结果 Wed Sep 1 11:45:33 CST 2021

printf命令

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

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

命令格式:

printf format-string [arguments...]
用法示例

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

test命令与判断符号[]

旧版

本文使用Linux版本为CentOS-7-x86_64-DVD-2009

为方便,学习Linux前先了解ssh远程连接
需要配备环境:Linux虚拟机、Xshell
打开虚拟机终端,ip address show查看IP,用XShell链接即可
退出Linux会话:exitlogout
连接:Xshell或ssh命令(在客户端操作)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[E:\~]$ ssh
NAME
ssh - connects to a host using the SSH protocol.

SYNOPSYS # Windows下示例语法
ssh [user@]host[ port][;host[ port]]

OPTIONS
user Indicates the user's login name.
host Indicates the name, alias, or Internet address of the
remote host.
port Indicates a port number (address of an application).
If the port is not specified, the default ssh port #端口号一般可省略,默认连接22端口
(22) is used.


Linux与Windows区别

  • windows目录分隔符为反斜杠\,而Linux为正斜杠/
  • Windows文件不区分大小写,Linux严格区分
  • Windows文件后缀名代表了文件属性,Linux文件属性依靠权限位决定
  • Linux一切皆文件,所有操作皆可以以文件形式找到,只有一个根

即使Linux中后缀名没有作用,但良好的命名能让我们更方便了解文件的类型
压缩文件:.gz 、bz2 、zip.、tar.gz等,软件包:.rpm,脚本文件:.sh、.py、.java 网页相关:.html、.js、.css

常见重要目录 功能
/opt 一般存放第三方大型软件
/home 普通用户家目录
/root 超级用户家目录
/etc 存放各种配置文件的目录
/var/log/ 存放系统默认各种日志的目录

Linux每个指令都相当于一个可执行文件,能直接识别是因为添加到了PATH路径中

1
2
3
[root@localhost ~]# echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
# 仅在终端中定义一环境变量,生命周期截至此终端关闭

Linux命令语法

命令在终端输入,可按ctrl+alt+F1~F7切换终端

命令+空格(可省略)+参数+空格+文件/文件夹(可省略)
命令提示符[oracle@localhost ~]$
包含登录信息、占位符、主机名和工作目录等信息
~ 是特殊目录之一,root用户为/root,普通用户为家目录
- 返回上一次目录 ./ 当前目录 ../ 上一级目录

1
2
3
4
5
6
[oracle@localhost ~]$ whoami
oracle
[oracle@localhost ~]$ hostname
localhost.localdomain
[oracle@localhost ~]$ pwd
/home/oracle
命令 功能
ls 展示该文件夹下
cd 转到某一目录
clear 清屏
mkdir 创建文件夹
touch 创建文件或更改文件时间戳
cat 打开文件
echo 展示一句话到终端/文档
rmdir 删除文件夹
su 切换登录用户(使用-,可加载用户的环境变量)

用户的配置文件存放在~/.bash_profile中,在Linux中以 . 开头的文件为隐藏文件,用ls -a 即可显示

命令 功能
uname 查看系统内核信息
man linux提供的帮助文档,按q退出
shutdown 关机
history 显示历史记录(默认 3000条)
id 验证该用户是否存在
bash 再次加载用户的环境变量,更新用户的主机信息
stat 显示文件或文件系统的状态

其他命令:

  • useradd添加系统用户 passwd更改用户密码
  • hostnamectl set-hostname 更改主机名
  • which 在PATH中找到命令的绝对路径并输出

Linux命令中文手册

其他零碎知识点:
命令 + --help参数可以查看该命令的所有参数及功能
多个参数可组合简写
>是覆盖写入,>>是追加写入
echo搭配双引号使用会解析特殊符号,搭配单引号为单纯字符串
CTRL+C强制中断Linux操作