常用指令

文件相关

输出文件夹所有文件名到txt

若是相对路径

1
ls > filenames.txt

若想包含绝对路径,后面的*.jpg是必须的

1
ls -R /path/*.jpg > test_trigger.txt

Linux 下的 file flags

可能你也遇到过在 Linux 下删除文件报错:

1
2
root@ubuntu:/home/barret/work# rm -f 1.md 
rm: cannot remove ‘1.md’: Operation not permitted

这个时候可以通过 lsattr 命令看看该文件是否被打了 flags:

1
2
root@ubuntu:/home/barret/work# lsattr 1.md
----i--------e-- ./1.md

如果文件上存在 i 标记,那肯定是删不掉的,同样这个文件也不能被编辑。可以进入 root 模式,去除这个标记:

1
root@ubuntu:/home/barret/work# chattr -i 1.md

给保护文件添加标记的方式:

1
root@ubuntu:/home/barret/work# chattr +i 1.md

软硬连接

硬链接

硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。

1
ln 源文件 目标文件

例如,建立一个硬连接/usr/local/bin/less指向/bin/less。当删除源文件/bin/less时,目标文件无影响。

1
ln /bin/less /usr/local/bin/less

软连接

另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。

1
ln -s 源文件 目标文件

例如,建立一个软连接/usr/local/bin/less指向/bin/less。当删除源文件/bin/less时,目标文件有影响。

1
ln -s /bin/less /usr/local/bin/less

合并两个目录

假设有两个目录,这些文件夹中的每一个都包含图像,并且images和images2下的目录名称完全相同,但是它们的内容不同。然后我想知道如何才能将/Images2/ad的图像复制合并到images/ad中,将/Images2/foo的图像复制合并到images/foo中,以此类推。

1
2
3
4
5
6
7
8
9
# 目录1
/images/ad
/images/fe
/images/foo

# 目录2
/images2/ad
/images2/fe
/images2/foo

最好的方法是使用rsync指令。

1
2
rsync -avh --progress /path/to/source/ /path/to/destination/  # 一定要注意目录结尾的/
rsync -avh --progress /images2/ /images/

-a means “archive” and copies everything recursively from source to destination preserving nearly everything.

-v gives more output (“verbose”).

-h for human readable.

—progress to show how much work is done.

If images with the same name exist in both directories, the command above will overwrite /images/SOMEPATH/SOMEFILE with /images2/SOMEPATH/SOMEFILE. If you want to replace only older files, add the option -u. If you want to always keep the version in /images, add the option --ignore-existing.

If you want to move the files from /images2, with rsync, you can pass the option --remove-source-files. Then rsync copies all the files in turn, and removes each file when it’s done. This is a lot slower than moving if the source and destination directories are on the same filesystem.

删除全部文件夹或者文件

假设我们有一个目录是下面这个样子。

1
2
3
4
5
6
dir
subdir1 <--directory
subdir2 <--directory
file.txt <--file
foo.mp3 <--file
bar.pdf <--file

如想要删除所有子文件夹,但是保存所有文件。可以使用指令:

1
rm -r dir/*/

若想删除所有文件,但保留所有子文件夹。可以使用指令:

1
# 待补充

Argument list too long

当使用mv等指令时,若文件太多,就会提示Argument list too long,遇到这个问题,采用如下方式解决:

1
2
3
4
$ ulimit -s
8192

$ ulimit -s 65536

系统相关

取消export

比如已经export了

1
export KUBECONFIG="/etc/kubernetes/admin.conf"

则可以使用unset取消,当然它值针对当前环境有效。

1
2
unset KUBECONFIG
# 此时echo $KUBECONFIG为空

watch

我们设置为每 10s 显示一次显存的情况

1
watch -n 10 nvidia-smi

终端打开文件管理器

1
2
# 适合于ubuntu
sudo nautilus

source缩写

source指令的缩写为.(点空格),例如:

1
2
3
source venv/bin/activate
# 等价于如下指令,不要忘了 . 后面的空格。
. venv/bin/activate

添加字符集

locale -a可以列出来当前系统支持的字符集,若运行程序时用到了系统不支持的字符集,可能会报错:terminate called after throwing an instance of 'std::runtime_error' what(): locale::facet::_S_create_c_locale name not valid,这个时候需要添加字符集,操作如下。

For a small server that did not support the locale I needed (locale -a did not list it), all I had to do was run

1
sudo dpkg-reconfigure locales

