介绍linux 中常见的命令 和github 中常用的命令

Linux 常见命令

awk、grep、sed是linux操作文本的三大利器,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂,awk更适合格式化文本,对文本进行较复杂格式处理。grep更适合单纯的查找或匹配文本,sed更适合编辑匹配到的文本。

awk 取列数据

之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。AWK是一种处理文本文件的语言,是一个强大的文本分析工具。特点是处理灵活,功能强大。可实现统计、制表以及其他功能。

awk 基本语法:

1
awk 'BEGIN{} {command} END{}' filename

awk 是逐行处理文本内容的;BEGIN{} 是初识化代码块,在处理文件第一行内容之前,定义一些变量;{command} 为一些命令,对文件内容的每一行进行相应地处理; END{} 为结束代码块,在 {command} 运行结束后执行。

格式

1
2
3
4
命令行格式
awk [options] 'command' file(s)
脚本格式
awk -f awk-script-file file(s)

常用内置参数

1
2
3
4
5
$0,$1,$2... 表示整个当前行
$1 每行第一个字段
NF 字段数量变量
NR 每行的记录号,多文件记录递增
FILENAME 文件名

awk -F'\t' ‘{print $1;}’ all-test.txt > all_query.inc

AWK是一种处理文本文件的语言,是一个强大的文本分析工具。之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

awk 非常擅长处理结构化数据和生成表单.和 sed 和 grep 很相似.由于 awk 具备各种及哦啊本语言的特点,所以可以把它看做是一种脚本语言.

语法(有三种方式)

第一种方式:

1
awk [-F 分隔符] ‘commands’ input-file(s)

在 awk 中默认使用空格间隔; 如果文件中使用冒号作为分隔符,那么必须使用 -F 选项:

1
awk -F : 'commands' input-file

第二种方式

将所有 awk 命令插入一个单独文件,然后调用

1
awk -f awk-script-file input-file

常见的案例学习

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd

除了 awk 的内置变量,awk 还可以自定义变量.
例如:统计/etc/passwd 的行数:

awk '{count++}END{print count}' /etc/passwd

count 是自定义变量,这里没有初始化 count,虽然默认是 0,但是妥当的做法还是初始化为 0.

awk 'BEGIN{count=0}{count=count+1}END{print count}' /etc/passwd

例如:统计某个文件夹下的文件占用的字节数

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'

如果按照 M 为单位显示

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'

shell 学习十七天—awk 命令

解释:打印包含 MA 的行中的第一个单词。(使用 echo 关键字可以模拟读入文件的操作)

1
echo 'this is one world\nthat is another world' | awk '{print $1}'

关于 -F 的使用 (设置分割符)默认使用空格分割;如果是passwd 文件,那么使用冒号作为分割符。其中的 $1 表示第一个字段, $0 表示所有的字段。

1
awk -F : 'commands' input_file

按照 [] 进行切分,然后打印第1,2,和3 个字段。

1
awk -F '[\[\]]' '{print $1, $2, $3}' log.txt

在输出的时候,可以加上字符串和转义字符之类的, 注意加上的这些东西是使用双引号表示的。

1
awk '{print $1 "\t" $2 "\t" $3}' fruit.txt

同时处理多个文件

1
awk '{print FILENAME "\t" $0}' demo1.txt demo2.txt

在 awk 中使用变量

1
awk '{msg="hello world"; print msg "\t" $0}' log.txt

如果要判断文件的第 3 列数据,也就是平均工资小于 5500 的公司,然后将其打印输出

1
awk '$3 < 5500 {print $0}' company.txt

在 awk 中使用正则表达式

使用正则表达式匹配字符串 “There” ,将包含这个字符串的行打印并输出

1
awk '/There/{print $0}' poetry.txt

使用正则表达式配一个包含字母 t 和字母 e ,并且 t 和 e 中间只能有任意单个字符的行

1
2
3
4
5
awk '/t.e/{print $0}' poetry.txt

There is nothing either good or bad, but thinking makes it so
There’s a special providence in the fall of a sparrow
No matter how dark long, may eventually in the day arrival

这个cat 命令也是不太懂得

cat base_meta | python segmentor.py ~/default_query/data > base_meta.seg

常见的变量

变量NF表示当前行有多少个字段,因此$NF就代表最后一个字段。

1
2
$ echo 'this is a test' | awk '{print $NF}'
test
1
$(NF-1)代表倒数第二个字段。

print命令里面,如果原样输出字符,要放在双引号里面。

awk还提供了一些内置函数,方便对原始数据的处理。

函数toupper()用于将字符转为大写。

1
2
3
4
5
6
7
tolower():字符转为小写。
length():返回字符串长度。
substr():返回子字符串。
sin():正弦。
cos():余弦。
sqrt():平方根。
rand():随机数。

完整的built-in function 手册

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 输出奇数行
$ awk -F ':' 'NR % 2 == 1 {print $1}' demo.txt
root
bin
sync

# 输出第三行以后的行
$ awk -F ':' 'NR >3 {print $1}' demo.txt
sys
sync

下面的例子输出第一个字段等于指定值的行。

1
2
3
4
5
$ awk -F ':' '$1 == "root" {print $1}' demo.txt
root
$ awk -F ':' '$1 == "root" || $1 == "bin" {print $1}' demo.txt
root
bin

if else 语句

1
2
3
4
$ awk -F ':' '{if ($1 > "m") print $1}' demo.txt
root
sys
sync

上面代码输出第一个字段的第一个字符大于m的行。

awk 处理文本

awk、grep、sed是linux操作文本的三大利器,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂。grep更适合单纯的查找或匹配文本,sed更适合编辑匹配到的文本,awk更适合格式化文本,对文本进行较复杂格式处理。

grep 命令

grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
-d<进行动作> 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。

-h 当搜索多个文件时,不显示匹配文件名前缀

-i 忽略字符大小写的差别。

-l 列出文件内容符合指定的范本样式的文件名称。

-n 列出所有的匹配的文本行,并显示行号

-r  递归搜索,搜索当前目录和子目录,此参数的效果和指定“-d recurse”参数相同。

-v 反转查找。只显示不匹配的文本行

history | grep “ssh” # 在返回的结果中使用 grep 进行查找

sed 行编辑器

sed是一种流编辑器,它是文本处理中非常重要的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

常用的选项

1
2
-e<script>或--expression=<script>:以选项中的指定的script来处理输入的文本文件;
-n或--quiet或——silent:仅显示script处理后的结果;

常用的命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
a\ 在当前行下面插入文本。
i\ 在当前行上面插入文本。
c\ 把选定的行改为新的文本。
d 删除,删除选择的行。
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
s 替换指定字符
p 打印模板块的行。
q 退出Sed。
r file 从file中读行。
w file 写并追加模板块到file末尾。  

更多详细的例子 最好是动手试一下

sed 是以行为单位处理信息的,比如下面的命令可以输出第二行的信息:

1
ifconfig  enp9s0f1 | sed -n '2p'

inet 10.2.7.140 netmask 255.255.255.128 broadcast 10.2.7.255

同样使用 awk 也可以达到同样的效果, 使用NR 关键词。所以awk 相比于sed 是更加强大处理工具。

1
ifconfig em1 | awk NR==2

Linux系统拥有一个类似的工具,也就是ifconfig(interfaces config)。通常需要以root身份登录或使用sudo以便在Linux机器上使用ifconfig工具。依赖于ifconfig命令中使用一些选项属性,ifconfig工具不仅可以被用来简单地获取网络接口配置信息,还可以修改这些配置。

命令格式

ifconfig [网络设备] [参数]

命令参数

up 启动指定的网络设备/ 网卡 down 关闭指定的网络设备 / 网卡。该参数可以有效的阻止指定接口的IP 信息流,如果想要永久关闭一个接口,需要从路由器中将该接口的路由信息全部删除。

