1.Linux基础命令
# 1. 基本常识
$
:普通用户#
:超级用户root~
:用户家目录/
:系统根目录
# 1.1 命令行中的快捷键
Ctrl + a : 定位行首
Ctrl + e : 定位行尾
Ctrl + f : 光标向前移动
Ctrl + b : 定位向后移动
Ctrl + d : 删除光标所在的字符
Ctrl + t : 交换光标所在位置与其前面的字符
Ctrl + u / k : 剪切光标前的和光标后的所有字符
Ctrl + y : 粘贴
若改成Alt + d/t : 对单词的操作
Alt + l / u : 改成小写/大写(注意,改写的范围为光标所在位置到当前单词的结尾)
Ctrl + l: = clear
# 2. 常用命令
# 2.1 查看命令
# 2.2.1 文件函数查看
man
:查看命令行、库函数、系统调用的用户手册
man -k(keyword)
=apropos
显示所有的匹配函数,类似一个目录:[test@VM-12-4-centos ~]$ apropos printf asprintf (3) - print to allocated string [test@VM-12-4-centos ~]$ man 3 asprintf
1
2
3
info
[test@VM-12-4-centos ~]$ info ls
1上下键翻页、u上级目录、n/p下一个和上一个node、带
*
可以按回车键进入
ls
[test@VM-12-4-centos ~]$ ls [!.]* # 过滤掉含.的文件 [test@VM-12-4-centos ~]$ ls -l $(which mkdir) -rwxr-xr-x 1 root root 79768 Nov 17 2020 /usr/bin/mkdir # 通配符 * ? [char] [!char] [:digit:] [test@VM-12-4-centos first]$ ls -l -rwxrwxr-x 1 test test 8408 May 30 18:42 main [test@VM-12-4-centos first]$ ls -nl # 用uid代替用户名,gid代替所属组名 -rwxrwxr-x 1 1001 1001 8408 May 30 18:42 main
1
2
3
4
5
6
7
8
9
10
stat
Access:文件最近被访问的时间;最新的系统中,不会立即更新,有一定时间间隔OS才会更新时间,防止过多系统资源的消耗。
Modify:最近一次修改文件内容的时间,修改内容时也可能修改属性(文件大小等)。应用场景:make 时会对比可执行文件时间和源文件时间,判断是否继续make
Change:最近一次修改文件属性的时间
[test@VM-12-4-centos 123]$ stat test.c File: ‘test.c’ Size: 1032 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 1577177 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1001/ test) Gid: ( 1001/ test) Access: 2022-05-28 11:15:22.725417793 +0800 # # 查看file的时间 使用可以touch更改时间 Modify: 2022-04-04 11:45:50.076246419 +0800 Change: 2022-04-04 11:45:50.093246362 +0800 Birth: -
1
2
3
4
5
6
7
8
9
file
[test@VM-12-4-centos 123]$ file test.c test.c: C source, ASCII text
1
2
pwd
which
[test@VM-12-4-centos ~]$ which ls alias ls='ls --color=auto' /usr/bin/ls
1
2
3
alias
表示对ls起了一个别名[test@VM-12-4-centos 123]$ alias ls='ls -al --color=auto' [test@VM-12-4-centos 123]$ ls total 68 drwxrwxr-x 2 test test 4096 Apr 4 11:45 . drwx------ 18 test test 4096 May 28 18:40 .. -rw-rw-r-- 1 test test 68 Mar 29 16:50 Makefile -rw-rw-r-- 1 test test 1032 Apr 4 11:45 test.c
1
2
3
4
5
6
7使用
unalias
可以取消这个别名
type
可以用来查看某个名称是否被占用
[test@VM-12-4-centos ~]$ type ls ls is aliased to `ls --color=auto'
1
2
whatis
[test@VM-12-4-centos ~]$ whatis ls ls (1) - list directory contents ls (1p) - list directory contents
1
2
3
cat
andtac
行正序和行倒序输出
选项:-n (带行号输出)
-A(查看格式) [$]-换行 [.^.I]-制表符
-s (合并空行)
tail
[test@VM-12-4-centos test2]$ tail -n +2 main.c # 查看文件,跳过第一行
1
head
[test@VM-12-4-centos 123]$ head -3 test.c #include <stdio.h> #include <string.h> #include <stdlib.h>
1
2
3
4
more
回车:向下翻一行
空格:向下翻一页
less
可以向上(
k
)和向下(j
)翻一行也可以
空格
、b
翻一页
/ +内容
:查找
q
:退出
grep
选项:
-n
(加行号显示)-i
(忽略大小写)-v
(文字的反向选择)-l
(默认匹配文件名:字符出现行,带l可以只匹配文件名)-h
(只匹配字符出现的行)[test@VM-12-4-centos ~]$ grep -l main* main.c main.txt [test@VM-12-4-centos ~]$ grep main* main.c:int main() main.txt:main.txt [test@VM-12-4-centos ~]$ grep -h main* int main() main.txt [test@VM-12-4-centos 123]$ less test.c | grep 'main' # 过滤出含有关键字的行 int main() [test@VM-12-4-centos 123]$ less test.c | grep -v 'main' # 过滤掉含有关键字的行-反向匹配 int main() # grep 'af[0-5]' + filename # 查找file中af0、af1、af2.。。 # grep -i '^x' + file # 以x开头
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 模糊匹配——匹配文件中的字符
.(任意) $ ^ [] - 下面是扩展表达(需要加 -E 选项): *(匹配任意字符) +(匹配1个或多个字符) ?(匹配0或1个字符) {}(匹配限定个字符) ()(给定一个组) |(字符串或匹配)
1
2
3# .表示匹配任意字符;注意匹配的字符用单引号,'',单独查看含.的需要转义\. [test@VM-12-4-centos ~]$ grep -h '.re' main* Binary file main matches return 0; [test@VM-12-4-centos ~]$ grep 're$' main* # $ 匹配字符为行尾的所有行 main.txt:Picture [test@VM-12-4-centos ~]$ grep '^in' main* # ^ 匹配字符为行尾的所有行 main.c:int main() [test@VM-12-4-centos ~]$ grep '^[i#]' main* # [] 中的字符是或的关系,匹配任意一个满足条件的字符 main.c:#include <stdio.h> main.c:int main() [test@VM-12-4-centos ~]$ grep '[^i#]' main* # ^ 在 []内表示取反,匹配的正好是上面的反集。 [test@VM-12-4-centos ~]$ grep '[a-z]' main* # - 可以用来表示一个范围,main*中,a到z的任意存在的字符行都被打印了 Binary file main matches main.c:#include <stdio.h> main.c:int main() main.c: while(1) main.c: printf("hello world\n"); main.c: return 0; [test@VM-12-4-centos ~]$ grep -E '[(a-z)]{4}\(' main* # {n}表示前面的字符出现了4次; \(转义左括号 main.c:int main() main.c: while(1) main.c: printf("hello world\n"); [test@VM-12-4-centos ~]$ grep -E 'mai|ret' main* # | 字符串或者匹配 Binary file main matches main.c:int main() main.c: return 0; main.txt:main.txt
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
# 2.2.2 系统进程查看
uname -a
显示系统信息top
任务管理器 q 退出
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 优先级 nice 虚拟内存 实际内存 共享内存
1
2
ps
ps axj ps aux # all user execute # USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND # 虚拟内存 物理内存 远程type [test@VM-12-4-centos first]$ ps -al F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 1001 8339 13095 0 80 0 - 1833 hrtime pts/1 00:00:00 main
1
2
3
4
5
6
7
8
9
PRI
和NI
构成了优先级的级别。值越小,优先级越高。NI
为修正数据,Linux通过修改nice值
修改优先级,而不是直接修改PRI
。
PRI
默认大小为80,NI
的范围为[-20, 19],PRI[new] = PRI[old] + NI = [60, 99]。即Linux进程的优先级共有40个级别。进程的优先级会由操作系统自动修改。
free -k(Kb) -m(Mb) -g(Gb)
查看内存使用情况df -h
硬盘使用情况du -h filename
查看文件大小nautilus
任务管理器 = 图形界面版- 日期的查看
date +%Y%m%d-%H:%M:%S date +%s - 时间戳 date +%Y%m%d-%H:%M:%S -d @时间戳 # 转化
# 2.2 用户及权限管理
useradd
创建一个新的用户,注意不使用
adduser
(这是一个脚本)cat /etc/passwd # 查看用户信息 cat /etc/shadow # 密码信息 cat /etc/group # 查看组id
1
2
3将用户添加到组
# 新建的用户 useradd -g group username # username 作为主用户,一个用户组内只能有一个主用户;-G 可以添加多个附属用户组 # 若组不存在,可以使用 groupadd groupname 添加 #将已存在的用户添加到组 usermod -a -G group username
1
2
3
4
5
6
userdel
:删除一个用户su
常用于用户的切换,也可执行一条其他用户才有权限执行的命令但不改变当前用户(类似
sudo
)[test@VM-12-4-centos Sticky]$ ls /root ls: cannot open directory /root: Permission denied [test@VM-12-4-centos Sticky]$ su -c 'ls /root' # -c Password: linux_amd64_server.tar.gz
1
2
3
4
5
chmod
- 首先看一下文件类型,使用
ls -l
查看的文件首字符即为文件类型-:普通文件
d: 目录
s: 套接字
p: 管道 mkfifio
l: 链接文件 ln -s file soft
b: 块设备(磁盘)
c: 字符设备(键盘,显示器)
对比普通文件和目录说明权限的作用:
用户 缺少权限 普通文件 目录 owner -r 文件拥有者无法读 目录文件拥有者无法查看目录下的内容,但可以创建 owner -w 文件拥有者无法写 目录文件拥有者无法向目录创建文件 owner -x 文件拥有者无法执行 目录文件拥有者无法进入目录,无法查看目录下文件属性。只能查看文件名 group -r 组内用户无法读 组内用户无法查看目录下的内容,但可以创建 group -w 组内用户无法写 组内用户无法向目录创建文件 group -x 组内用户无法执行 组内用户无法进入目录,无法查看目录下文件属性。只能查看文件名 other -r 其他用户无法读 other无法查看 other -w 其他用户无法写 若有w,其他人可以创建和删除目录下的任何文件;若无w,则other无法创建和删除任何文件。若要other能创建文件和删除自己的文件,但是无法删除其他文件,可以设置粘滞位。 other -x 其他用户无法执行 其他用户无法进入目录 root用户可以直接修改普通文件的属性,并对文件的内容进行读和修改,即使文件权限设为
000
;只
是无法执行,预防恶意文件。文件的重命名和删除是由目录属性决定的;脚本语言可执行时必须设置成可读。
目录必须设置可执行(x)才能进行读和写。
- 基本操作
[test@VM-12-4-centos ~]$ ls -l main.txt -rw-rw-r-- 1 test test 0 May 28 22:34 main.txt # u(所有者) g(所属组) o(其他) a(all) +(增加)/-(减少)/=(设置) r(读) w(写) x(执行) [test@VM-12-4-centos ~]$ chmod u+x main.txt [test@VM-12-4-centos ~]$ ls -l main.txt -rwxrw-r-- 1 test test 0 May 28 22:34 main.txt [test@VM-12-4-centos ~]$ chmod a=w+r main.txt [test@VM-12-4-centos ~]$ ls -l main.txt -rw-rw-rw- 1 test test 0 May 28 22:34 main.txt [test@VM-12-4-centos ~]$ chmod 777 main.txt # 使用8进制的方式设置
1
2
3
4
5
6
7
8
9
10
11
- 粘滞位
对于一个用户,若允许其在某一个目录下创建文件(o+w),又不允许删除其他用户文件(o-w),则:打开所有权限并设置粘滞位
为了防止用户删除其他用户创建的文件,给目录设置粘滞位:
chmod o+t dir
,该操作会让other
用户的x
权限变成t
粘滞位保证文件只有以下用户可以删除 1、root; 2、目录拥有者; 3、文件拥有者
[test@VM-12-4-centos ~]$ ls /home/ remote test [test@VM-12-4-centos ~]$ su remote [remote@VM-12-4-centos Sticky]$ ls -ld Sticky # 当前用户作为Sticky目录的other drwxrwxrwx 2 root root 4096 May 29 01:36 Sticky # 该目录对other有w(写)权限 [remote@VM-12-4-centos Sticky]$ ll # 先准备好一些文件 total 0 -rw-rw-r-- 1 remote remote 0 May 28 23:03 file0 -rw-rw-r-- 1 remote remote 0 May 28 23:03 file1 -rw-r--r-- 1 root root 0 May 29 01:36 Root0 -rw-r--r-- 1 root root 0 May 29 01:36 Root1 -rw-r--r-- 1 root root 0 May 29 01:36 Root2 -rw-r--r-- 1 root root 0 May 29 01:36 Root3 [remote@VM-12-4-centos Sticky]$ rm -i Root3 # 此时作为普通用户删除了root用户的文件 rm: remove write-protected regular empty file ‘Root3’? y [remote@VM-12-4-centos Sticky]$ ls file0 file1 file2 file3 Root0 Root1 Root2 [remote@VM-12-4-centos ~]$ chmod o-w Sticky # 修改o的w权限 [remote@VM-12-4-centos ~]$ ll -d Sticky drwxrwxr-x 2 root root 4096 May 29 01:49 Sticky [remote@VM-12-4-centos Sticky]$ rm -f Root2 rm: cannot remove ‘Root2’: Permission denied [remote@VM-12-4-centos Sticky]$ rm -f file3 rm: cannot remove ‘file3’: Permission denied # 当目录对其他用户不能写(w)时,其他用户无法删除目录中的文件,即使是用户自己的文件。 #添加粘滞位,只能对目录进行设置 [remote@VM-12-4-centos ~]$ sudo chmod o+t Sticky [remote@VM-12-4-centos ~]$ ll drwxrwxrwt 2 root root 4096 May 29 01:49 Sticky # x 变成了 t [remote@VM-12-4-centos Sticky]$ touch hello [remote@VM-12-4-centos Sticky]$ echo "hello world" > hello [remote@VM-12-4-centos Sticky]$ cat hello hello world [remote@VM-12-4-centos Sticky]$ rm hello [remote@VM-12-4-centos Sticky]$ ls file0 file1 file2 file3 Root0 Root1 Root2 # 此时用户可以对自己的文件进行操作。 [remote@VM-12-4-centos Sticky]$ rm Root2 rm: remove write-protected regular empty file ‘Root2’? y rm: cannot remove ‘Root2’: Operation not permitted # 但是不允许删除其他用户的文件
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
- setuid
chmod u+s ExecuteFile
,给可执行文件设置,使得该文件在运行时,可以访问当前用户不能访问的文件,提升程序的权限。 与粘滞位类似.
chown
和chgrp
修改拥有者和所属组,也可使用
chown user:user + file
一次修改拥有者和所有组普通用户对文件修改时可能需要sudo,但是文件对于拥有者是自己的用户来说,修改所属组时不用sudo
umask
普通文件的起始权限 (666),目录文件 (777) + umask(普通用户默认为0002)/ root(0022)
凡是在umask出现的,都应该在权限中去掉。
使用
umask 0222
设置umask - 只在本次登录有效,除非修改配置文件。[test@VM-12-4-centos Sticky]$ ll -d dir/ drwxrwxr-x 2 test test 4096 May 29 02:25 dir/ # 775 [test@VM-12-4-centos Sticky]$ touch file [test@VM-12-4-centos Sticky]$ ll file -rw-rw-r-- 1 test test 0 May 29 02:25 file # 664
1
2
3
4
5
# 2.3 常用操作命令
rm
选项 :
-f
(force,不询问)、-i
(询问)、-r
(递归删除)# 要说明的一点就是 rm 不能从标准输入中读取,所以无法通过管道的方式删除,但是可以如下操作 [test@VM-12-4-centos a]$ ls text1 text2 text3 [test@VM-12-4-centos a]$ ls | rm rm: missing operand Try 'rm --help' for more information. [test@VM-12-4-centos a]$ ls text1 text2 text3 [test@VM-12-4-centos a]$ rm $(ls) # ()会使得ls命令运行在bash的子进程中,通过$取得输出的字符串 [test@VM-12-4-centos a]$ ls [test@VM-12-4-centos a]$
1
2
3
4
5
6
7
8
9
10
11
12
mkdir
选项 :
-p
可以创建多层目录
cp
-r
递归复制
mv
移动和重命名
进程+&
让进程后台运行。
使用
jobs
可以查看当前后台运行的程序。使用fg
可以让进程回到前台运行
# 2.4 bash标准输入
- 输入重定向
<
和输入追加重定向<<
# 输入以end结尾之前的行数,若不指定,则是换行结尾。wc -w(word) -b(byte) -l(line) [test@VM-12-4-centos test2]$ wc -l << end > 123 34 > 2df > 234 > end 3 [test@VM-12-4-centos test2]$ cat < main.c
1
2
3
4
5
6
7
8
cat > file
:将输入的内容重定向到文件中,若没有file,则重定向到标准输出;以Ctrl + D
结尾结束输入[test@VM-12-4-centos test2]$ cat > commands ls -al pwd [test@VM-12-4-centos test2]$ cat commands ls -al pwd
1
2
3
4
5
6
# 2.5 bash标准输出
echo
用echo打印出字符串,加
''
和不加是有区别的,不加''
会自动将字符串间的空格改成一个。另外双引号也有类似的作用,他会将引号内的内容转化成字符串输出,但是对于含有$()
和命令输出的(ls\pwd..)内容不受影响,若要输出$
,可以使用\
转义,或者改成单引号。[test@VM-12-4-centos ~]$ echo hello world hello world [test@VM-12-4-centos ~]$ echo 'hello world' hello world [test@VM-12-4-centos ~]$ echo $HOME /home/test [test@VM-12-4-centos ~]$ echo "$HOME" /home/test [test@VM-12-4-centos ~]$ echo "\$HOME" $HOME [test@VM-12-4-centos ~]$ echo '$HOME' $HOME
1
2
3
4
5
6
7
8
9
10
11
12
13echo会自动在字符串后添加换行符,若不想echo换行,则可以使用
-n
选项;或者使用-e
转义\c
,\c
表示禁止打印换行结束符[test@VM-12-4-centos ~]$ echo -n 'hello world' hello world[test@VM-12-4-centos ~]$ [test@VM-12-4-centos ~]$ echo -e 'hello world\c' hello world[test@VM-12-4-centos ~]$
1
2
3
4
printf
[test@VM-12-4-centos ~]$ printf '%s : %3.2f\n' 'height' 180.2 'weight' 130.5 height : 180.20 weight : 130.50
1
2
3bash的
printf
类似C语言的用法,\n
表示换行;变量可以自定义个数,用空格分隔。
- 重定向
>
和追加重定向>>
- 先写一段C代码:
#include <stdio.h> int main() { fprintf(stdout, "stdout output\n"); fprintf(stderr, "stderr output\n"); return 0; }
1
2
3
4
5
6
7编译得到
main
,运行:[test@VM-12-4-centos test2]$ ./main 1> out 2> err [test@VM-12-4-centos test2]$ cat out stdout output [test@VM-12-4-centos test2]$ cat err stderr output
1
2
3
4
5其中的数字1、2表示文件描述符。1——标准输出;2——标准错误。上诉的代码将标准输出重定向到out;标准错误重定向到err。
标准输出是有缓冲的,而标准错误是没有的,这样保证了标准错误的即使输出。
- 当然也可以将以上的输出重定向到同一个文件中:
[test@VM-12-4-centos test2]$ ./main >& output [test@VM-12-4-centos test2]$ cat output stderr output stdout output # 或者这样:[test@VM-12-4-centos test2]$ ./main > output 2>&1
1
2
3
4
5
- 若向屏蔽一些输出的信息,可以将输出重定向到
/dev/null
[test@VM-12-4-centos test2]$ ./main stdout output stderr output [test@VM-12-4-centos test2]$ ./main 2> /dev/null stdout output [test@VM-12-4-centos test2]$ cat /dev/null [test@VM-12-4-centos test2]$
1
2
3
4
5
6
7
8
- 多条命令输出的重定向:
[test@VM-12-4-centos test2]$ { ls;pwd;uname -a; } > cat #注意:括号必须保留空格,并且最后一条命令后带分号; [test@VM-12-4-centos test2]$ (ls;pwd;uname -a) > cat # 这个和上面的区别在于,本条是运行在shell的子进程中。
1
2这里可以引入一下关于
{ }
的神奇用法[test@VM-12-4-centos ~]$ echo {{1..10},{a..z}} 1 2 3 4 5 6 7 8 9 10 a b c d e f g h i j k l m n o p q r s t u v w x y z
1
2
- 一个和重定向类似的命令
tee
[test@VM-12-4-centos a]$ ls | tee ls.out text1 text2 text3 [test@VM-12-4-centos a]$ ls ls.out text1 text2 text3 [test@VM-12-4-centos a]$ cat ls.out text1 text2 text3
1
2
3
4
5
6
7
8
9
10
# 3. 其他
# 3.1 环境变量
env | cat -n #显示行号
set # 显示环境变量和本地变量
# 定义一个本地变量
localval = 1000
set | grep localval # 查看本地变量
export localval
env | grep localval #使用export后发现本地变量变成了环境变量
unset localval # 取消环境变量
2
3
4
5
6
7
8
9
# 查看环境变量 [test@VM-12-4-centos ~]$ echo $PATH # 用户私有(推荐) [test@VM-12-4-centos ~]$ vim ~/.bash_profile # profile 登录shell启动;会读取.bashrc的内容 [test@VM-12-4-centos ~]$ vim ~/.bashrc # bash非登录启动,可以是执行某个命令,如运行某个程序 # 适用于所有用户 [test@VM-12-4-centos ~]$ vim /etc/profile # profile登录shell启动 [test@VM-12-4-centos ~]$ vim /etc/bashrc # bash非登录启动 # 修改后生效: [test@VM-12-4-centos ~]$ source .bashrc # 在当前bash中设置一个临时的环境变量,bash重新登录后失效 export PATH=$PATH:/your path/ # 注意要添加 $PATH: ,否则会将原来的环境变量替换。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在C库中,有一个全局变量也可以查看当前的环境变量envrion
;main函数也会获取当前的环境变量
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[], char *env[])
{
int i = 0;
//extern char **environ; // 指向env[]的首地址
//for(; environ[i]; i++)
// printf("%s\n",environ[i]);
while(env[i])
{
printf("%s\n",env[i++]);
}
printf("PATH: %s\n", getenv("PATH"));
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 修改命令提示符
- 修改环境变量
PS1
[test@VM-12-4-centos ~]$ PS1= #此时不会出现任何提示符
[test@VM-12-4-centos ~]$ PS1="<\A>\&"
2
-
在bash中表示制表符