which provided text-based dialogues that I could select from (page up/down, up/down, space to select, tab to OK, and Enter to save). It automatically regenerated the locales.

As others have stated, you will need to restart any process that needs the new locale.

另外一种方式是:执行apt-cache search language-pack,然后装对应的包,但是这样装不上zh_CN.gb2312等。

更改locale

若想要临时更改locale指令的结果,可以执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
zhaodali@ubuntua:baseline_custom_voice$ export LC_ALL="en_US.UTF-8" 
zhaodali@ubuntua:baseline_custom_voice$ locale
# 输出结果:
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8

或者说另外一种字符集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
zhaodali@ubuntua:baseline_custom_voice$ export LC_ALL="C"
zhaodali@ubuntua:baseline_custom_voice$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=C

查看剩余内存

free -g:以GB显示剩余内存大小

free -m:以MB显示剩余内存大小

查看CPU相关信息

总核数 = 物理CPU个数 X 每颗物理CPU的核数

总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数

【物理CPU数量】

1
2
$ cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
1

【物理CPU内核的个数】(1个物理CPU里面有几个物理内核,即Core)

1
2
$ cat /proc/cpuinfo| grep "cpu cores"| uniq
cpu cores : 10

【查看所有逻辑CPU的个数】

1
2
$ cat /proc/cpuinfo| grep "processor"| wc -l
10

【逻辑CPU数量和型号】

1
2
$ cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
10 Intel(R) Xeon(R) Platinum 8255C CPU @ 2.50GHz

【物理CPU中逻辑CPU的个数】(如果不使用超线程技术,则此值和物理CPU内核数量一致;不一致则为整倍数)

1
2
$ cat /proc/cpuinfo | grep 'siblings' | uniq
siblings : 10

【超线程】(分别输出cpu cores和siblings数量,使用超线程则后者翻倍)

1
2
3
$ cat /proc/cpuinfo | grep -e "cpu cores" -e "siblings" | sort | uniq
cpu cores : 10
siblings : 10

Planck服务器:

1
2
3
4
5
6
7
8
【逻辑CPU数量和型号】56  Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
【物理CPU数量】2
【物理CPU内核的个数】cpu cores : 14
【查看所有逻辑CPU的个数】56
【物理CPU中逻辑CPU的个数】siblings : 28
【超线程】cpu cores : 14 / siblings : 28

# 两个物理CPU,每个物理CPU含有14个物理内核和28个逻辑处理器,因此对外共有2*14*2=56个逻辑处理器

DGX服务器:

1
2
3
4
5
6
7
8
【逻辑CPU数量和型号】40  Intel(R) Xeon(R) CPU E5-2698 v4 @ 2.20GHz
【物理CPU数量】1
【物理CPU内核的个数】cpu cores : 20
【查看所有逻辑CPU的个数】40
【物理CPU中逻辑CPU的个数】siblings : 40
【超线程】cpu cores : 20 / siblings : 40

# 只有一个物理CPU,含有20个物理核,使用了超线程技术即40个逻辑处理器

GPU和CPU对应

有些服务器可能有多个CPU,多个GPU。通过下面指令可以查看CPU和GPU的对应关系。

1
nvidia-smi topo -m

GPU进程

有的时候,比如说当使用PyTorch时,有时候会在控制台终止掉正在运行的程序,明明程序已经结束了,nvidia-smi 也看到没有程序了,但是GPU的内存并没有释放。这是为啥呢?

这是因为使用PyTorch设置多线程进行数据读取,其实是假的多线程,他是开了N个子进程(PID都连着)进行模拟多线程工作,所以你的程序跑完或者中途kill掉主进程的话,子进程的GPU显存并不会被释放,需要手动一个一个kill才行,具体方法描述如下:

使用如下指令发现僵尸进程。

1
2
yum -y install psmisc
fuser -v /dev/nvidia*

然后使用 kill -9 pid 杀死僵尸进程,当僵尸进程比较多时,上述命令重复输入显得非常繁琐,使用下属命令一句话杀死所有进程:

1
fuser -v /dev/nvidia* |awk '{for(i=1;i<=NF;i++)print "kill -9 " $i;}' | sh

如果需要权限,命令更改如下:

1
sudo fuser -v /dev/nvidia* |awk '{for(i=1;i<=NF;i++)print "kill -9 " $i;}' | sh

若这种方法,不管用的话,还可以使用nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv指令来看僵尸进程。