常见的名称

1
2
3
4
5
6
7
8
eth0 表示第一块网卡, 其中 HWaddr 表示网卡的物理地址,可以看到目前这个网卡的物理地址(MAC地址), inet addr 用来表示网卡的IP地址
lo 是表示主机的回坏地址,这个一般是用来测试一个网络程序,但又不想让局域网或外网的用户能够查看,只能在此台主机上运行和查看所用的网络接口。


#启动关闭指定网卡
ifconfig eth0 up
ifconfig eth0 down

关于上述三个命令的练习

awk 的练习题看上面的例子就行

强大的grep,sed和awk–用案例来讲解 更多sed 详细的例子 关于sed 的练习题

软链接 硬链接 和cp

ln -s 源文件 目标文件 做软链接

软链接:通过软链接建立的链接文件与原文件是同一个文件,相当于windows中的快捷方式。硬链接:一个文件可以拥有两个文件名,硬链接和原有的文件名是平等的,由于这个原因,硬链接不能连接两个不同文件系统上的文件。相反,软连接可以跨文件系统。

硬链接是以文件副本的形式存在,软连接可以用来解决空间不足的问题。

1
2
ln -s ~/sag_common/production/search/nlp/query_quality/src/libglog.so.0 /usr/lib6 #软连接
ln  ~/sag_common/production/search/nlp/query_quality/src/libglog.so.0 /usr/lib6 #硬链接

如果一个文件 aa.txt 来自windows 系统,那么使用

1
2
ln -s aa.txt /root/bb # 操作成功
ln  aa.txt /root/bb # 操作失败

ssh 远程登录的命令

ssh -i .ssh/qiso_id_rsa qiso@10.39.22.30

使用 exit 退出当前账户的ssh 登录

ssh -i .ssh/qiso_id_rsa zhlu@10.52.80.185 # 这个是有gpu 的机器

ssh -i .ssh/qiso_id_rsa qiso@10.39.22.30 # 这个应该是hadoop 的机器

所以现在一共有三个机器,一个是我账户下的机器,一个是 gpu机器,一个是qiso 的机器

本机:

1
2
ssh_config是针对客户端的配置文件
sshd_config是针对服务器的配置文件

设置过期时间

方案一:在客户端设置 /etc/ssh/ssh_config 此后该系统里的用户连接SSH时,每60秒会发一个KeepAlive请求,避免被踢。

1
ServerAliveInterval 60 

方案二:在服务器端设置 /etc/ssh/sshd_config

1
ClientAliveInterval 60

配置服务器的ssh

只允许指定用户进行登录(白名单):在/etc/ssh/sshd_config配置文件中设置AllowUsers选项,(配置完成需要重启 SSHD 服务)格式如下:

  • 配置白名单
1
2
AllowUsers    aliyun test@192.168.1.1            
# 允许 aliyun 和从 192.168.1.1 登录的 test 帐户通过 SSH 登录系统。
  • 或者配置黑名单 只拒绝指定用户进行登录(黑名单): 在/etc/ssh/sshd_config配置文件中设置DenyUsers选项,(配置完成需要重启SSHD服务)格式如下:
1
2
DenyUsers    zhangsan aliyun    #Linux系统账户        
# 拒绝 zhangsan、aliyun 帐户通过 SSH 登录系统
  • 重启ssh
1
service sshd restart

ssh设置权限,然后免密登录。

1
2
3
4
5
6
7
8
chmod 700 .ssh
chmod 600 authorized_keys

rwx = 4 + 2 + 1 = 7
rw = 4 + 2 = 6
rx = 4 +1 = 5


tar 命令

1
2
3
4
5
# 压缩一个目录
tar -cvf FileName.tar DirName

# 解压
tar -xvf FileName.tar       

执行shell 脚本

1
2
3
sh -x vulgar_query_preprocessor.sh
scp -r -i ~/.ssh/qiso_id_rsa qiso@10.39.22.30:/home/qiso/data/production/search/nlp/query_quality/data/vulgar_query/model/ ./
/home/qiso/data/production/search/nlp/query_quality/data/vulgar_query/embedding/query_ngram_represent

diff 命令

理解diff 如何工作的,下面给出了一个非常易懂的例子

{% fold 开/合 %} diff分析两个文件,并输出两个文件的不同的行。diff的输出结果表明需要对一个文件做怎样的操作之后才能与第二个文件相匹配。diff并不会改变文件的内容,但是diff可以输出一个ed脚本来应用这些改变。 现在让我们来看一下diff是如何工作的,假设有两个文件:

//file1.txt I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed.

//file2.txt I need to buy apples. I need to do the laundry. I need to wash the car. I need to get the dog detailed.

我们使用diff比较他们的不同: diff file1.txt file2.txt

输出如下结果: 2,4c2,4 < I need to run the laundry. < I need to wash the dog.

< I need to get the car detailed.

I need to do the laundry. I need to wash the car. I need to get the dog detailed.

我们来说明一下该输出结果的含义,要明白diff比较结果的含义,我们必须牢记一点,diff描述两个文件不同的方式是告诉我们怎么样改变第一个文件之后与第二个文件匹配。我们看看上面的比较结果中的第一行 2,4c2,4 前面的数字2,4表示第一个文件中的行,中间有一个字母c表示需要在第一个文件上做的操作(a=add,c=change,d=delete),后面的数字2,4表示第二个文件中的行。

2,4c2,4 的含义是:第一个文件中的第[2,4]行(注意这是一个闭合区间,包括第2行和第4行)需要做出修改才能与第二个文件中的[2,4]行相匹配。 接下来的内容则告诉我们需要修改的地方,前面带 < 的部分表示左边文件的第[2,4]行的内容,而带> 的部分表示右边文件的第[2,4]行的内容,中间的 — 则是两个文件内容的分隔符号。

ss {% endfold %}

比较两个目录的demo讲解

{% fold 开/合 %} 比较两个目录的时候无非是有的文件仅仅存在于某个目录中而在另一个目录中没有,如果存在同名的文件,则比较这两个文件的不同。diff比较目录的结果我们可以结合grep命令筛选出我们想要的输出,例如仅仅输出两个目录下不同的文件而忽略掉某一个目录独有另一个目录不存在的输出记录。

另外比较目录的时候有两个参数很有用,-r 和 -q ,前者表示递归比较目录中的子目录,后者表示仅仅列出两个目录中有哪些文件不同,而不去比较目录中各个文件的具体内容。特别是在作版本控制的时候,比较的两个目录如果文件很多,我们可能只需要知道两个目录有那些文件有差异就行了,而不需要diff列出具体的差异内容,因为文件很多,默认情况下diff会输出两个目录所有不同文件的内容差异,这会使得输出很多很杂乱,加上-q之后则只会输出不同的文件名。

diff -r -q directory1 direcotory2 {% endfold %}

diff详解,读懂diff结果

alias

用来设置指令的别名

在机器上使用vim 而不要使用 vi

alias vi='/usr/bin/vim' # 设置 alias

alias vi=‘vim’ # 设置指向

source, sh, bash, ./ 执行 shell 文件的区别

  1. source

    source a.sh # 在当前的shell 中读取,a.sh 不需要有执行权利

    . a.sh # 也可以写成这样,注意中间是有空格的

    #这个是在当前的 shell 中,逐行读入的脚本,然后创建的变量都保存在当前的shell 中

  2. sh/bash

    sh a.sh

    bash a.sh # 这两种方式都是打开一个 subshell 去执行, a.sh 不需要有执行权限

    sh -x a.sh # 这个是 boss 常用的执行方式

  3. ./

    ./a.sh #打开一个subshell 执行, a.sh 是需要有执行权限的,如果没有可以通过 chmod +x 进行添加

