2023年11月27日发(作者:)

AcWing—tmux,vim,Linux基础课,shell,命令

catalog

vim

`ggdG` 剪切所有内容

gg=G ' 格式化代码 '

u ' 撤销 '

v ' 然后, 按⽅向键, 进⾏⽂本的选中 '

y ' 复制 所选中的内容. yyank复制 (⽆法复制出来, 即仅限于vim)'

yy ' 复制⼀⾏ '

p ' 粘贴 paste '

:set paste ' 当你要shift+insert, vim 粘贴进⼀些⽂本时, 要设置这个模式; 否则你的⽂本, 和他原来的格式 不⼀样 '

:set nopaste ' 绝⼤多数下, 都是使⽤这个模式 (默认vim也是这个模式); 只有当你要粘贴时, 设置paste, 粘贴完毕, 就设置回去nopaste '

/abc '查找 找所有`abc`字符串(按回车后,按`n` 可以进⾏迭代) '

解释paste模式

int x;

a

b

当你在的后⾯, 按下回车时, 你肯定是希望光标在 这就是模式, 即他会⾃动给你缩进

;a nopaste

但是, 当你要粘贴⽂本时, 你肯定不希望, 在你⽂本中的 每个’n’后⾯, 都新加⼀个. 即让⽂本按照本来的样⼦来粘贴, 这就是

tab缩进paste

模式

tmux

tmux ' 打开⼀个新的tmux '

tmux a ' 打开之前挂起的tmux (即恢复你之前的那些分屏状态) '

ctrl + a, shift + 5 ' 左右分屏 '

ctrl + a, shift + " ' 上下分屏 (注意, 是引号键)'

ctrl + a, ⽅向键 ' 切换视图 '

ctrl + d ' 删除tmux, 退出; '

ctrl + d, a ' 挂起tmux, 退出; [ctrl+d, a]是保存tmux 退出, 然后[tmux a]是恢复之前的tmux状态 '

'⽐如你当前有很多的分屏, 你想要保存下来, 明天继续 '

ctrl + a, s ' 查看所有挂起的tmux (即被ctrl+d) '

然后, 选中某个, x y ' 删除某个tmux; 按下x, 下⾯命令⾏会提⽰ 是否删除'

ctrl + a, z ' 全屏/取消全屏 '

直接⿏标左击选中(复制)

ctrl + a, ] ' 粘贴, 但只能在tmux⾥粘贴 '

按住shift选中, ctrl+insert ' 也会选中其他tmux, 最好提前给ctrl+a,z 全屏'

shift + insert ' 粘贴 '

Shell

linux中常见shell有:

shbash(sh的加强版, 默认)

shell⽂件⾥的代码,都可以直接放到你的命令⾏⾥执⾏!! ⼀样的,只是写成⽂件,每次可以⾃动的执⾏。

source引⼊头⽂件

类似于C语⾔, 我们提前写好⼀些 代码, 然后其他的sh 就可以直接的引⼊. (其实和C语⾔⼀样, 就是代码⽂件的展开)

a.sh:

var=123

b.sh:

source /home/acs/a.sh ' source也可以写成: . '

echo ${var}

终端terminal是⼀个 (⼤的 bash脚本⽂件), 我们登陆时, 他会模式先执⾏( )⾥的所有内容

/home/acs/.bashrc

⽽这个⽂件, 他并不是⼀个, 执⾏权限也没有.

.sh⽂件x

这个命令, 是不可⾏的.

./bashrc

但是, 这个⽂件⾥, 都是shell命令!! (⽐如, ⼀些, 都可以在shell执⾏的)

ls, dir, ...

此时, 就可以使⽤ (⽂件内容展开) 这个功能.

即把该⽂件的内容, 都展开到 (当前terminal)⾥, 也就是: ==该⽂件⾥的代码, 都执⾏了⼀遍 ==

⽐如:

⾥是: dir

./ 是失败的. (他没有+x权限)

source dir

就等价于 (执⾏了), 因为把⾥的内容, 展开到当前命令⾏⾥