ldd查看程序依赖库

作用:用来查看程式运行所需的共享库,常用来解决程式因缺少某个库文件而不能运行的一些问题。

示例:查看test程序运行所依赖的库:

1
2
3
4
5
6
/opt/app/todeav1/test$ldd test
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00000039a7e00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003996400000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000039a5600000)
libc.so.6 => /lib64/libc.so.6 (0x0000003995800000)
/lib64/ld-linux-x86-64.so.2 (0x0000003995400000)
  • 第一列:程序需要依赖什么库
  • 第二列: 系统提供的与程序需要的库所对应的库
  • 第三列:库加载的开始地址

通过上面的信息,我们可以得到以下几个信息:

  1. 通过对比第一列和第二列,我们可以分析程序需要依赖的库和系统实际提供的,是否相匹配
  2. 通过观察第三列,我们可以知道在当前的库中的符号在对应的进程的地址空间中的开始位置

如果依赖的某个库找不到,通过这个命令可以迅速定位问题所在。例如下面例子,可以看出来libqqseg.so等动态库找不到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
zhaodali@ubuntua:baseline_custom_voice$ bash ./run.sh run.json                                                                                                                                     
/mnt/private_zhaodali_sz/lfe_lab/build/linux/debug/x86_64/lfe_tools: error while loading shared libraries: libqqseg.so: cannot open shared object file: No such file or directory

zhaodali@ubuntua:baseline_custom_voice$ ldd /mnt/private_zhaodali_sz/lfe_lab/build/linux/debug/x86_64/lfe_tools
linux-vdso.so.1 (0x00007ffcdd37c000)
/$LIB/libonion.so => /lib/x86_64-linux-gnu/libonion.so (0x00007f46e130a000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f46e12dc000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f46e12d6000)
libqqseg.so => not found
libc10.so => not found
libtorch_cpu.so => not found
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f46e1185000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f46e0fa3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f46e0f88000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f46e0d96000)
/lib64/ld-linux-x86-64.so.2 (0x00007f46e1412000)

ldconfig

ldconfig 命令的用途主要是在默认搜寻目录 /lib 和 /usr/lib 以及动态库配置文件 /etc/ld.so.conf 内所列的目录下,搜索出可共享的动态链接库(格式如 lib.so),进而创建出动态链接器(ld.so 或 ld-linux.so)所需的缓存文件。缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表,为了让动态链接库为系统所共享,需运行动态链接库的管理命令 ldconfig 更新动态链接库的缓存文件,此执行程序存放在 /sbin 目录下。ldconfig 通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。

常用指令:

1
2
# 刷新动态链接库缓存文件 /etc/ld.so.cache
sudo ldconfig

注意事项:

(1)往 /lib 和 /usr/lib 里面加动态链接库,是不用修改 /etc/ld.so.conf的,但是完了之后要调一下 ldconfig,不然这个 library 会找不到。

(2)想往上面两个目录以外加东西的时候,一定要修改 /etc/ld.so.conf,然后再调用 ldconfig,不然也会找不到。

比如安装了一个 mysql 到 /usr/local/mysql,mysql 有一大堆 library在 /usr/local/mysql/lib 下面,这时就需要在 /etc/ld.so.conf 里面加一行 /usr/local/mysql/lib,保存过后执行 ldconfig 更新一下动态链接库缓存 /etc/ld.so.cache,新的 library 才能在程序运行时被找到。

(3)如果想在 /lib 和 /usr/lib 这两个目录以外放 lib,并且又不想在 /etc/ld.so.conf 中加动态链接库的目录(或者是没有权限加)。那么可以 export 一个全局变量 LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找 library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。

(4)ldconfig 更新动态链接库的缓存文件只与程序运行时有关,跟编译时没有关系。编译时需要加 -L 就得加,不要混淆了。

(5)总之,就是不管做了什么关于 library 的变动后,最好都 ldconfig 一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。

查看某个lib是否存在

1
2
ldconfig -p | grep libjpeg
# ldconfig -p | grep cudnn

killall

删除某个用户的所有进程:

1
killall -u username

网络相关

ping指令