chmod 和chown 的区别

chown用法:

用来更改某个目录或文件的用户名和用户组。(改变所属)

chown 用户名:组名 文件路径(可以是绝对路径也可以是相对路径)

1
2
3
chown root:root /tmp/tmp1

#就是把tmp下的tmp1的用户名和用户组改成root和root(只修改了tmp1的属组)。

chmod

用来修改某个目录或文件的访问权限。

1
chmod -R 777 /home/linux

环境变量 - set、env、export

set命令显示当前shell的变量,包括当前用户的变量;

env命令显示当前用户的变量;

export命令显示当前导出成用户变量的shell变量。

**查看命令-more, less, cat **

cat 是一次性显示整个文件的内容,还可以将多个文件连接起来显示,它常与重定向符号配合使用,适用于文件内容少的情况;

more命令,功能类似 cat。more命令只能前向后读取文件,因此在启动时就加载整个文件。

less可以前后看,比more 功能更加强大。

linux 中 sort

1
2
3
4
5
6
7
sort file1.txt file2.txt  > sorted.txt
sort file1.txt file2.txt  -o sorted.txt #上面两种手工写法都是一样的

cat sorted_file.txt | uniq > uniq_lines.txt # 找出已排序文件中不重复的行:
sort -k 2 data.txt # k表示的列数  依据第二列进行排序
sort -nrk 1 data.txt #依据第一列进行逆序排序, -r 表示逆序

1
依据第二列进行排序

查看cpu信息的方法

  1. 使用命令 lscpu
  2. 查看系统文件 less /proc/cpuinfo
  3. 使用三方的软件包

linux 中的脚本调试

常用是以下的三种方式。

  1. echo 方式输出

    最简单的调试方法, 比如:

    echo $VAR

  2. 命令选项 -n

    功能:读取shell脚本,但是不执行。 比如

    bash –n script.sh

  3. 命令选项 -x

    功能: 提供跟踪执行信息,将执行脚本的过程中把实际执行的每个命令显示出来,行首显示+, +后面显示经过替换之后的命令行内容,有助于分析实际执行的是什么命令.

    其中"+" 表示执行的某个命令人,然后基于上一个"+" 使用"++" 表示更近一步的执行。很好理解的方式。

    特点: 是shell 首选的调试方式。比如:

    在命令行提供参数: sh -x script.sh

    在脚本开头提供参数: #!/bin/sh -x

在脚本中用 set 命令启用or 禁用参数: set -x 表示启用, set +x 表示禁用

管道

linux 中有些命令是可以带参数,接受“标准输入”作为参数

1
cat /etc/passwd | grep root

其中的 | 是管道命令。左侧的命令(cat /etc/passwd)的标准输出作为后面命令的输入。其中grep 是可以接受标准输入作为参数。上面的命令等同于

1
grep root /etc/passwd

但是大多数的命令是不接受标准输入作为参数,比如说 echo

这个使用后就出现了 xargs 命令, 该命令将标准输入转换成命令行参数。

1
2
echo "hello world" | xargs echo
# hello world 就是输出

该命令的格式如下

1
$ xargs [-options] [command]

xargs的作用在于,大多数命令(比如rmmkdirls)与管道一起使用时,都需要xargs将标准输入转为命令行参数。

默认情况下, xargs 将换行符和空格作为分隔符,把标准输入分解成一个个命令行参数。

1
echo "one two three" | xargs mkdir

使用 -d 可以更改分隔符

1
echo -e "a\tb\tc" | xargs -d "\t" echo

参数 -p,可以确认到底执行的是什么命令

-p参数打印出要执行的命令,询问用户是否要执行。

1
2
$ echo 'one two three' | xargs -p touch
touch one two three ?...

-t参数则是打印出最终要执行的命令,然后直接执行,不需要用户确认。

1
2
$ echo 'one two three' | xargs -t rm
rm one two three

examples

xargscp 命令结合使用过,返回前 5 个结果作为 cp 的输入。

1
2
3
4
ls | head -n 5| xargs -i cp {} /home/jijeng/projects/test/src

# 回到上一个目录(最近的目录)
cd -

其他小命令

查看端口

在mac 上使用 lsof: list open files

1
2
lsof -i # 查看某个端口是否被占用, i 表示ip tcp 表示tcp 协议
lsof -i tcp:8888  

比如说查看服务器8000 端口(port )的占用情况

linux 中可以使用 lsofnetstat 两个命令

netstat用来查看系统当前系统网络状态信息,包括端口,连接情况等,常用方式如下:

netstat -atunlp,各参数含义如下: -t : 指明显示TCP端口 -u : 指明显示UDP端口 -l : 仅显示监听套接字(LISTEN状态的套接字) -p : 显示进程标识符和程序名称,每一个套接字/端口都属于一个程序 -n : 不进行DNS解析 -a 显示所有连接的端口

1
2
3
4
5
6
7
8
lsof -i:端口号
netstat -nltp | grep 进程号

netstat -tunlp | grep 22
netstat -tunlp | grep  端口号

ps -ef | grep 进程名

Mac OS/Linux命令查询网络端口占用情况

1
netstat -an | grep 3306
1
lsof -i:80

-i参数表示网络链接,:80指明端口号,该命令会同时列出PID,方便kill

查看所有进程监听的端口

1
sudo lsof -i -P | grep -i "listen"

两者的区别

netstat无权限控制,lsof有权限控制,只能看到本用户 losf能看到pid和用户,可以找到哪个进程占用了这个端口

查看哪些端口被打开

1
netstat -anp

ubuntu 中打开某个端口或者关闭某个端口号

1
2
3
4
5
6
iptables -A OUTPUT -p tcp --dport 端口号-j DROP

iptables -A OUTPUT -p tcp --dport 9200-j DROP


iptables -A INPUT -ptcp --dport  9200-j ACCEPT

进程相关

ps是显示瞬间进程的状态,并不动态连续;如果想对进程进行实时监控应该用top命令。

基本参数:

1
2
3
4
-A :所有的进程均显示出来,与 -e 具有同样的效用;
-a : 显示现行终端机下的所有进程,包括其他用户的进程;
-u :以用户为主的进程状态 ;
x :通常与 a 这个参数一起使用,可列出较完整信息。

输出格式规划:

1
2
3
l :较长、较详细的将该PID 的的信息列出;
j :工作的格式 (jobs format)
-f :做一个更为完整的输出。

ps 命令的输出说明

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
USER:该命令是由哪个用户产生的。
PID:进程的ID号。
%CPU:该进程占用CPU资源的百分比。
%MEM:该进城占用物理内存的百分比。
VSZ:该进程占用虚拟内存的大小,单位KB。
RSS:该进程占用实际物理内存的大小,单位KB。
TTY:该进程在哪个终端中运行。其中tty1-tty7代表本地控制台终端,tty1-tty6是本地字符界面终端,tty7是图形终端。pst/0-255代表虚拟终端。
STAT:进程状态。常见的状态有:

R:运行
S:睡眠
T:停止状态
s:包含子进程
+:位于后台

START:该进程的启动时间
TIME:该进程占用CPU的运算时间,注意不是系统时间
COMMAND:产生此进程的命令
  1. 不加参数执行ps命令
1
2
3
4
[vagrant/tmp] ]$ps
  PID TTY          TIME CMD
 1558 pts/0    00:00:00 bash
 2990 pts/0    00:00:00 ps

结果默认会显示4列信息。

  • PID: 运行着的命令(CMD)的进程编号
  • TTY: 命令所运行的终端
  • TIME: 运行着的该命令所占用的CPU处理时间
  • CMD: 该进程所运行的命令
  1. 显示所有当前进程

这个命令的结果或许会很长。为了便于查看,可以结合less命令和管道来使用。

1
2
ps -aux

  1. 显示所有进程信息,连同命令行
