== Linux 基础知识 ==
一,基本操作
常用快捷键:
Ctrl+c 键来强行终止当前程序
Ctrl+d 键盘输入结束或退出终端
Ctrl+s 暂停当前程序,暂停后按下任意键恢复运行
Ctrl+z 将当前程序放到后台运行,恢复到前台为命令fg
Ctrl+a 将光标移至输入行头,相当于Home键
Ctrl+e 将光标移至输入行末,相当于End键
Ctrl+k 删除从光标所在位置到行末
Alt+Backspace 向前删除一个单词
Shift+PgUp 将终端显示向上滚动
Shift+PgDn 将终端显示向下滚动
Shell 常用通配符:
* 匹配 0 或多个字符
? 匹配任意一个字符
[list] 匹配 list 中的任意单一字符
[!list] 匹配 除list 中的任意单一字符以外的字符
[c1-c2] 匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z]
{string1,string2,...} 匹配 string1 或 string2 (或更多)其一字符串
{c1..c2} 匹配 c1-c2 中全部字符 如{1..10}
banner命令
$ sudo apt-get update
$ sudo apt-get install sysvbanner
$ banner shiyanlou
或者你觉得这字体不好看,那么你还可以使用默认已经安装的一个命令printerbanner:
$ printerbanner -w 50 A
-w参数指定打印宽度,因为我们的环境在屏幕中显示比较小,必须要加上宽度限制。
还有两个类似的命令toilet,figlet
二,用户及文件权限管理
1,查看用户:
who am i
who 命令其它常用参数
-a 打印能打印的全部
-d 打印死掉的进程
-m 同am i,mom likes
-q 打印当前登录用户数及用户名
-u 打印当前登录用户登录信息
-r 打印运行等级
2,创建用户:
su <user> 可以切换到用户 user,执行时需要输入目标用户的密码。
sudo <cmd> 可以以特权级别运行 cmd 命令,需要当前用户属于 sudo 组,且需要输入当前用户的密码。
su - <user> 命令也是切换用户,同时环境变量也会跟着改变成目标用户的环境变量。
新建一个叫 lilei 的用户:
$ sudo adduser lilei
用如下命令切换登录用户:
$ su -l lilei
3 用户组
方法一:使用 groups 命令
$ groups shiyanlou
$ sudo cat /etc/sudoers.d/shiyanlou
方法二:查看 /etc/group 文件
$ cat /etc/group | sort
或者$ cat /etc/group | grep -E "shiyanlou"
/etc/group 的内容包括用户组(Group)、用户组口令、GID 及该用户组所包含的用户(User),每个用户组一条记录。格式如下:
group_name:password:GID:user_list
将其它用户加入 sudo 用户组:
$ su shiyanlou # 此处需要输入shiyanlou用户密码
$ groups lilei
$ sudo usermod -G sudo lilei
$ groups lilei
4 删除用户
sudo deluser lilei --remove-home
5,Linux 文件权限
使用较长格式列出文件:$ ls -l
文件类型
socket:网络套接字 s
pipe 管道 p
软链接文件:软链接等同于 Windows 上的快捷方式 l
d 目录
- 普通文件
文件权限
读权限;写权限;执行权限
链接数
链接到该文件所在的 inode 结点的文件名数目
文件大小
以 inode 结点大小为单位来表示的文件大小,你可以给 ls 加上 -lh 参数来更直观的查看文件
$ ls -Al
查看某一个目录的完整属性,而不是显示目录里面的文件属性:
$ ls -dl <目录名>
显示所有文件大小,并以普通人类能看懂的方式呈现:
6,变更文件所有者和权限
sudo chown shiyanlou iphone6
方式一:二进制数字表示
chmod 700 iphone6
方式二:加减赋值操作
chmod go-rw iphone6
g、o 还有 u 分别表示 group、others 和 user,+ 和 - 分别表示增加和去掉相应的权限。
dduser 和 useradd 的区别是什么?
答:useradd 只创建用户,创建完了用 passwd lilei 去设置新用户的密码。
adduser 会创建用户,创建目录,创建密码(提示你设置),做这一系列的操作。
三,Linux 目录结构及文件基本操作
sudo apt-get install tree
$ tree / 查看
使用 pwd 获取当前路径:
$ pwd
新建空白文件
$ cd ~
$ touch test
新建目录
$ mkdir mydir
使用 -p 参数,同时创建父目录(如果不存在该父目录)
$ mkdir -p father/son/grandson
复制文件
使用 cp(copy)命令复制一个文件到指定目录。
$ cp test father/son/grandson
复制目录
要成功复制目录需要加上 -r 或者 -R 参数,表示递归复制:
$ cp -r father family
删除文件
$ rm test
-f 参数强制删除:
$ rm -f test
删除目录
跟复制目录一样,要删除一个目录,也需要加上 -r 或 -R 参数:
$ rm -r family
移动文件
$ mkdir Documents
$ mv file1 Documents
重命名文件
$ mv file1 myfile
批量重命名
# 使用通配符批量创建 5 个文件:
$ touch file{1..5}.txt
# 批量将这 5 个后缀为 .txt 的文本文件重命名为以 .c 为后缀的文件:
$ rename 's/.txt/.c/' *.txt
# 批量将这 5 个文件,文件名改为大写:
$ rename 'y/a-z/A-Z/' *.c
rename 是先使用第二个参数的通配符匹配所有后缀为 .txt 的文件,然后使用第一个参数提供的正则表达式将匹配的这些文件的 .txt 后缀替换为 .c
查看文件
使用 cat,tac 和 nl 命令查看文件
前两个命令都是用来打印文件内容到标准输出(终端),其中 cat 为正序显示,tac 为倒序显示。
比如我们要查看之前从 /etc 目录下拷贝来的 passwd 文件:
$ cat passwd
可以加上 -n 参数显示行号:
$ cat -n passwd
查看文件类型
$ file /bin/ls
四,环境变量与文件查找、
1,变量
$ declare tmp
$ declare tmp
$ echo $tmp
2,环境变量
set 显示当前 Shell 所有变量,包括其内建环境变量(与 Shell 外观等相关),用户自定义变量及导出的环境变量。
env 显示与当前用户相关的环境变量,还可以让命令在指定环境中运行。
export 显示从 Shell 中导出成环境变量的变量,也能通过它将自定义变量导出为环境变量。
永久生效
按变量的生存周期来划分,Linux 变量可分为两类:
永久的:需要修改配置文件,变量永久生效;
临时的:使用 export 命令行声明即可,变量在关闭 shell 时失效。
这里介绍两个重要文件 /etc/bashrc(有的 Linux 没有这个文件) 和 /etc/profile ,它们分别存放的是 shell 变量和环境变量。
还有要注意区别的是每个用户目录下的一个隐藏文件:这个 .profile 只对当前用户永久生效。
而写在 /etc/profile 里面的是对所有用户永久生效,所以如果想要添加一个永久生效的环境变量,只需要打开 /etc/profile,在最后加上你想添加的环境变量就好啦。
3, 命令的查找路径与顺序
添加自定义路径到“ PATH ”环境变量
$ PATH=$PATH:/home/shiyanlou/mybin
注意这里一定要使用绝对路径。
zsh 的配置文件是 .zshrc,相应 Bash 的配置文件为 .bashrc 。它们在 etc 下还都有一个或多个全局的配置文件,不过我们一般只修改用户目录下的配置文件。
我们可以简单地使用下面命令直接添加内容到 .zshrc 中:
$ echo "PATH=$PATH:/home/shiyanlou/mybin" >> .zshrc
上述命令中 >> 表示将标准输出以追加的方式重定向到一个文件中,注意> 是以覆盖的方式重定向到一个文件中,使用的时候一定要注意分辨。
4,创建一个 Shell 脚本文件:
$ gedit hello_shell.sh
在脚本中添加如下内容,保存并退出
#!/bin/bash
for ((i=0; i<10; i++));do
echo "hello shell"
done
exit 0
为文件添加可执行权限:
$ chmod 755 hello_shell.sh
执行脚本:
$ ./hello_shell.sh
5, 修改和删除已有变量
变量修改
${变量名#匹配字串} 从头向后开始匹配,删除符合匹配字串的最短数据
${变量名##匹配字串} 从头向后开始匹配,删除符合匹配字串的最长数据
${变量名%匹配字串} 从尾向前开始匹配,删除符合匹配字串的最短数据
${变量名%%匹配字串} 从尾向前开始匹配,删除符合匹配字串的最长数据
${变量名/旧的字串/新的字串} 将符合旧字串的第一个字串替换为新的字串
${变量名//旧的字串/新的字串} 将符合旧字串的全部字串替换为新的字串
比如要修改我们前面添加到 PATH 的环境变量。为了避免操作失误导致命令找不到,我们先将 PATH 赋值给一个新的自定义变量 path:
$ path=$PATH
$ echo $path
$ path=${path%/home/shiyanlou/mybin}
# 或使用通配符,*表示任意多个任意字符
$ path=${path%*/mybin}
变量删除
可以使用 unset 命令删除一个环境变量:
$ unset temp
6. 如何让环境变量立即生效
$ source .zshrc
source 命令还有一个别名就是 .,注意与表示当前路径的那个点区分开,虽然形式不一样,但作用和使用方式一样,上面的命令如果替换成 . 的方式就该是:
$ . ./.zshrc
注意第一个点后面有一个空格,而且后面的文件必须指定完整的绝对或相对路径名,source 则不需要。
7,与搜索相关的命令常用的有 whereis,which,find 和 locate 。
whereis 简单快速
locate 快而全
$ locate /usr/share/*.jpg
注意要添加 * 号前面的反斜杠转义,否则会无法找到。
如果想只统计数目可以加上 -c 参数,-i 参数可以忽略大小写进行查找,whereis 的 -b、-m、-s 同样可以使用。
which 小而精
它只从 PATH 环境变量指定的路径中去搜索命令:
$ which man
find 精而细
find 应该是这几个命令中最强大的了,它不但可以通过文件类型、文件名进行查找而且可以根据文件的属性(如文件的时间戳,文件的权限等)进行搜索。
这是 find 命令最常见的格式,千万记住 find 的第一个参数是要搜索的地方:
$ sudo find /etc/ -name interfaces
与时间相关的命令参数;
-atime 最后访问时间
-ctime 最后修改文件内容的时间
-mtime 最后修改文件属性的时间
五,文件打包与解压缩
常用命令:
zip:
打包 :zip something.zip something (目录请加 -r 参数)
解包:unzip something.zip
指定路径:-d 参数
tar:
打包:tar -zcvf something.tar something
解包:tar -zxvf something.tar
指定路径:-C 参数
六,文件系统操作与磁盘管理
使用 df 命令查看磁盘的容量
$ df -h
使用 du 命令查看目录的容量
$ du -h
mount [-o [操作选项]] [-t 文件系统类型] [-w|--rw|--ro] [文件系统源] [挂载点]
$ mount -o loop -t ext4 virtual.img /mnt
# 也可以省略挂载类型,很多时候 mount 会自动识别
# 以只读方式挂载
$ mount -o loop --ro virtual.img /mnt
# 或者mount -o loop,ro virtual.img /mnt
$ sudo umount /mnt
# 查看硬盘分区表信息
$ sudo fdisk -l
七,Linux下的帮助命令
内建命令与外部命令
type 命令来区分命令是内建的还是外部的
type exit
type service
help 命令
ls --help
man 命令
man ls
info 命令
info ls //更加详细
八,Linux任务计划crontab
https://www.shiyanlou.com/courses/1/labs/1918/document
九,命令执行顺序控制与管道
顺序:$ sudo apt-get update;sudo apt-get install some-tool;some-tool
管道:$ ls -al /etc | less
通过管道将前一个命令(ls)的输出作为下一个命令(less)的输入,然后就可以一行一行地看。
grep
# 查看环境变量中以"yanlou"结尾的字符串
$ export | grep ".*yanlou$" 其中$就表示一行的末尾。
$ wc /etc/passwd
分别只输出行数、单词数、字节数、字符数和输入文本中最长一行的字节数
# 行数
$ wc -l /etc/passwd
# 单词数
$ wc -w /etc/passwd
# 字节数
$ wc -c /etc/passwd
# 字符数
$ wc -m /etc/passwd
# 最长行字节数
$ wc -L /etc/passwd
sort 排序命令
默认为字典排序:
$ cat /etc/passswd | sort
反转排序:
$ cat /etc/passwd | sort -r
十,正则表达式
https://www.shiyanlou.com/courses/1/labs/354/document
十一,Linux 软件安装
通常 Linux 上的软件安装主要有四种方式:
在线安装
从磁盘安装deb软件包
从二进制软件包安装
从源代码编译安装
这几种安装方式各有优劣,而大多数软件包会采用多种方式发布软件,所以我们常常需要全部掌握这几种软件安装方式,以便适应各种环境。
1,apt-get
apt-get 是用于处理 apt包的公用程序集,我们可以用它来在线安装、卸载和升级软件包等,下面列出一些apt-get包含的常用的一些工具:
install 其后加上软件包名,用于安装一个软件包
update 从软件源镜像服务器上下载/更新用于更新本地软件源的软件包列表
upgrade 升级本地可更新的全部软件包,但存在依赖问题时将不会升级,通常会在更新之前执行一次update
dist-upgrade 解决依赖关系并升级(存在一定危险性)
remove 移除已安装的软件包,包括与被移除软件包有依赖关系的软件包,但不包含软件包的配置文件
autoremove 移除之前被其他软件包依赖,但现在不再被使用的软件包
purge 与remove相同,但会完全移除软件包,包含其配置文件
clean 移除下载到本地的已经安装的软件包,默认保存在/var/cache/apt/archives/
autoclean 移除已安装的软件的旧版本软件包
-y 自动回应是否安装软件包的选项,在一些自动化安装脚本中使用这个参数将十分有用
-s 模拟安装
-q 静默安装方式,指定多个q或者-q=#,#表示数字,用于设定静默级别,这在你不想要在安装软件包时屏幕输出过多时很有用
-f 修复损坏的依赖关系
-d 只下载不安装
--reinstall 重新安装已经安装但可能存在问题的软件包
--install-suggests 同时安装APT给出的建议安装的软件包
重新安装已经安装但可能存在问题的软件包
$ sudo apt-get --reinstall install w3m
软件升级
# 更新软件源
$ sudo apt-get update
# 升级没有依赖问题的软件包
$ sudo apt-get upgrade
# 升级并解决依赖关系
$ sudo apt-get dist-upgrade
卸载软件
sudo apt-get remove w3m
软件搜索
sudo apt-cache search softname1 softname2 softname3……
2,使用dpkg安装deb软件包
我们先使用apt-get加上-d参数只下载不安装,下载完成后,我们可以查看/var/cache/apt/archives/目录下的内容
$ cp /var/cache/apt/archives/emacs24_24.3+1-2ubuntu1_amd64.deb ~
# 安装之前参看deb包的信息
$ sudo dpkg -I emacs24_24.3+1-2ubuntu1_amd64.deb
# 使用dpkg安装
$ sudo dpkg -i emacs24_24.3+1-2ubuntu1_amd64.deb
-i 安装指定deb包
-R 后面加上目录名,用于安装该目录下的所有deb安装包
-r remove,移除某个已安装的软件包
-I 显示deb包文件的信息
-s 显示已安装软件的信息
-S 搜索已安装的软件包
-L 显示已安装软件包的目录信息
用apt-get,使用它的-f参数,修复依赖关系的安装
$ sudo apt-get -f install
3 ,查看已安装软件包的安装目录
使用dpkg -L查看deb包目录信息
$ sudo dpkg -L emacs
4,从二进制包安装
二进制包的安装比较简单,我们需要做的只是将从网络上下载的二进制包解压后放到合适的目录,然后将包含可执行的主程序文件的目录添加进PATH环境变量即可。
十二,Linux进程
关于父进程与子进程便会提及这两个系统调用 fork() 与 exec()
子进程就是父进程通过系统调用 fork() 而产生的复制品,fork() 就是把父进程的 PCB 等进程的数据结构信息直接复制过来,只是修改了 PID,所以一模一样
只有在执行 exec() 之后才会不同,而早先的 fork() 比较消耗资源后来进化成 vfork(),效率高了不少,感兴趣的同学可以查查为什么。
pid_t p;
p = fork();
if (p == (pid_t) -1)
/* ERROR */
else if (p == 0)
/* CHILD */
else
/* PARENT */
既然子进程是通过父进程而衍生出来的,那么子进程的退出与资源的回收定然与父进程有很大的相关性。
当一个子进程要正常的终止运行时,或者该进程结束时它的主函数 main() 会执行 exit(n);
或者 return n,这里的返回值 n 是一个信号,系统会把这个 SIGCHLD 信号传给其父进程,当然若是异常终止也往往是因为这个信号。
1, top 工具的使用
top 工具是我们常用的一个查看工具,能实时的查看我们系统的一些关键信息的变化:
load average: 0.29,0.20,0.25 分别对应1、5、15分钟内cpu的平均负载
若是 load < 0.7 并不会去关注他;
若是 0.7< load < 1 的时候我们就需要稍微关注一下了,虽然还可以应付但是这个值已经离临界不远了;
若是 load = 1 的时候我们就需要警惕了,因为这个时候已经没有更多的资源的了,已经在全力以赴了;
若是 load > 5 的时候系统已经快不行了,这个时候你需要加班解决问题了
2,ps 工具的使用
ps 也是我们最常用的查看进程的工具之一
ps aux
ps axjf
使用 -l 参数可以显示自己这次登陆的 bash 相关的进程信息罗列出来ps -l
3,pstree 工具的使用
通过 pstree 可以很直接的看到相同的进程数量
pstree -up
4, kill 命令的掌握
#首先我们使用图形界面打开了 gedit、gvim,用 ps 可以查看到
ps aux
#使用9这个信号强制结束 gedit 进程
kill -9 1608
#我们在查找这个进程的时候就找不到了
ps aux | grep gedit