重定向

linux所有进程, 默认都会打开 3个 ⽂件描述符: (stdin , 从命令⾏输⼊) (stdout , 向命令⾏输出) (stderr , 向命令⾏输出错误)

012

dir > a.txt ' dir的输出, (覆盖⽅式) '

ls >> a.txt ' ls的输出, (追加append⽅式) '

read var < a.txt ' , (读⼀⾏) 因为, read遇到(n)就结束 '

函数

func(){

a="abc"

echo "hello ${a}"

}

func ' 函数的调⽤, 不⽤写参数 '

func(){

a="abc"

echo ${a}

return 123 ' shell⾥的函数, 返回值是(exit code,[0,255]之间) '

' ⼀般, 0为表⽰成功(你不写,默认是他) '

'因为, 没有函数返回值这个概念, 所以, 如果要获取返回值, 你可以规则 ⽤他的stdout(echo) '

}

output=$(func) ' output == "abc" '

ret=$? ' ret == 123 '

for/while循环/continue

for i in 123 abc 456 ' 类似于c++ 序列化容器 '

do

echo ${i}

done

-----------------

for i in $(ls) ' 命令的输出 '

do

echo ${i}

done

--------------------

for i in $(seq 1 10) ' 遍历 [1,...,10] '

do

..

done

----------------

for i in {1..10} ' 遍历[1,...,10] ;'

for i in {10..1} ' 遍历[10,9,...,1] '

for i in {a..z} ' 遍历[a,b,..,z] '

--------------

for ((i=1; i<=10; ++i)) ' 遍历 [1,...,10] '

...

while read a ' 当你ctrl + d, 就是⽂件结束符. 即终⽌录⼊ '

do

echo ${a}

done

-------------------------

for ((i=1; i<=10; ++i))

do

if [ $( expr ${i} % 2 ) -eq 0 ] ' 跳过所有的 偶数 '

then

continue

fi

echo ${i}

done

#! /bin/bash

开头 必须要写上: ,这是在指明(使⽤bash作为 脚本解释器)

#! /bin/bash

chmod

chmod: change mode 改变模式

⼀个执⾏⽂件`a.sh`,需要有(执⾏的权限): `chmod +x a.sh`

注释

# ...

条件if

if

if [ ${a} -lt ${b} ]

then ' 注意这⾥有个then, 其实就表⽰: 如果这个if成⽴,... '

echo "a < b"

else

echo "a >= b"

fi

取反

if ! [ ${a} -eq ${b} ] ' 取反: ! '

then

echo ""

if

elif

if [ .. ]

then

...

elif [...]

then ' 注意格式!! '

...

else

...

fi

expr

length

expr length "${var}"""

,求⼀个字符串的长度 (加,是处理 var⾥有空格的情况)

四则运算

v1=123

v2=456

echo ${v1+v2} ' 输出是出错的! '

shell是不⽀持运算的!!

v1=123

v2=456

echo $(expr ${v1} + ${v2}) ' 注意, +的左右 要有空格!! '

echo $(expr ${v1} - ${v2}) ' -号,左右要有空格! '

echo $(expr ( ${v1} + 1 ) * ${v2}) ' *号要转义(*)!! 括号也要转义!! '

⽐较

v1=123

v2=456

echo $(expr ${v1} '==' ${v2}) ' 判断是否相等 (注意,要⽤单引号括起来) '

echo $(expr ${v1} '<' ${v2})

字符串、变量

var="abc"

var='abc'

var=abc

三种写法都可以,注意:等号左右,不可以有空格!!

写法,不会转义!! 写法,会进⾏转义!)

''""

shell⾥不存在(数据类型)的概念,即都是“字符串”!! (但他会⾃动检测,当需要是整数时,他会⾃动转换)

shell⾥的变量, 不存在 (定义)这个含义.

⽐如你 , 即使他不存在, 也不会报错, 他的值是空的.

echo ${a}

空格

var="abc ef"

echo ${var}

这是会报错的

但是,并不是说,var不能存储空格! ⽽是,操作 其实就会变成:

${var}abc ef

即,其实是形如: ,这是报错的!!

echo abc ef

所以,在对字符串进⾏操作时, 最好要加上 (可以处理,有空格的情况)

""

即,,这就对了

echo "${var}"

只读变量

var="abc"

readonly var

var

只读,不可以修改

全局变量

export varvar

: 所谓“全局”,指的是 “进程”!! 即,当前进程的 ⼦进程,可以访问到(当前进程⾥的

export var=123

: 声明⼀个全局变量

打印

echo

输出到屏幕

取字符串/数组 的长度

var="abc"

echo ${#var} ' 会输出: 3 '

字符串切割

${var:0:2}var[0, 1]

, 和substr的功能⼀样,即⼦字符串

脚本参数

echo ${0}

echo ${1}

echo ${2}

echo ${3}

当执⾏:,会输出:

./ 1 2 3./ 1 2 3

当执⾏:,会输出:

/home/wc/ 1 2 3/home/wc/ 1 2 3

(即,你命令⾏是怎么执⾏的这个sh⽂件, 就对应⼏个参数)

echo $#1, 2, 3

,表⽰,你传⼊的(参数个数)输出参数个数(不包括第⼀个参数) (⽐如上⾯命令, 你传⼊了: 共3个)

进程id

$$

当前进程id

获取(命令)返回值

echo $(ls) 等价于 echo `ls` ' 输出: ls的结果 '

注意,是,不是

$()${}

数组

arr=(123 "abc")

以上写法,完全等价于:

arr[0]=123

arr[1]="abc"

--------------------------

获取元素: ${arr[0]}

---------------------------

arr[0]=1

arr[5]=5

arr[10]=10

${arr[*]} ' 所有元素: 1 5 10 '

${#arr[*]} ' 数组长度: 3 '

可以发现,shell⾥的数组,有点像是: map的感觉!!

linux⽂件系统

bin

常⽤的 可执⾏⽂件的 命令

etc

放配置。⽐如,代理服务器nginx,他的配置,都是在etc⾥⾯。

var

⽐如,⽇志log,会放到这⾥。

lib

⽐如,C++的头⽂件,会在这⾥

home

所有的⽤户,都会在这⾥

proc

⽐如,他⾥⾯有⼀个,存的是(cpu的信息)

cpuinfo

命令

进程

top : 动态

ps aux: 静态

kill -9 PID: 杀死⼀个进程

ctrl + c/d

ctrl + c: 终⽌(杀死) 进程!!

ctrl + d: ⽂件结束符 (read会终⽌)

seq

seq -3 3 ' 返回: [-3, -2, -1, 0, 1, 2, 3] '

read/echo

read a ' 等价于: cin ' ' 结束符是: ctrl + d '

echo ${a} ' cout, 但是, 会⾃动换⾏!! '

echo -e "abc c" ' -e是开启(转义), '

echo "a b" > a.txt ' 以覆盖⽅式, 重定向 '

data

data ' ⽇期 '

bash

在当前的 terminal的基础上,再开⼀个bash!(新开的bash,是当前bash的 “⼦进程”)

exit

,退出新开的bash(⼦进程)

选中、复制、粘贴

在shell⾥,⿏标、以往的是不顶事的!

ctrl+c

(选中): 按住,⿏标左击

shift

(复制):

ctrl + insert

(粘贴) :

shift + insert

touch

touch

创建⽂件

ls

ls | wc -l

所有 (⽂件 + ⽂件夹)的 个数

ls -l

所有(⽂件夹 和 ⽂件)的详细信息

ls -a

包括(隐藏⽂件)

cp

复制 ⽂件

cp ./dir1/ ./dir2./dir2

此时,有⼀个(复制操作)

cp ./dir1/ ./dir2/./dir2

此时,有⼀个(复制 + 重命名操作)

cp

(把当前⽬录下的a,复制⼀份,命名为b)

复制 ⽂件夹

cp ./dir1 ./dir2 -r

(把dir1的所有东西,复制到dir2⾥)

mkdir

mkdir /dir

(创建⽂件夹)

mv

mv

(重命名操作)

cat

cat

(输出⽂件内容)

rm

rm *.txt*.txt

(删除当前⽬录所有

rm * -r

(删除当前⽬录下,所有的 “⽂件夹 + ⽂件”)

history

history

(展⽰,所有你使⽤过的 命令)

tmux

功能:

分屏

允许断开terminal后,继续运⾏进程

你在tmux⾥的命令等,会存到服务器⾥。 即使你本机terminal关闭或断⽹了,重新打开terminal,他还是会恢复的

⼀个tmux⾥,可以包含有多个session

⼀个session,可以包含有多个window

⼀个window,可以包含有多个pane

tmux命令也就是分屏

: 新建⼀个session (其中会包含⼀个window,window⾥包含⼀个pane,pane⾥包含⼀个shell对话框)

、、、、如果已经在tmux模式下,则该命令就失效(因为,⼀个session下 ⽆法再创建⼀个session)

、、、、(⽐如,普通shell 和 tmux模式,长相是⼀样的,如何区分 当前是否是在tmux模式呢? 就可以输⼊命令,看他能否创建⼀

tmux

个tmux)

在tmux模式⾥: 将当前pane,分成左右2个 (分屏

ctrl+a,然后松开,shift+5

在tmux模式⾥: 将当前pane,分成上下2个 (分屏

ctrl+a,然后松开,shift+"

在tmux模式⾥: 关闭(删除)当前的分屏(如果是最后⼀个tmux,则退出tmux模式)

ctrl+d

ctrl + a,然后,⽅向键

在多个分屏中,切换

ctrl + a, 然后,d

挂起当前的session

tmux a(ttach)

回到 刚才挂起的session

在tmux⾥的(任意⼀个session⾥) 查看并选择所有的session

ctrl + as

⼀般常⽤的是:

tmux 新开⼀个tmux a 回到⼀个tmuxctrl d, 关闭

vim

(默认模式)

输⼊,进⼊(⽂本编辑模式)

i

输⼊ 进⼊(命令⾏模式)

: ? /

G3G (3, 然后, shift+g)gg = 1G3回车

到最后⼀⾏, 到第3⾏ (,到第⼀⾏), 向下⾛3⾏

(⽂本编辑模式)

,进⼊(命令⾏模式)

esc

(命令⾏模式 “光标会出现在最下⾯”)

: set nu: set nonu

有⾏号、 ⽆⾏号

: wq

保存退出

/abcabcn

查找 找所有字符串(按“回车”后,按 可以进⾏迭代)

:a,bs/aaa/bbb/ga=1, b=$

替换:把第[a - b]⾏⾥的 “aaa”字符串,全部换成“bbb”(当时,表⽰“全⽂”)

、、在该命令最后,加上(即),则每⼀次的替换,需要你确定)

c/gc

v

选中

ddd

剪切(删除) 剪切当前⾏

yyy

复制, 复制⼀⾏

p

粘贴(在当前光标的“下⼀个位置” 粘贴:如果复制的是⼀⾏ 则在下⼀⾏粘贴,否则在右侧⼀个位置。。。奇怪)

u

撤销

:w:w!:q:q!:wq

保存, 强制保存, 退出,强制退出,保存退出

: set paste: set nopaste

设置为粘贴模式(取消 代码⾃动缩进功能)。 (开启 代码⾃动缩进)

ggdG

删除所有内容

输⼊后, 按(上下⽅向键),可以查看历史的命令

: / ?

如果⼀⾏内容很多,(home是开头,end是末尾)

gg=G

全⽂格式化

当vim在操作⽂件时,会创建(.swp)的临时⽂件。(当vim退出后,⽂件会删除掉)

.swp

-> ..

(注意,最前⾯有个

所以,当⼀个vim打开⼀个⽂件时,如果该⽂件,有⽂件;则会报错(因为,已经有个进程A打开了该⽂件)

.swp

(此时,有2种⽅式: 要么关闭进程A,要么删除swp⽂件)