linux常见操作

测试磁盘性能

测试写性能

1
time dd if=/dev/zero of=test.dbf bs=8k count=300000 oflag=direct

测试读性能

1
dd if=test.dbf of=/dev/null bs=8k count=300000 iflag=direct

GPU管理

如果出现在nvidia-smi的界面下没有进程运行,但是显存不为0,那么可能是有些程序没有正常关闭。一般是python程序或者是jupyter下的程序,可以查看一下,然后杀掉。一般就可以让显存正常释放。

用户管理

增加一个用户

1
useradd -g <初始组名称> -G <附属组名称> -m -d /home/<username> -s /bin/bash <username>
1
2
useradd -g benben -G sudo -m -d /home/zhangsan -s /bin/bash zhangsan
passwd zhangsan

上面新建了一个用户,属于笨笨组的,同时也属于sudo组,拥有sudo权限,是个拥有很高权限的管理员,仅次于root。同时他的目录定义在了/home/zhangsan,同时将shell指定为/bin/bash,第二句话会设置一个密码。

如果只是一个普通的用户,不希望让他拥有sudo权限的话,将-G参数去掉,只让他属于benben组即可。这样这个帐户就无法安装东西,必须联系管理员才能进行安装。

公共工作空间

为了让大家共同合作,可以利用管理员账户建立一个目录,这个目录的组别属于benben,也就是需要合作的人的共同组别。然后将这个目录的属于组修改为benben。

1
chgrp -R benben /mnt/benben

然后再修改这个目录的权限为775,也就是rwx rwx r_x,拥有者和组成员拥有读、写、执行权限,而其他人只拥有读、执行权限。

1
chmod 775 /mnt/benben

为用户增加sudo权限

登陆到root账号,然后输入下面的命令,以zhangsan这个用户为例

1
usermod -G sudo zhangsan

也可以在/etc/group中在sudo后面加上zhangsan

增加用户到另一个用户组中

我新建了一个用户yezhe,然后想要把它增加到用户组sudo中,以便于使用sudo命令,这里需要使用root用户

1
usermod -G sudo yezhe

更改用户的工作目录

需要用root权限

1
usermod -d /home/yezhe yezhe

如果出现一个用户在命令行无法显示名字和路径

这个情况下我在更改了/etc/passwd之后就可以了,也就是给它添加一个shell,一般默认是和root一样用同一个shell:/bin/bash

screen设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# Set default encoding using utf8
defutf8 on


## 解决中文乱码,这个要按需配置
defencoding utf8
encoding utf8 utf8


#兼容shell 使得.bashrc .profile /etc/profile等里面的别名等设置生效
shell -$SHELL

#set the startup message
startup_message off
term linux