ping用到的是ICMP协议。不是端口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Usage: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS] 
[-r count] [-s count] [[-j host-list] | [-k host-list]]
[-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name

Options:
-t Ping the specified host until stopped.
To see statistics and continue - type Control-Break;
To stop - type Control-C.
-a Resolve addresses to hostnames.
-n count Number of echo requests to send.
-l size Send buffer size.
-f Set Don't Fragment flag in packet (IPv4-only).
-i TTL Time To Live.
-v TOS Type Of Service (IPv4-only).
-r count Record route for count hops (IPv4-only).
-s count Timestamp for count hops (IPv4-only).
-j host-list Loose source route along host-list (IPv4-only).
-k host-list Strict source route along host-list (IPv4-only).
-w timeout Timeout in milliseconds to wait for each reply.
-R Trace round-trip path (IPv6-only).
-S srcaddr Source address to use (IPv6-only).
-4 Force using IPv4.
-6 Force using IPv6.

在Linux下输入下面两句

1
2
iptables -A INPUT -i eth+ -p icmp --icmp-type 8 -j ACCEPT
iptables -A OUTPUT -o eth+ -p icmp --icmp-type 0 -j ACCEPT

就可以打开所有网卡的Ping功能了

使用Ping检查连通性有六个步骤:

  1. 使用 ifconfig观察本地网络设置是否正确;
  2. Ping 127.0.0.1,127.0.0.1回送地址Ping回送地址是为了检查本地的TCP/IP协议有没有设置好;
  3. Ping本机IP地址,这样是为了检查本机的IP地址是否设置有误;
  4. Ping本网网关或本网IP地址,这样的是为了检查硬件设备是否有问题,也可以检查本机与本地网络连接是否正常;(在非局域网中这一步骤可以忽略)
  5. Ping本地DNS地址,这样做是为了检查DNS是否能够将IP正确解析。
  6. Ping远程IP地址,这主要是检查本网或本机与外部的连接是否正常。

检查端口开启/占用状态

如果想使用如下指令,对应的端口需要有相应的监听程序,才能检查出来。

lsof

1
2
3
4
lsof -i:6379 # 如果有显示说明已经开放了,如果没有显示说明没有开放

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 431717 root 4u IPv4 133236252 0t0 TCP *:6379 (LISTEN)

也可以使用lsof -i命令直接将开放的端口输出,来查看某些端口是否开放。

netstat

1
2
3
4
5
6
7
8
9
netstat -apn | grep 8080

-a:所有的套接字
-t :TCP连接
-u:UDP连接
-p: 显示进程或程序名的相关PID

# 输出,后面这个20500是PID
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 20500/python

如果它有输出,则证明端口占用了。

telnet

1
2
3
4
5
telnet 127.0.0.1 6379 # telnet IP 端口号
输出
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

捕捉端口数据

假设某服务器开放端口是808,之前该服务器作为kafka的客户端,接收过kafka数据。后续因为某种特殊原因,客户端程序已经断了,但是kafka服务端仍在发数据。此时若使用uvicorn+fastapi开启web服务,服务端口是808,会一直遇到WARNING: Invalid HTTP request received.

调试uvicorn代码,发现一直会有b'\x00\x00\x00$\x00\x12\x00\x03\x00\x00\x016\x00\x07rdkafka\x00\x0blibrdkafka\x061.5.3\x00'数据到来,但是不清楚该数据的服务端是哪,此时就需要捕捉端口数据了。

1
2
3
apt install tcpflow
# eth1替换为对应的网卡
tcpflow -c -i eth1 port 808

等待一段时候后,在./report.xml文件可以查看捕捉到的数据了,其中包含IP以及mac地址等信息。

查看局域网所有IP和用户名

首先,安装nmap,命令如下:

1
sudo apt install nmap

使用ifconfig命令得知当前电脑的IP地址为192.168.123.188,则使用如下命令得知与当前电脑所有同在一个局域网的IP地址和用户名:

1
sudo nmap -sL 192.168.123.*

返回的部分结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ sudo nmap -sL 192.168.123.*

Starting Nmap 7.60 ( https://nmap.org ) at 2020-02-13 18:58 CST
Nmap scan report for 192.168.123.0
Nmap scan report for RT-AC54U.lan (192.168.123.1)
Nmap scan report for chuangmi-plug-m1_miio61456883.lan (192.168.123.2)
Nmap scan report for 192.168.123.3
Nmap scan report for 192.168.123.4
Nmap scan report for 192.168.123.5
Nmap scan report for 192.168.123.6
Nmap scan report for 192.168.123.7
Nmap scan report for mxq-station-ubuntu.lan (192.168.123.8)
Nmap scan report for 192.168.123.9
Nmap scan report for 192.168.123.10
....

可以看到,还上面还有一台电脑连接着,IP地址为192.168.123.8,用户为mxq-station-ubuntu

存储相关

tree

此时如果想打印某个目录下的所有文件,可以使用tree命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
[liudiwei@master _code]$ tree
.
`-- preprocessing
|-- compareTwoFile.py
|-- download.py
|-- extractChainFromSeq.py
|-- extractSeqByChain.py
|-- formatChain.py
|-- generateSeqFromDSSP.py
|-- getProteinFromChain.py
|-- getProteinNameFromDir.py
|-- pdbToDSSP.py
`-- _README.txt

此外,如果只想要显示目录的话,可以使用添加-d参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[liudiwei@master DNA_BP]$ tree -d
.
|-- _code
| `-- preprocessing
|-- _data
| `-- Exp_DBPI
| |-- DBPI_Datasets
| |-- dssp_testset
| | `-- format
| |-- dssp_trainset
| | `-- format
| |-- pdb_testset
| `-- pdb_trainset
|-- _feature
| `-- feature_extraction
`-- paper_Graham

14 directories

若想显示特定的深度:

1
2
# 例:显示深度为3级:
tree -L 3

如果你不想看到全部的文件?可以加上“-P 通配符”的方法来只列出某种文件:

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
[liudiwei@master DNA_BP]$ tree -P "*.py"
.
|-- _code
| `-- preprocessing
| |-- compareTwoFile.py
| |-- download.py
| |-- extractChainFromSeq.py
| |-- extractSeqByChain.py
| |-- formatChain.py
| |-- generateSeqFromDSSP.py
| |-- getProteinFromChain.py
| |-- getProteinNameFromDir.py
| `-- pdbToDSSP.py
|-- _data
| `-- Exp_DBPI
| |-- DBPI_Datasets
| |-- dssp_testset
| | `-- format
| |-- dssp_trainset
| | `-- format
| |-- pdb_testset
| `-- pdb_trainset
|-- _feature
| `-- feature_extraction
`-- paper2015_Graham

查看分区的剩余空间大小

1
2
3
4
5
# 大小以MB和GB为单位
df -hl
ls -lh
# 如果df -hl看不到有些目录, 则尝试
df -ah

查看当前路径下,最大深度为1查看各个文件夹所占大小

1
2
3
4
5
6
7
8
du -h --max-depth=1 .
显示结果为:
6.1G ./anaconda36
46G ./Code
4.0K ./ft_local
6.0G ./anaconda3
1.1G ./usr
59G .

如果遇到df -hl指令卡住,可以使用如下方法找卡到哪了。

1
2
3
4
5
# 首先就是使用strace去追踪到底在哪里卡住了
strace df -h

# 如果没有strace命令则进行安装即可
yum install strace

统计文件夹下的文件数目

  • 统计当前目录下文件的个数(不包括子目录)
1
ls -l | grep "^-" | wc -l
  • 统计当前目录下文件的个数(包括子目录)
1
ls -lR| grep "^-" | wc -l
  • 查看某目录下文件夹(目录)的个数(包括子目录)
1
ls -lR | grep "^d" | wc -l

查看文件夹大小

在linux中经常使用ls -l 或者ls -alh查看文件大小,但是文件列表中有目录的时候就会发现显示的文件夹大小和实际文件大小不对应,文件夹的大小很多都是相等的,其实这是因为ls -l命令显示的是文件夹作为目录占用磁盘空间的大小。可以使用du -h命令查看,该命令会查询目录里所有文件大小并累加。

du -h --max-depth=1:—max-depth=<目录层数> 超过指定层数的目录后,予以忽略。

查看文件夹下的文件类型

参考recursive statistics on file types in directory?

1
2
3
4
5
6
7
8
9
10
11
12
13
find . -type f -printf '%f\n' | sed -r -n 's/.+(\..*)$/\1/p' | sort | uniq -c | sort -bn

# 输出结果
85 .json
94 .golden
224 .tq
262 .py
335 .mjs
365 .out
988 .txt
1732 .h
1794 .cc
8452 .js

搜索查找相关

find

一些常用的实例如下:

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
find -name april*                      在当前目录下查找以april开始的文件
find . -name "*.pth" 在当前目录下查找以pth结尾的文件
find -name april* fprint file        在当前目录下查找以april开始的文件,并把结果输出到file中
find -name ap* -o -name may* 查找以ap或may开头的文件
find /mnt -name tom.txt -ftype vfat 在/mnt下查找名称为tom.txt且文件系统类型为vfat的文件
find /mnt -name t.txt ! -ftype vfat   在/mnt下查找名称为tom.txt且文件系统类型不为vfat的文件
find /tmp -name wa* -type l           在/tmp下查找名为wa开头且类型为符号链接的文件
find /home -mtime -2                 在/home下查最近两天内改动过的文件
find /home   -atime -1                  查1天之内被存取过的文件
find /home -mmin   +60                  在/home下查60分钟前改动过的文件
find /home -amin +30                  查最近30分钟前被存取过的文件
find /home -newer tmp.txt             在/home下查更新时间比tmp.txt近的文件或目录
find /home -anewer tmp.txt            在/home下查存取时间比tmp.txt近的文件或目录
find /home -used -2                  列出文件或目录被改动过之后,在2日内被存取过的文件或目录
find /home -user cnscn                列出/home目录内属于用户cnscn的文件或目录
find /home -uid +501                 列出/home目录内用户的识别码大于501的文件或目录
find /home -group cnscn              列出/home内组为cnscn的文件或目录
find /home -gid 501                   列出/home内组id为501的文件或目录
find /home -nouser                    列出/home内不属于本地用户的文件或目录
find /home -nogroup                   列出/home内不属于本地组的文件或目录
find /home   -name tmp.txt   -maxdepth 4 列出/home内的tmp.txt 查时深度最多为3层
find /home -name tmp.txt -mindepth 3 从第2层开始查
find /home -empty                     查找大小为0的文件或空目录
find /home -size +512k               查大于512k的文件
find /home -size -512k               查小于512k的文件
find /home -links +2                 查硬连接数大于2的文件或目录
find /home -perm 0700                查权限为700的文件或目录
find /tmp -name tmp.txt -exec cat {} /;
find /tmp -name tmp.txt -ok rm {} /;

find   / -amin   -10       # 查找在系统中最后10分钟访问的文件
find   / -atime -2         # 查找在系统中最后48小时访问的文件
find   / -empty              # 查找在系统中为空的文件或者文件夹
find   / -group cat        # 查找在系统中属于 groupcat的文件
find   / -mmin -5         # 查找在系统中最后5分钟里修改过的文件
find   / -mtime -1        #查找在系统中最后24小时里修改过的文件
find   / -nouser             #查找在系统中属于作废用户的文件
find   / -user   fred       #查找在系统中属于FRED这个用户的文件

Grep

非递归搜索包含指定字符串的文件

第一个例子让我们来搜索 /etc/ 目录下所有包含 stretch 字符串的文件,但不去搜索其中的子目录:

1
2
3
# grep -s stretch /etc/*
/etc/os-release:PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
/etc/os-release:VERSION="9 (stretch)"

grep 的 -s 选项会在发现不存在或者不能读取的文件时隐藏报错信息。结果显示除了文件名之外,还有包含请求字符串的行也被一起输出了。

递归地搜索包含指定字符串的文件

上面案例中忽略了所有的子目录。所谓递归搜索就是指同时搜索所有的子目录。

下面的命令会在 /etc/ 及其子目录中搜索包含 stretch 字符串的文件:

1
grep -R stretch /etc/*

搜索所有包含特定单词的文件

上面 grep 命令的案例中列出的是所有包含字符串 stretch 的文件。也就是说包含 stretches , stretched 等内容的行也会被显示。 使用 grep 的 -w 选项会只显示包含特定单词的行:

1
2
3
4
5
6
7
8
9
10
11
12
# grep -Rw stretch /etc/*
/etc/apt/sources.list:# deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:#deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:deb http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb-src http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb http://security.debian.org/debian-security stretch/updates main
/etc/apt/sources.list:deb-src http://security.debian.org/debian-security stretch/updates main
/etc/dictionaries-common/words:stretch
/etc/dictionaries-common/words:stretch's
/etc/grub.d/00_header:background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
/etc/os-release:PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
/etc/os-release:VERSION="9 (stretch)"

显示包含特定文本的文件名

上面的命令都会产生多余的输出。下一个案例则会递归地搜索 etc 目录中包含 stretch的文件并只输出文件名:

1
2
3
4
5
# grep -Rl stretch /etc/*
/etc/apt/sources.list
/etc/dictionaries-common/words
/etc/grub.d/00_header
/etc/os-release

账号相关

创建新用户

  1. 在root权限下,useradd只是创建了一个用户名,如 (useradd +用户名 ),它并没有在/home目录下创建同名文件夹,也没有创建密码,因此利用这个用户登录系统,是登录不了的,为了避免这样的情况出现,可以用 (useradd -m +用户名)的方式创建,它会在/home目录下创建同名文件夹,然后利用( passwd + 用户名)为指定的用户名设置密码。
  2. 可以直接利用adduser创建新用户(adduser +用户名)这样在/home目录下会自动创建同名文件夹。

例如:此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录 /home/sam(/home为默认的用户主目录所在的父目录)。

1
useradd -d /home/sam -m sam

为用户添加sudo权限(sudo是在当前用户环境下执行root指令):

1
2
3
sudo usermod -G sudo username 
# 在centos下
usermod -aG wheel username

更改用户默认目录

Linux下默认的用户目录一般为/home/xxx(root用户除外),有些时候我们可能需要修改这个目录,下面我就给大家分享2种修改的方法

1、切换到root用户,直接修改/etc/passwd文件,找到你的用户名你一行,修改路径,然后保存即可。

2、切换到root用户,使用usermod命令,例如usermod -d /tmp test (test为你的用户名),使用该命令请确保该用户下没有运行的软件或进程。

最后切换到普通账户,就会看到当前默认目录已经更改了。

遇到每次登录,bashrc文件不生效的情况。可以输入:vim ~/.bash_profile,然后在其中加上:

1
2
3
if [ -f ~/.bashrc ] ; then
source .bashrc
fi

修改密码

1
2
3
4
# 超级权限登陆
sudo su

passwd + 用户名(非root)

修改终端中用户名和主机名

~/.bashrc文件进行修改,主要修改一下这句

1
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

\u 当前登录用户名 \h 当前计算机名称(譬如ubuntu)

例如,在~/.bashrc文件中添加如下一行:

1
2
# 若\w改为\W,则显示段路径
export PS1='${debian_chroot:+($debian_chroot)}zhaodali@ubuntu:\w\$ '

这样终端显示为:

1
zhaodali@ubuntu:~$

查看uid与gid

1
2
3
4
5
id +账户名

# 比如说
# id root
uid=0(root) gid=0(root) groups=0(root)

gid 只是当前工作主工作组的展示, 而groups 包含了用户所在的所有组。

修改uid与gid

1
2
usermod -u 1000 zd
groupmod -g 1000 zd

删除用户

例:删除用户user2

1
userdel user2

例:删除用户user3,同时删除他的工作目录

1
userdel –r user3

newgrp命令

Linux newgrp 命令用于登入另一个群组。newgrp 指令类似 login 指令,但它是以相同的帐号,另一个群组名称,再次登入系统。欲使用 newgrp 指令切换群组,您必须是该群组的用户,否则将无法登入指定的群组。单一用户要同时隶属多个群组,需利用交替用户的设置。若不指定群组名称,则 newgrp 指令会登入该用户名称的预设群组。

语法

1
newgrp [群组名称]

实例

改变群组

1
$ newgrp root

用户在/etc/passwd无法找到

That is because the users database is stored elsewhere, for example an LDAP. Use getent passwd $USER to resolve your user.

参考

【整理】ubuntu ln命令简单学习
如何在linux下查看目录的剩余空间大小
Linux统计文件夹下的文件数目)
How to send list of file in a folder to a txt file in Linux
Display list of computers on a LAN in Linux
ldd 查看程序依赖库
“Argument list too long”: How do I deal with it, without changing my command?
linux查看目录大小 linux统计目录大小并排序 查看目录下所有一级子目录文件夹大小 du -h —max-depth=1 |grep []
linux 查找目录或文件
修改或隐藏Linux终端命令行中的用户名和主机名
How do I add locale to ubuntu server?
解决方案: locale::facet::_S_create_c_locale name not valid
Linux下如何修改用户默认目录
How to copy-merge two directories?
How to delete sub-folders but keep all the files?
linux df -h 命令卡住 解决方法
ldconfig 命令
Listening to port and capturing data in python
What is the ‘dot space filename’ command doing in bash?
Linux系统查看CPU个数&超线程&线程数
【转载】解决Nvidia-smi没有进程但是显存不释放的问题
Nvidia-smi doesn’t show GPU Memory Usage and full path for Process Names [closed]
How to check if a library is installed?

------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道