1
ps -ef 
  1. ps 与grep 组合使用,查找特定进程
1
ps -ef|grep ssh
  1. 通过pid来过滤进程
1
ps -L 1213

如果想要看到更多的细节,那么可以格式化输出列表

1
ps -f -C getty
  1. 根据用户过滤进程

查看用户’jeng' 的进程

1
ps -u jeng
  1. 根据进程名和pid 进行过滤
1
ps -C getty
  1. 根据cpu 和内存使用来过滤进程

默认的结果集是未排好序的。可以通过 –sort命令来排序。

根据cpu使用来降序排序

1
2
ps -aux --sort -pcpu | less
ps -aux --sort -pcpu | head -n 10

根据 内存使用 来降序排序

1
ps -aux --sort -pmem | less

也可以将上述两个命令和到一起,并使用通道显示前 10个结果

1
 ps -aux --sort -pcpu,+pmem | head -n 10
  1. pstree 命令(查看进程树)

这个是非常直观的查看进程变化的命令

Linux上进程有5种状态:

  1. 运行(正在运行或在运行队列中等待)
  2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号)
  3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)
  4. 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放)
  5. 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行)

ps工具标识进程的5种状态码:

1
2
3
4
5
D 不可中断 uninterruptible sleep (usually IO) 
R 运行 runnable (on run queue) 
S 中断 sleeping 
T 停止 traced or stopped 
Z 僵死 a defunct ("zombie") process 

显示的结果中pid 是进程,ppid 显示的是父进程。

1
2
3
4
5
6
7
8
ps -ef  

ps -ax | grep vulgar_
kill -9 pid 杀死进程

#自定义ps 的输出形式(查看进程的pid、开始时间,持续时间和命令格式) 
ps -eo pid,lstart,etime,cmd | grep 'bash run.sh'
ps -eo pid,lstart,etime,cmd | grep pid # 在grep 后面既可以使用pid数字 也可以使用cmd
  1. 动态监测进程状态

ps 命令是系统当前的静态结果,如果想要实时监控进程状态,那么可以考虑将ps 命令和 watch命令结合起来。

1
2
# 结果是每秒刷新一次,注意这种书写的方式
watch -n 1 ‘ps -aux --sort -pmem, -pcpu’

xargs

该命令和管道的命令是类似的,不同点在于, xargs 是把 | 左边的输出当做后面命令的一个参数来运行。而如果只是使用|, 是把其左边的输出当做右边命令的输入。xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。

Linux 中脚本执行的四种方式

(1)切换到shell脚本所在的目录(此时,称为工作目录)执行shell脚本

1
./hello.sh

其中命令行中的.表示当前工作目录。不是什么执行之类的符号 (2)使用绝对路径执行

1
/data/shell/hello.sh

上述两种方法实际上是一类,文件执行时候的bash 路径是文件第一行声明的bash路径;需要执行权限。 (3)使用命令bash或者 sh执行脚本

1
2
bash hello.sh
sh hello.sh

这种方式不需要设定执行权限;不需要执行bash路径,因为使用的是当前bash 的路径。

上述三种((1),(2), (3))都是在父shell中开启了一个子shell,执行的脚本是在子shell 中执行,当执行完成之后,子shell就关闭,然后回到父shell 中。 (4)使用source命令执行

1
source hello.sh

source命令是作用于整个父进程,这个是和上述三者的最大区别。比如说,如果不想注销系统的,但是想让全局配置文件生效,那么就使用source命令。

1
source /etc/profile

解压缩命令

.tar.gz.rar.zip 等扩展名的比较

.zip.rar 经常见于windows系统,不对文件名进行压缩,所以容易造成乱码; .tar.gz 经常见于linux 系统,默认在linux 环境下无法使用 .zip.rar ,所以需要

1
sudo apt-get install rar  

压缩文件夹和多个文件到一个名称下

1
zip -r test.zip test_dir *txt *sh *py

.tar 是归档或者说打包,将多个文件或者目录变成一个文件并不会使得总的体积减少,比如

如果你 tar 100 个 50kb 的文件得到的 tar 归档文件大小应该为 5000kb 左右。 使用 Tar 进行文件归档的唯一好处就是减少某种粒度磁盘空间的分配。(例如在簇大小为 4kb 的磁盘上 1 字节的文件也要占用 4kb 磁盘空间,若有 1000 个 1 字节的文件分散在此磁盘上的话,则会占用 4MB 大小,而使用 Tar 归档之后则只占用 1MB 左右大小。)

所以更加常见的文件后缀是 .tar.gz。该种压缩方式其实上是2个过程。tar是打包工具,把很多文件打包成一个文件,gz是压缩格式。

解压命令

1
tar -zxvf ×××.tar.gz

后面的-C是大写C,如果不指定解压位置需要去掉-C,系统会把压缩包中所有文件解压到当前工作文件夹

1
tar -zxf XXX.tar.gz -C 解压位置

云端主机之间传输文件

(1) 使用scp 命令

scp -i 表示使用秘钥 进行传输文件(不用输入密码)

1
2
3
scp -r -i ~/.ssh/qiso_id_rsa qiso@10.39.22.30:/home/qiso/jarvis* ~/
scp -r -i ~/.ssh/qiso_id_rsa qiso@10.39.22.30:/home/qiso/data/production//search/nlp/default_query/data/*traditi* /home/qiso/data/production/search/nlp/query_quality/data/
scp -i  Selects the file from which the identity (private key) for public # 使用 private key 进行测试

设置特定端口(ssh 默认是 22 端口,scp 是基于ssh ,所以也是 22端口)

1
scp -P 2222 root@www.xxorg.com:/root/test.tar.gz /home/test.tar.gz

传输文件夹

1
scp -r root@www.xxorg.com:/root/test_dir /home/jeng

scp传输速度较慢,但使用ssh通道保证了传输的安全性。提高scp 的速度:

  • 通常压缩会降低scp 速度,所以是很多文件夹,那么建议先压缩,然后再scp 传输

(1)wget -c

使用 wget 也是可以实现断点传输的

1
2
-c (continue )
Continue getting a partially-downloaded file

(2)使用 rsync 命令

rsync (remote sync)是Linux系统下的文件同步和数据传输工具,它采用“rsync”算法,可以将一个客户机和远程文件服务器之间的文件同步,也可以在本地系统中将数据从一个分区备份到另一个分区上。相比于 scp 传输文件, 可以增量同步文件,如果数据传输出现中断,恢复后可以从传输不一致的部分重新开始。可以使用rcp、ssh等方式来传输文件,当然也可以通过直接的socket连接。

rsync默认使用ssh的22端口,那么如果我们的服务器为了安全已经修改成其他的端口,比如端口是1234那怎么办呢?可以加上 -e ‘ssh -p 1234’参数来指定端口号:

1
2
3
4
rsync -P -e 'ssh -p 1234' daweibro@linode-server:/home/daweibro/database-backup.sql /home/daweibro ./
rsync -avL --progress -e "ssh -i gitlab_filerun.pem" -r up_test.gz root@39.98.115.246:/home/upload
rsync -avL  -r up_test.gz root@39.98.115.246:/home/upload # 常用的几个命令和参数

rsync 适合大量小文件,压缩之后就不太好用了。

(3)使用国外的vps

方案一:vps+ php 端口

搞个 VPS,先在 VPS wget 下来。然后 php -S 0.0.0.0:4000。下载 http://vpsip:4000/xxx.zip

方案二:换 scp 的端口(使用webfs)

scp 走的是 22 端口,严重受到监 kong。 我都是安装一个 webfs,它是 mini-server,执行 webfsd -p 80 -F,这样就可以 80 端口下载了(可以用 wget 下载)。 80 端口速度会比 22 速度快。下载完之后 Ctrl-C 关掉 webfsd 即可。