## 解决无法滚动
termcapinfo xterm|xterms|xs ti@:te=\E[2J

# 屏幕缓冲区行数
defscrollback 10000

# 下标签设置
hardstatus on
caption always "%{= kw}%-w%{= kG}%{+b}[%n %t]%{-b}%{= kw}%+w %=%d %M %0c %{g}%H%{-}"

#关闭闪屏
vbell off

#Keboard binding
# bind Alt+z to move to previous window
bindkey ^[z prev
# bind Alt+x to move to next window
bindkey ^[x next

# bind Alt`~= to screen0~12
bindkey "^[`" select 0
bindkey "^[1" select 1
bindkey "^[2" select 2
bindkey "^[3" select 3
bindkey "^[4" select 4
bindkey "^[5" select 5
bindkey "^[6" select 6
bindkey "^[7" select 7
bindkey "^[8" select 8
bindkey "^[9" select 9
bindkey "^[0" select 10
bindkey "^[-" select 11
bindkey "^[=" select 12
# bind F5 to create a new screen
bindkey -k k5 screen
# bind F6 to detach screen session (to background)
bindkey -k k6 detach
# bind F7 to kill current screen window
bindkey -k k7 kill``
# bind F8 to rename current screen window
bindkey -k k8 title
  • 在screen中,一个session中可以包含多个windows
  • C-a A 用于修改当前标签的名字
  • C-a k 关闭当前windows

运维方案

  • 这个方案以ubuntu 14.04 为例,并且是使用vultr的服务器。

修改root账号的密码

  • 登录root账号
  • 使用 passwd root命令,即可根据提示修改密码

增加个人用户,并使其拥有sudo权限

1
2
3
useradd -d /home/zhangsan -m zhangsan
passwd zhangsan
usermod -G sudo zhangsan

第一行的命令同时为zhangsan这个账户增加了一个工作目录,第二行为修改密码,第三行为修改这个账户的权限,将其加入到sudo的组中,到此为止一个简单的linxu远程服务器的用户部分就已经配置好了。

查看进程

1
ps aux|grep <name>

查看主机最近一次的启动时间

1
who -b

在高性能服务器上跑训练

标准输出重定向

1
command > out.put 2>&1

command就是我们要跑的程序。out.put就是我们希望把屏幕上输出的内容存入的文件,比如我希望明天一早起来看到一个程序的结尾,但是我又不想改这个程序让其把最后的算法结果存入某个程序(其实就是懒)。2表示标准输出,而1表示标准错误输出。另外提一句0就是表示标准输入,这些都是一个进程的默认的文件描述符,unix中一切皆文件。

如果中间的符号改为>>的话,是以追加的方式写文件。

查看cpu信息

1
cat /proc/cpuinfo

使用nologin运行程序

1
sudo -u nologin <cmd>

top命令

改变RES(实际占用的物理内存大小)

1
2
e 是切换任务区域的
E 切换总结区域的

查看文件夹大小

1
du -h --max-depth=1

公钥登录

生成本地的公钥

1
ssh-keygen

然后将其复制到远程主机上

1
ssh-copy-id -p port username@remotehost

如果有问题的话,可能是.sshauthorized_keys这两个东西的权限的有问题,正常情况下分别是700和600的权限。

可以在linux远程主机上的~/.profile里加上一句话screen -r <name>这样子可以一登录就重启之前启动好的screen。千万不能变成screen -R <name>。否则会陷入死循环。

alias 命令别名

在实际使用中,需要登录的机器的名字太长了,所以可以设置一些别名,用这些别名来代替真正的命令行。

1
vim ~/.bash_profile

然后输入

1
alias to_host="ssh yezhe@remotehost"

保存退出后让其生效

1
source ~/.bash_profile

这时候使用

1
to_host

就可以直接登录了,而且还支持补全代码,也就是tab

locale 设置

生成空白文件

1
dd if=/dev/zero of=hello.txt bs=100M count=1

supervisor

supervisor是一个进程管理,在我们远程登录server的时候会启动一个bash,但是这个bash我们退出ssh之后就消失了,里面的进程也就消失了。于是我们需要一个进程管理,我们将想要启动的进程扔给它,由它来管理即可。screen可以是一个不错的进程管理,可以用来debug,因为它可以前端显示,但是本质也还是后台启动。

但是最近在使用一个开源工具,这个工具的crash的频率比较高,因此需要一个能够自动重启carsh进程的进程管理,那就是supervisor

安装

1
easy_install supervisor

这个命令可以在屏幕上打印出配置信息

1
echo_supervisord_conf

然后将配置输入到/etc路径中,这个需要root权限

1
echo_supservisord_conf > /etc/supervisord.conf

启动

如果supdervirod的二进制文件是安装在系统的PATH下的话,是可以直接启动的

新建一个文件夹/etc/supervisor/
然后在/etc/supervisord.conf中的include项中加入

1
2
[include]
files = /etc/supervisor/*.conf

然后填写一个需要启动的程序的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[program:phantomjs]
directory = /data/pyspider ; 程序的启动目录
command = pyspider -c ./config/pyspider.json phantomjs ; 启动命令,可以看出与手动在命令行启动的命令是一样的
autostart = true ; 在 supervisord 启动的时候也自动启动
startsecs = 5 ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true ; 程序异常退出后自动重启
startretries = 3 ; 启动失败自动重试次数,默认是 3
user = yezhe ; 用哪个用户启动
redirect_stderr = true ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /data/pyspider/log/phantomjs.log

; 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改 PYTHONPATH
; environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere

输出日期

1
2
echo `date`
echo `date +%Y-%m-%d-%H-%M-%S`

cron command not found

这个问题的原因在于cron在运行时的环境变量不一样,其中的$PATH会被

查看当前文件夹下的文件个数和文件夹个数

1
ls -l |grep "^-"|wc -l

转载自http://blog.sina.com.cn/s/blog_464f6dba01012vwv.html
统计某文件夹下文件的个数

1
ls -l |grep "^-"|wc -l

统计某文件夹下目录的个数

1
ls -l |grep "^d"|wc -l

统计文件夹下文件的个数,包括子文件夹里的

1
ls -lR|grep "^-"|wc -l

如统计/home/han目录(包含子目录)下的所有js文件则:

1
ls -lR /home/han|grep js|wc -l 或 ls -l "/home/han"|grep "js"|wc -l

统计文件夹下目录的个数,包括子文件夹里的

1
ls -lR|grep "^d"|wc -l

说明:

1
ls -lR

长列表输出该目录下文件信息(R代表子目录注意这里的文件,不同于一般的文件,可能是目录、链接、设备文件等)

1
grep "^-"

这里将长列表输出信息过滤一部分,只保留一般文件,如果只保留目录就是 ^d

1
wc -l

统计输出信息的行数,因为已经过滤得只剩一般文件了,所以统计结果就是一般文件信息的行数,又由于一行信息对应一个文件,所以也就是文件的个数。

======================================
如果只查看文件夹
ls -d 只能显示一个.
find -type d 可以看到子文件夹
ls -lF |grep /ls -l |grep '^d' 只看当前目录下的文件夹,不包括往下的文件夹

sudo无法解析主机名字

修改/etc/hosts中的一行

先打开/etc/hostname,其中包括一个主机名字

然后在/etc/hosts中保证有一行

1
127.0.1.1    <主机名字>

查看正在使用的端口

1
sudo netstat -anltp | grep "LISTEN"

安装nvidia GTX1080驱动

1
2
3
4
sudo apt-get purge nvidia-*
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update
sudo apt-get install nvidia-375

cuda 8.0 安装

1
2
3
4
wget https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb
sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb
sudo apt-get update
sudo apt-get install cuda

安装完成之后还需要添加环境变量

1
vim ~/.bashrc

在文件的最后添加两行

1
2
export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-8.0.61/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

然后在当前的bash中执行会让修改生效,或者可以打开新的bash

1
source ~/.bashrc

cuda的下载链接
cuda 7.5 for ubuntu 14.04

1
http://developer.download.nvidia.com/compute/cuda/7.5/Prod/local_installers/cuda-repo-ubuntu1404-7-5-local_7.5-18_amd64.deb

cudnn 5.0 for cuda 7.5

1
http://developer.download.nvidia.com/compute/machine-learning/cudnn/secure/v5/prod/cudnn-7.5-linux-x64-v5.0-ga.tgz?autho=1491911109_39b0ac86b2d9e816a24be1fb8148a31c&file=cudnn-7.5-linux-x64-v5.0-ga.tgz

cudnn 5.1 for cude 8.0

1
http://developer.download.nvidia.com/compute/machine-learning/cudnn/secure/v5.1/prod_20161129/8.0/cudnn-8.0-linux-x64-v5.1.tgz?autho=1491911192_c4362e4d2c81a2d3c463a819201b25e6&file=cudnn-8.0-linux-x64-v5.1.tgz

错误

如果出现了以下错误

1
/sbin/ldconfig.real: /usr/lib32/nvidia-375/libEGL.so.1 is not a symbolic link

可以使用下面的命令来尝试解决

1
2
3
4
sudo mv /usr/lib/nvidia-375/libEGL.so.1 /usr/lib/nvidia-375/libEGL.so.1.org
sudo mv /usr/lib32/nvidia-375/libEGL.so.1 /usr/lib32/nvidia-375/libEGL.so.1.org
sudo ln -s /usr/lib/nvidia-375/libEGL.so.375.39 /usr/lib/nvidia-375/libEGL.so.1
sudo ln -s /usr/lib32/nvidia-375/libEGL.so.375.39 /usr/lib32/nvidia-375/libEGL.so.1

建立http代理服务器

1
sudo pip install shadowsocks

然后建立新的json文件

1
2
3
4
5
6
7
8
{
"server":"my_server_ip",
"server_port":8388,
"local_port":1080,
"password":"barfoo!",
"timeout":600,
"method":"rc4-md5"
}

启动sslocal

1
sudo sslocal -c yezhe.json -d start

1
2
3
sudo apt-get install polipo
sudo service polipo stop
sudo polipo socksParentProxy=localhost:1080

然后就可以在命令前面加上代理的信息http_proxy=http://localhost:8123

1
http_proxy=http://localhost:8123 apt-get update

解压 .gz

1
gzip -d <input>

并行压缩软件

pigz
可以将tar并行地压缩成tar.gz

统计文件内的文件个数

ls -lR feat|grep "^-"|wc -l

NFS配置

我现在有多台GPU机器,为了能够方便地在各个机器上启动我的程序,我决定采用NFS的方式来共享我的数据。

Server端安装

1
sudo apt-get install nfs-kernel-server

客户端

1
sudo apt install nfs-common

利用conda安装requirements

这个方法可以自动安装依赖

1
while read requirement; do conda install --yes $requirement; done < requirements.txt

分享到