原因: http 是80 端口(https 是443 端口),所以当使用http 协议传输的时候,更加快,以牺牲安全性?为代价

scp 用于加密网管会话,该加密基于RSA,基于TCP 端口22.

方案三:

Download a large file from Google Drive. 使用 ,主要解决的问题 security warning from Google Drive

If you use curl/wget, it fails with a large file because of the security warning from Google Drive.

关于 curl 命令

在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具。它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具。 curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。

(4)单个文件太大的问题

第一种方式:大文件还是用 7z 分一下卷吧,一个文件 512M ,不管用啥方法下载,保险系数都大得多。将大文件分卷成中等或者小文件,是非常实用的技巧,可以缓解scp 数据传输中断的问题。

第二种方式: 使用 SFTP,支持断点续传

(5) ftp 和sftp

文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,工作在应用层,使用TCP 传输而不是UDP 传输,在客户和服务器端建立连接需要经过”三次握手“,保证连接的可靠性,为数据传输提供可靠保证。ftp默认的连接端口是 21, 传输端口是20.

sftp(Secure File Transfer Protocol)协议是在ftp 的基础上对数据进行加密,使得传输的数据相对更安全。但是这种安全是以牺牲效率为代价的(需要实际验证一下这种效率下降的程度)。sftp默认的端口是 22.

ftp 是基于ssh 等加密实现的传输通道,而ssl 是为http/ smtp 设计的加密算法。

基于python 实现的sftp 断点续传

(6)基于 udp

思路很简单,使用TCP进行传输控制、用UDP进行数据传输。tsunami-udp 这样可以无状态的进行数据传输,然后中间加一些文件校验和重传机制,达到加速传输的目的。传统的tcp传统,基于长连接,很容易受网络波动的影响。特别是网络拥塞的情况下,只能通过多进程/线程来进行有序传输。

这方面是一个很好的思路,但是没有找到相应比较好的开源工具。

(7) 一些网盘服务

好用的大文件分享服务

使用 kaggle 作为中介进行下载,教程,不建议经常这么做。

(8)安装 bbr 加速

如果是从服务器上下载资源,那么在服务器上安装bbr;如果是从本地上传文件到服务器上,那么在本地安装bbr 的支持。这个逻辑需要搞清楚,发出流量的主机是需要安装bbr的。

国内测速文件: http://bhs.proof.ovh.net/files/10Gb.dat

前台执行和后台执行命令

1
2
3
4
5
6
7
&
nohup
ctrl + z
ctrl + c
jobs
bg
fg

(1) 还未执行的命令

  • &

当在前台运行某个作业时,终端被该作业占据;可以在命令后面加上& 实现后台运行。例如:sh test.sh & 适合在后台运行的命令有find、费时的排序及一些shell脚本。在后台运行作业时要当心:需要用户交互的命令不要放在后台执行,因为这样你的机器就会在那里傻等。

但是该命令同样是将结果输出到屏幕上,干扰其他工作,所以最好使用功能下面的方法重定向到某个文件中

1
command >> out.file &
  • nohup

使用&命令后,作业被提交到后台运行,当前控制台没有被占用,但是一但把当前控制台关掉(退出帐户时),作业就会停止运行。nohup命令可以在你退出帐户之后继续运行相应的进程。

1
nohup command &

或者将命令输出重定向到结果文件

1
nohup command  >>  command.log

使用了nohup之后,很多人就这样不管了,其实这样有可能在当前账户非正常退出或者结束的时候,命令还是自己结束了。所以在使用nohup命令后台运行命令之后,需要使用exit正常退出当前账户,这样才能保证命令一直在后台运行

(2)正在执行的命令

  • ctrl + z 可以将一个正在前台执行的命令放到后台,并且处于暂停状态

  • ctrl + c 终止前台命令

  • jobs 查看当前有多少在后台运行的命令。 jobs -l选项可显示所有任务的PID,jobs的状态可以是running, stopped, Terminated。但是如果任务被终止了(kill),shell 从当前的shell环境已知的列表中删除任务的进程标识

jobs 列出后台已停止或正在运行的工作。

1
2
3
-l:列出PID
-r:仅列出正在后台运行的工作
-s:仅列出正在后台当中暂停的工作
  • bg 将一个在后台暂停的命令,变成继续执行 (在后台执行) 如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid) 将任务转移到后台运行: 先ctrl + z;再bg,这样进程就被移到后台运行,终端还能继续接受命令。

  • fg 将后台中的命令调至前台继续运行 如果后台中有多个命令,可以用 fg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)

apt 和apt-get 的区别

Ubuntu 16.04 发布时,一个引人注目的新特性便是 apt 命令的引入。随着 apt install package 命令的使用频率和普遍性逐步超过 apt-get install package,越来越多的其它 Linux 发行版也开始遵循 Ubuntu 的脚步,开始鼓励用户使用 apt 而不是 apt-get

(1) apt 和apt-get 之间的区别

注意以下是latex 的格式,实际上这类应该使用 markdown 的语法。

\begin{table}[] \begin{tabular}{lll} apt 命令 & 取代的命令 & 命令的功能 \\
apt install & apt-get install & 安装软件包 \\
apt remove & apt-get remove & 移除软件包 \\
apt purge & apt-get purge & 移除软件包及配置文件 \\
apt update & apt-get update & 刷新存储库索引 \\
apt upgrade & apt-get upgrade & 升级所有可升级的软件包 \\
apt autoremove & apt-get autoremove & 自动删除不需要的包 \\
apt full-upgrade & apt-get dist-upgrade & 在升级软件包时自动处理依赖关系 \\
apt search & apt-cache search & 搜索应用程序 \\
apt show & apt-cache show & 显示装细节
\end{tabular} \end{table}

当然 apt 也有自己的命令:

\begin{table}[] \begin{tabular}{ll} 新的apt命令 & 命令的功能 \
apt list & 列出包含条件的包(已安装,可升级等) \
apt edit-sources & 编辑源列表
\end{tabular} \end{table}

结论:

apt-get 虽然没被弃用,但作为普通用户,还是应该首先使用 apt。简单说,一个是分开写,一个使用- 连接到一块。

Ubuntu 完全卸载某个软件,以 nginx 软件为例。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 删除nginx,–purge包括配置文件
sudo apt-get --purge remove nginx
 
# 自动移除全部不使用的软件包 (卸载软件及其依赖的安装包)
sudo apt-get autoremove

# 列出与nginx相关的软件 并删除显示的软件
dpkg --get-selections|grep nginx

sudo apt-get --purge remove nginx
sudo apt-get --purge remove nginx-common
sudo apt-get --purge remove nginx-core

未归类

1
2
last # 表示登录成功的user
lastb  # 表示登录不成功user

find命令

1
2
3
4
5
6
find . -maxdepth 3 -name datasetMaker

find furniture_odd -name *jpg  -exec mv {} tmp/ \;
find sourcePath/ -name "*.txt"  -exec mv {} targetPath/  \;
#or
find sourcePath/ -type f  -exec mv {} targetPath/  \;

Whois,通常来说,就是一个用于查询域名是否已经被注册,以及注册域名的详细信息(如域名所有人、域名注册商、域名注册日期和过期日期等)的工具。当然,现在已经有各种网页版查看 whois 信息的工具,但是很多时候网页查询有附加条件,比如输入验证码或者不支持的后缀等,比较低效。因此我还是喜欢在命令行下使用 whois 命令来直接获得域名的 whois 信息。

Ubuntu 16.04下安装VNC和Unity桌面系统;windows下通过VNC图形化访问Ubuntu桌面环境

apt-get install -y –reinstall ubuntu-desktop&& apt-get -y install unity apt install -y xfce4 xfce4-goodies vnc4server vncserver

mv 和rename 的区别?

mv 适合对于一个文件的修改。 rename 是对多个文件进行重命名。(rename multiple files)

方法1:

1
find -nam e*log | xargs -i {} mv {}.log xin_{}.log # 先find 然后 xargs 使用mv 进行单个mv

方法2: rename 命令

1
2
3
rename test xinyu*.log

rename 原字符串 新字符串 文件名

例子

将后缀名 jpg 改成png

1
rename 's/\.jpg$/\.png/' *.jpg
1
2
3
# 查看某路径下的所有文件夹(不包括文件)

ls  dir | grep ^d 

(1)NSLookup

NSLookup (Name Server Look Up) is a tool used to obtain domain names, IP addresses, and more. nslookup用于查询DNS的记录,查询域名解析是否正常,在网络故障时用来诊断网络问题

1
2
3
# nslookup [IP地址/域名]
nslookup www.baidu.com # 使用默认的dns 解析
nslookup www.baidu.com 8.8.8.8 # 使用 8.8.8.8 dns 解析

bash相关快捷键

bash 指得是命令行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
ctrl键组合

ctrl+a:光标移到行首。

ctrl+c:杀死当前进程。

ctrl+d:退出当前 Shell。

ctrl+e:光标移到行尾。

esc组合
esc+d: 删除光标后的一个词
esc+f: 往右跳一个词, 不能连续跳,需要按一下然后停一下。
esc+b: 往左跳一个词
esc+t: 交换光标位置前的两个单词。


定位命令位置和相关信息的命令

(1)type 命令查询命令所在的目录

Display information about command type. output a single word which is one fo ‘alias’, ‘keyword’, ‘function’, ‘builtin’ , ‘file’

1
type ch

(2)which 命令查询命令

which returns the pathnames of the files (or links) which would be executed in the current environment.

(3) whereis

locate the binary, source, and manual page files for a command

1
2
whereis -b whereis
whereis -m whereis

which 和whereis 的区别:which 是find exeable version。 whereis 是find all location。所以which 更加常见,有用?

linux 中进程和线程的关系

几种进程间的通信方式

  1. 管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有血缘关系的进程间使用。进程的血缘关系通常指父子进程关系。
  2. 有名管道(named pipe):有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间通信。
  3. 信号量(semophore):信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它通常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  4. 消息队列(message queue):消息队列是由消息组成的链表,存放在内核中 并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  5. 信号(signal):信号是一种比较复杂的通信方式,用于通知接收进程某一事件已经发生。
  6. 共享内存(shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问,共享内存是最快的IPC方式,它是针对其他进程间的通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量配合使用,来实现进程间的同步和通信。
  7. 套接字(socket):套接口也是一种进程间的通信机制,与其他通信机制不同的是它可以用于不同及其间的进程通信。

几种线程间的通信机制

  1. 锁机制
  • 互斥锁:提供了以排它方式阻止数据结构被并发修改的方法。
  • 读写锁:允许多个线程同时读共享数据,而对写操作互斥。
  • 条件变量:可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
  1. 信号量机制:包括无名线程信号量与有名线程信号量
  2. 信号机制:类似于进程间的信号处理。

线程间通信的主要目的是用于线程同步,所以线程没有象进程通信中用于数据交换的通信机制。

更多关于这方面的介绍可以参考这里

(3)vim python缩进等一些配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
set filetype=python
# au BufNewFile,BufRead *.py,*.pyw setf python
autocmd FileType python set tabstop=4 | set expandtab | set autoindent  # 建议使用这个,设置只是针对 python文件生效,其他文件不变
set helplang=cn "中文帮助文档(前提是下了中文包)
syntax enable
syntax on " 自动语法高亮
set number"显示行号
colorscheme desert" 设定配色方案
set guifont=Consolas:h12:cANSI"英文字体
set guifontwide=SimSun-ExtB:h12:cGB2312
set tabstop=4"表示Tab代表4个空格的宽度
set expandtab"表示Tab自动转换成空格
set autoindent"表示换行后自动缩进
set autoread " 当文件在外部被修改时,自动重新读取
set history=400"vim记住的历史操作的数量,默认的是20
set nocompatible"使用vim自己的键盘模式,而不是兼容vi的模式
set confirm"处理未保存或者只读文件时,给出提示
set smartindent"智能对齐
set shiftwidth=4

设置缩进和反缩进

1
2
3
4
:10,100>
第10行至第100行缩进
:20,80<
第20行至第80行反缩进

跳转到指定的行

1
:n # 当 n=88 ,则跳转到 88 行

到达本文件的最开始和最后的位置

1
2
[[  # 表示最开始的位置
]]  # 表示最后的位置

(1)代码补全

代码自动补全,这个只限于本文中已经出现过的字符串可以自动补全。

1
2
CTRL-N是向下查找以进行补全,在不同场合使用不同的快捷键可以加速补全的速度。
CTRL-P一般的含义是向上,因此CTRL-P补全是向上查找以进行补全,

更加普世的代码补全

常用的有三种方式进行代码补全

  • python-mode:页面太丑
  • YouCompleteMe:功能过于强大,支持多种编程语言,加载繁琐
  • jedi-vim:对于python 的提醒足以

环境是 Ubuntu

1
2
sudo apt-get install vim-python-jedi
vim-addons install python-jedi

有了自动补全之后,就是语法检测,一般选择 w0rp/ale链接

其实不用麻烦,直接使用该博主写好的脚本即可。

\begin{table}[] \begin{tabular}{lll} Action & Mode & key binding \\
Toogle Nerdtree & Normal & crtl + n \\
toogle Tagbar & Normal & f8 \\
Look for file & Normal & crtl + p \\
Goto definition & Normal & crtl + {]} \\
Show docstring & Normal & K \\
Extract method & Normal/Visual & crlt + c r m \\
Auto complete & Insert & crtl + space \\
Expand snippet & Insert & tab
\end{tabular} \end{table}

使用vim-plug安装vim插件

常用的命令:

1
2
3
4
5
PlugInstall [name ...] [#threads]	安装插件
PlugUpdate [name ...] [#threads]	安装或更新vim插件
PlugClean[!]	卸装未使用的目录 (bang version will clean without prompt)
PlugUpgrade	更新vim-plug自身
PlugStatus	查看vim插件的状态

https://vimjc.com/vim-plug.html

linux 中连续使用两个命令

1
2
3
#这种example :
mkdir elasticsearch-docker && cd elasticsearch-docker

linux磁盘和内存

(1)linux 内存管理

主要特点是,无论物理内存有多大,Linux 都将其充份利用,将一些程序调用过的硬盘数据读入内存,利用内存读写的高速特性来提高Linux系统的数据访问性能。而Windows是只在需要内存时,才为应用程序分配内存,并不能充分利用大容量的内存空间。简单来说,buff是即将要被写入磁盘的,而cache是被从磁盘中读出来的。所以,linux 中的内存分配机制是优先使用物理内存,所以再次打开会比较快。

buffer:是为了减少短期内突发io 的影响,起到流量整形的作用。cache 是缓解cpu 和内存之间的速度差异。所以linux中的 cache 可以回收,但是不能全部回收。

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。 内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光

实际可用内存大小:Free(-/+ buffers/cache行)= Free(Mem)+buffers(Mem)+Cached(Mem);

(1)Linux中buff-cache占用过高解决手段

1
2
3
4
sync
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches
  • sync:将所有未写的系统缓冲区写到磁盘中,包含已修改的i-node、已延迟的块I/O和读写映射文件
  • echo 1 > /proc/sys/vm/drop_caches:清除page cache
  • echo 2 > /proc/sys/vm/drop_caches:清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。
  • echo 3 > /proc/sys/vm/drop_caches:清除pagecache和slab分配器中的缓存对象。 /proc/sys/vm/drop_caches的值,默认为0

在 linux (Ubuntu) 中查看进程是否因为内存占据过大而被杀掉

1
2
3
egrep -i -r 'killed process' /var/log

grep "Out of memory" /var/log/messages

创建定时脚本解决

1
2
3
4
5
6
7
#!/bin/bash#每两小时清除一次缓存
echo "开始清除缓存"
sync;sync;sync #写入硬盘,防止数据丢失
sleep 10#延迟10秒
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches

创建定时任务

设置crond启动以及开机自启

1
crontab -e #弹出配置文件

设置crond启动以及开机自启

1
2
#分  时  日  月  周  命令
0 */2 * * * ./cleanCache.sh

设置crond启动以及开机自启

1
2
systemctl start crond.service
systemctl enable crond.service

查看定时任务是否被执行

1
cat /var/log/cron | grep cleanCache

(2)linux 中磁盘管理

Linux 查看磁盘空间可以使用 dfdu 命令。

df 以磁盘分区为单位查看文件系统,可以获取硬盘被占用了多少空间,目前还剩下多少空间等信息。

我们使用df -h 或者 df -hi命令来查看磁盘信息, -h 选项为根据大小适当显示,以下是常见的参数。

  • Filesystem:文件系统
  • Size: 分区大小
  • Used: 已使用容量
  • Avail: 还可以使用的容量
  • Use%: 已用百分比
  • Mounted on: 挂载点 

我们还可以使用参数 -i 来查看目前档案系统 inode 的使用情形。有的时候虽然档案系统还有空间,但若没有足够的 inode 来存放档案的信息,一样会不能增加新的档案。所以使用或者创建文件是需要满足能够创建文件和文件node 两方面要求。inode 的数量关系着系统中可以建立的档案和目录。

du 的英文原义为 disk usage,含义为显示磁盘空间的使用情况,用于查看当前目录的总大小。

du -sh

方便阅读的格式显示test目录所占空间情况:

1
2
3
4
5
6
du -h test
du -h --max-depth=1 #  当前路径的第一层目录

# 查看每个用户目录下硬盘使用情况
cd /home
du -h *

(3)linux运用软链接解决目录空间不足

1
2
3
4
5
6
cd /
mv /usr /new
mv /home /new
ln -s /new/usr /usr
ln -s /new/home /home
这样,/usr和/home目录中的东东就都移到新硬盘中了。

(4)挂载和卸载磁盘

如果目录的空间不足,可以使用软连接解决,但是如果整个磁盘(分区)

  • 磁盘(设备)在Linux中的表示:

Linux所有设备都被抽象为一个文件,保存在/dev目录下 磁盘设备一般的名称为hd[a-z]或sd[a-z]([a-z]为分区号),如hda,sda,hdb,sdb IDE设备的名称为hd[a-z],SATA、SCSI、SAS、USB等设备的名称为sd[a-z]

  • 分区管理

将一个磁盘逻辑的分为几个区,每个区当做独立磁盘,以方便使用和管理 不同分区的名称一般为:设备名称+分区号 第一块硬盘的第一个分区叫sda1,第一块硬盘的第二个分区sda2 第二块硬盘的第一个分区叫sdb1,第二块硬盘的第二个分区叫sdb2

磁盘类型

1
2
3
4
5
fd:软驱
hd:IDE 磁盘
sd:SCSI 磁盘
tty:terminals
vd:virtio 磁盘

最多能划分多少个分区?

由于磁盘分区表只能保留四条记录,所以一个磁盘的主分区+扩展分区最多只能有四个。

如果在多用户中,不建议使用,因为你在扩容之前需要 unmount 相应的设备,在 unmount 过程中可能还需要 kill 相应的进程。这样的操作很危险,相应的代码和教程。控制台扩容云硬盘代码 和对应的教程Linux系统云硬盘扩容后新分区指引

(5) du df disk 三个命令的区别

df 全称 disk filesystem,用于显示 Linux 系统磁盘利用率,通常也用来查看磁盘占用空间。

df -T 显示磁盘使用情况以及每个块的文件系统类型(例如,xfs、ext2、ext3、btrfs 等)。

常见的文件系统有 Windows 下的 FAT32,NTFS,Unix 系统下的 ext3, ext4,添加 -T 参数在输出结果中增加一列来表示当前分区的文件系统。

用 inode 方式显示磁盘使用情况

df -i

inode (index node) 是一个在类 Unix 文件系统下用来描述文件系统对象(文件或者目录)的数据结构。每一个 indoe 保存对象数据的属性和磁盘块地址。文件类型对象属性包括 metadata(修改时间,访问属性等)和文件的所有者以及文件权限。

du 的英文原义为 disk usage,含义为显示磁盘空间的使用情况,用于查看当前目录的总大小。

例如查看当前目录的大小:

1
du -sh

显示指定文件所占空间:

1
du log.log

(3)fdisk 命令

分区是将一个硬盘驱动器分成若干个逻辑驱动器,分区是把硬盘连续的区块当做一个独立的磁盘使用。分区表是一个硬盘分区的索引,分区的信息都会写进分区表。

分区的优点:

  • 优化I/O性能
  • 实现磁盘空间配额限制增加磁盘空间使用效率
  • 提高修复速度
  • 隔离系统和程序
  • 安装多个OS
  • 采用不同文件系统
  • 防止数据丢失

fdisk -l 显示磁盘大小以及磁盘分区信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[root@localhost ~]# fdisk -l
#查询本机可以识别的硬盘和分区
Disk /dev/sda:32.2 GB, 32212254720 bytes
#硬盘文件名和硬盘大小
255 heads, 63 sectors/track, 3916 cylinders
#共255个磁头、63个扇区和3916个柱面
Units = cylinders of 16065 *512 = 8225280 bytes
#每个柱面的大小
Sector size (logical/physical): 512 bytes/512 bytes
#每个扇区的大小
I/O size (minimum/optimal): 512 bytes/512 bytes

要使用一块新的硬盘,我们必须将它格式化建立合适的文件系统(linux:ext2,ext3等,windows:ntsf,fat32),并挂载到相应的目录下我们才可以使用。比如有一个新硬盘 /dev/sdb,这个硬盘用于存放mysql 数据库之类的

1
2
3
4
5
mkfs.ext3 /dev/vdb
mkfs.ext3 /dev/vdb1  //注:将/dev/sdb1格式化为ext3类型
mkdir /data1
mount /dev/sdb1 /data1
#df -h

挂载硬盘操作流程

linux上的盘和window的有区别,磁盘空间必须挂载在目录上,要不然没用

  1. 确定硬盘名
1
sudo fdisk -l
  1. 建立分区
1
sudo fdisk /dev/sda

如果是新硬盘,那么需要新建分区并格式化硬盘(如果硬盘已经有数据,那么请先备份,谨慎操作)

1
2
3
4
n    新建分区
p    创建逻辑分区
1    创建一个分区
w    保存

这个时候再使用命令查看设备信息

1
sudo fdisk -l
  1. 格式化分区

加入分区格式不是 ext4,那么可先格式化成 ext4

1
sudo mkfs.ext4 /dev/sda1
  1. 挂载到指定目录

(先创建)

1
mkdir ~/hdd

挂载

1
sudo mount /dev/sda1 ~/hdd
  1. 设置开机自动挂载
1
2
3
sudo vim /etc/fstab
# 然后加上
/dev/sda1 /home/jeng/hdd ext4 defaults 0 0

(4)硬盘的管理

多硬盘合并挂载 mhddfs, 当多个硬盘挂载在相应的文件夹下,那么形成了分散的目录,这样对于访问文件十分不利。所以可以使用 mhddfs 将多个硬盘挂载在一个路径下,也被称为linux 分区合并,即挂载点合并。

(5)各种段错误

在Linux下编译没有问题,运行时出现:段错误(有的系统提示:segmentation fault)

常常使用以下的命令

1
ulimit -s unlimited

查看本机的内存设置

1
ulimit -a

注意到其中的stack size只有10240k byte,即系统的默认值。这样ifort编译的子程序只能开辟10兆的内存,超出这个数目,运行程序将报错“Segmentation fault”。

解决的办法是提高堆栈大小,例如:

1
2
$ ulimit -s 200000

子程序就可以开辟约200M的内存。

另外,主程序中开辟内存则不受这一限制,但是ifort编译的主程序在32位系统中最多不可以超过2G内存。

另注:ulimit是bash的内部命令,一个终端只能运行一次,如果需要再改变堆栈大小,重新开一个终端

linux中文件夹

linux 中的“一切皆文件”

  1. bin

binary(二进制)的缩写;存放一般的所需要的命令,比如说ls,cp,mkdir等,基础命令的可执行文件在这里存放。

  1. sbin

system binary是系统管理员专用的二进制代码存放目录。比如说引导系统的 init 程序,普通用户无权限执行该目录下的命令,在sbin 中包含都是具有 root权限才能执行的命令

  1. boot

“引导”, 存放Linux系统启动的文件,启动配置以及内核的镜像。系统启动阶段,引导程序

  1. dev

device(设备)的缩写,存放是系统下的所有设备文件。在linux 中设备都适合以文件的形式出现,这里的设备可以是硬盘,键盘,鼠标等终端。

  1. etc

具有 “and so on”等等的额意思,存放系统的各种配置文件。系统和程序一般可以通过修改配置文件,来进行配置。比如设置系统开机启动项,配置某个程序启动的风格? 可以在/etc 下面寻找相应的文件进行修改。比如/etc/passwd(用户数据库),/etc/group, 存储的是各种组的信息,不是用户信息。/etc/shadow 将 /etc/passwd 文件中的几家米口令移动到/etc/shadow 中,后者对于 root 是可读的。

5.1 /etc/group 的解析

/etc/group 的内容包括用户组(Group)、用户组口令、GID及该用户组所包含的用户(User),每个用户组一条记录;格式如下: group_name:passwd:GID:user_list

在/etc/group 中的每条记录分四个字段:

1
2
3
4
第一字段:用户组名称;
第二字段:用户组密码;
第三字段:GID
第四字段:用户列表,每个用户之间用,号分割;本字段可以为空;如果字段为空表示用户组为GID的用户名;

将一个用户添加到用户组中,千万不能直接用:

1
usermod -G groupA 

这样做会使你离开其他用户组,仅仅做为 这个用户组 groupA 的成员。 应该用 加上 -a 选项:

1
usermod -a -G groupA user

useradd 示例 – 增加一个新用户到附加用户组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

useradd -G {group-name} username

grep developers /etc/group
# 为确保已经将该用户正确的添加到 developers 用户组中,可以查看该用户的属性,使用 id 命令:
id cnzhx





# grep developers /etc/group
  1. home

普通用户的家目录

  1. root

系统管理员所在的“家”目录,只有root 用户可以对其进行操作。root 的主目录比较特殊,不存放在/home 下,而是直接在/root 下

  1. lib

libiary(图书馆),在计算机中翻译成“库” 更加合适。系统使用函数库的目录,如存放/bin 和 /sbin 目录下程序所需要的库文件

  1. media

media(媒体,介质);软盘或者光盘等的挂载点。系统自动挂载会选择的地方。

  1. mnt

mount(嵌入,挂载点)系统可移动设备的挂载点。手动挂载选择的地方

  1. opt

optional, “可选择”的意思,作用是安装第三方软件的地方

  1. proc

process (进程),包含某些程序使用的系统信息

  1. run

运行,表示运行时的临时文件

  1. src

service(服务), 服务启动后,所需要访问的数据目录

  1. sys

system,表示系统文件

  1. tmp

系统temporary(临时)目录。 该目录存放系统中的一些临时文件,当重启时候,文件被清空。

  1. usr

unix software resource, 操作系统软件资源。包含了命令的库文件和通常操作中不会被修改的文件。比如说/usr/lib, /usr/bin 等

  1. var

variable(可变的),此目录的大小可能发生变化,存储的是缓存文件,日志文件。

  1. lost+found

当系统崩溃的时候,在系统恢复的过程中需要恢复的文件,可能在这里找到(不是删除文件的回收站)

完全重新安装软件, Ubuntu 18.04 完全重装 SSH 服务

linux 版本问题

在命令行如何查询是哪个版本的linux 呢?

uname命令虽不能查看当前系统名和版本,但可以显示系统核心信息,也可以使用cat /proc/version

1
2
3
4
uname -a

cat /proc/version 

常见的版本有centos, redhat 和ubuntu。 当然 MacOS 也是根据linux 二次开发的,所以很多命令是通用的。

  1. 权限差异

centos/redhat上面:root权限最高,想干啥干啥,其次是普通用户,切换到哪去都可以,但是要增删查改,不行,除非在/etc/sudoers上面添加用户

ubuntu上面:root权限最高,他是大哥,其次是普通用户,这个用户的个体数据存放在/home/User下面,个体用户对其所属的/home/User,下面有rw权限

  1. 安装包不同

centos/redhat:rpm包,安装方式

1
yum  -y  install   XXXX

ubuntu:.deb包,安装方式

1
apt-get  install  XXXX
  1. 界面差异
1
2
centos/redhat:比较死板,单一
ubuntu:比较炫酷,很nice

这里说一句:服务器上安装系统:最好选择centos,比较稳定,我们一般登录服务器都是后台登录,没有会去界面登录,ubuntu上的界面看不到。redhat是开源的,用户少,维护起来有些困难,要翻墙查资料。ubuntu这个路径不能伸缩(对于用多了centos的我,好难受啊,强迫症强迫症。。。)

红帽系比较稳定,Ubuntu更新较频繁。个人使用,推荐Ubuntu。

linux的内核目前还在飞速的发展,现在常见的是2.X版本,X为奇数,为不稳定版,x为偶数为稳定版,比如rhel采用的2.4和目前最新的,很多个人桌面采用的2.6。不同的linux发行版本采用的内核不尽相同,比如fedora一般都是采用最新的内核。

linux 日志

查看linux 相关日志涉及到系统安全,是系统管理中非常重要的一部分。

  1. /var/log/auth.log

记录了所有和用户认证相关的日志。无论通过ssh (秘钥) 还是sudo 登录都会在auth.log 中有记录。

  1. 可以记录所有的 sudo 命令的使用情况

sudo使用及日志添加

  1. linux 的登录日志

lastlog引用的是 /var/log/lastlog文件中的信息,包括login-name、port、last login time

last 列出当前和曾经登入系统的用户信息

lastb 列出失败尝试的登录信息

/var/log/btmp

这是一个二进制文件,所以不能直接通过文本编辑器查看其内容。这个文件记录的是所有失败的登录尝试,使用 last 命令及其 -f 选项可以查看这个文件的内容:

1
last -f /var/log/btmp

who 命令

who 命令通过查询 /var/run/utmp 文件来显式系统中当前登录的每个用户。默认的输出包括用户名、终端类型、登录日期及远程主机:

w 命令

如果能够查询到当前登录系统的用户都在干什么是不是一件令人很兴奋的事情呢!使用 w 命令就可以做到:

查看重启情况

1
last reboot

查看 用户登录 情况

1
last | less 

其他

  1. Linux 查看进程被杀死的详情
1
2
3
4
5
6
7
8
dmesg | egrep -i -B100 'killed process'

或:
egrep -i 'killed process' /var/log/messages
egrep -i -r 'killed process' /var/log

或:
journalctl -xb | egrep -i 'killed process'