本篇博客记录了些 Linux 系统的常用知识。
文件和目录权限
root 默认对所有文件具有读写权限,但默认没有执行权限。
目录权限知识
对于目录来说, r 查看目录中的内容 w 可以在目录中创建、删除、修改、重命名文件。 x 表示是否可以进入到目录中,是否能查看或修改目录中文件的属性信息。
目录的 r 权限,需要 x 权限配合。 目录的 w 权限,需要 x 权限配合。 单独的 x 权限没有用。
ulimit
设置当前shell以及由它启动的进程的资源限制。
linux 对于每个用户,系统限制其最大进程数。为提高性能,可以根据设备资源情况,设置各linux 用户的最大进程数。
可以用 ulimit -a
来显示当前的各种用户进程限制。
可以通过 ulimit -n 4096
将每个进程可以打开的文件数目加大到4096,缺省为1024。
其他建议设置成无限制(unlimited)的一些重要设置是:
|
|
暂时地,适用于通过 ulimit 命令登录 shell 会话期间。 永久地,通过将一个相应的 ulimit 语句添加到由登录 shell 读取的文件中, 即特定于 shell 的用户资源文件。
ulimit 的硬限制和软限制
硬限制使用 -H 参数,软限制使用 -S 参数。
ulimit -a 看到的是软限制,可以通过 ulimit -a -H 查看其硬限制。
如果 ulimit 不限定使用 -H 或 -S,此时它会同时把两类限制都改掉的。
软限制可以限制用户/组对资源的使用,硬限制的作用是控制软限制。
超级用户和普通用户都可以扩大硬限制,但是超级用户可以缩小硬限制,普通用户则不能缩小硬限制。
硬限制设定后,设定软限制时只能是小于或者等于硬限制。
解除资源限制
1、解除 Linux 系统的最大进程数和最大文件打开数限制:
在 /etc/security/limits.conf
中添加如下行:
|
|
说明:* 代表针对所有用户,noproc
是代表最大进程数,nofile
是代表最大文件打开数。
2、修改所有Linux用户的环境变量文件:
在/etc/profile
中添加如下内容
|
|
保存后运行source /etc/profile
使其生效。
参考资料
https://blog.csdn.net/csq_year/article/details/49304895
https://blog.csdn.net/fengspg/article/details/39646337
僵尸进程和孤儿进程
在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。 僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用 wait 函数或 waitpid 函数获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
unix提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。 但是仍然为其保留一定的信息(包括进程号,退出状态,运行时间等)。直到父进程通过wait / waitpid来取时才释放。 但这样就导致了问题,如果父进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤 儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。
任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。 如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。
解决方法:
-
通过信号机制,子进程退出时向父进程发送
SIGCHILD
信号,父进程处理SIGCHILD
信号。在信号处理函数中调用wait进行处理僵尸进程。 -
Fork两次,原理是将子进程成为孤儿进程,从而其的父进程变为init进程,通过init进程可以处理僵尸进程。
守护进程
守护进程(Daemon Process),是Linux中的后台服务进程,是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
守护进程是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。
Linux 的大多数服务器就是用守护进程实现的。比如,Internet 服务器 inetd,Web 服务器 httpd 等。
系统平均负载
系统平均负载被定义为在特定时间间隔内运行队列中的平均进程数。如果一个进程满足以下条件,则其就会位于运行队列中:
- 没有在等待I/O操作的结果。
- 没有主动进入等待状态(也就是没有调用wait)。
- 没有被停止。
|
|
命令输出的最后内容表示在过去的1、5、15分钟内运行队列中的平均进程数量。
一般来说只要每个CPU的当前活动进程数不大于3那么系统的性能就是良好的,如果每个CPU的任务数大于5,那么就表示这台机器的性能有严重问题。对于 上面的例子来说,假设系统有两个CPU,那么其每个CPU的当前任务数为:0.90/2=0.45。这表示该系统的性能是良好的。
vm.swappiness
Linux 会使用硬盘的一部分作为 Swap 分区,用来进行进程的调度。如果内存够大,应当告诉 Linux 不必太多地使用 Swap 分区,可以通过修改 swappiness 的数值实现。
swappiness=0 的时候表示最大限度地使用物理内存,然后才是 swap 空间;
swappiness=100 的时候表示积极地使用 swap 分区,并且把内存上的数据及时地搬运到 swap 空间里面。
在 Linux 中,swappiness 的默认值为:60
/proc/stat 文件 内容含义
文件内容为:
cpu 38612618 56617 34286154 1463872231 372072760 0 957390 9312034 0 0
cpu0 10354076 16022 9826771 452299838 4246512 0 72999 2704956 0 0
cpu1 9711715 13481 9043388 455113973 3912957 0 57785 2331301 0 0
cpu2 9036808 12888 8220419 101656754 360163130 0 47335 1991839 0 0
cpu3 9510018 14225 7195574 454801665 3750159 0 779269 2283936 0 0
intr 8888957117 132 9 0 0 0 0 3 0 0 0 0 24 126 0 0 4364057 0 0 0 0 0 0 0 0 0 0 557138249 2 5427 0 5427157 0 3141694 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 15656962072
btime 1528977806
processes 17976269
procs_running 2
procs_blocked 1
softirq 3416731289 3 1574245130 526818 783196686 2384220 0 202 386807575 0 669570655
表示的是CPU总的使用情况,从左向右分别表示user,nice,system,idle,iowait,irq和softirq
- user:处于用户态的运行时间,不包含nice值为负的进程。
- nice:nice值为负的进程所占用的CPU时间。
- system:处于内核态的运行时间。
- idle:除IO等待时间以外的其他等待时间。
- iowait:io等待时间
- irq:硬中断时间
- softirq:软中断时间
以上所有时间均是从系统启动开始累计到当前时刻,单位为:jiffies(jiffies是内核中的一个全局变量,用来记录自系统启动以来产生的节拍数。在linux中,一个节拍大致可以理解为操作系统进程调度的最小时间片,不同的linux内核,值可能不同,通常在1ms~10ms之间)
~ 和 / 的区别
/
是目录层的分隔、表示符。只有一个 /
表明是根目录, /etc/
表明是根目录下面的 etc
目录。当然目录最后不需要 /
,但有 /
直接表明他是目录,没有末尾的 /
,那么 /etc
需要检测一下确定是目录还是文件,虽然习惯上 /etc
绝对是目录。
~
是一个代位符,表明的是个人目录的地址,因为每个用户都有自己的个人目录地址,所以用 ~
作为统一替代这个根据用户不同而不同但有规可循的地址,来保证某些情况下的兼容问题。
单引号、双引号、反引号
1、由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。
2、由双引号括起来的字符,除$(美元符号)、\(反斜杠)、’(单引号)、和”(双引号)这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待。对于“$”来说,就是用其后指定的变量的值来代替这个变量和$;对于“\”而言,是转义字符,它告诉shell不要对其后面的那个字符进行特殊处理,只当作普通字符即可。可以想见,在双引号中需要在前面加上“\”的只有四个字符$,\,’和”本身。而对”号,若其前面没有加“\”,则Shell会将它同前一个”号匹配。
把双引号内的内容输出出来,如果内容中有命令、变量等,会先把变量、命令解析出结果,然后再输出最终的内容来。
3、反引号(`)这个字符所对应的键一般位于键盘的左上角,不要将其同单引号(’)混淆。反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。
4、反引号还可以嵌套使用。但需注意,嵌套使用时内层的反引号必须用反斜杠(\)将其转义。
5、在反引号之间的命令行中也可以使用shell的特殊字符。Shell为得到中命令的结果,它实际上要去执行
中指定的命令。执行时,命令中的特殊字符,如$,”,?等又将具有特殊含义,并且``所包含的可以是任何一个合法的Shell命令。
带双引号和不带双引号的区别:
把双引号内的内容输出出来,如果内容中有命令、变量等,会先把变量、命令解析出结果,然后再输出最终的内容来。
对于 bash 来说
echo $1
看上去是 打印第一个参数,其实是 把第一个参数按照空格、制表符、换行符等符号来分割开,然后把这些分割后的每一项再按 glob 模式展开,最后把这些值,再用一个空格重新连接起来并打印出来。
如果 第一个参数 碰巧就是 用一个空格连接的,且没有包含这些 glob 模式,那看上去就是原样输出,其实是转换以后没有发生变化。
字符串相关操作
判断读取字符串值
表达式 | 含义 |
---|---|
${var} | 变量var的值, 与$var相同 |
${var-DEFAULT} | 如果var没有被声明, 那么就以$DEFAULT作为其值 * |
${var:-DEFAULT} | 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 * |
${var=DEFAULT} | 如果var没有被声明, 那么就以$DEFAULT作为其值 * |
${var:=DEFAULT} | 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 * |
${var+OTHER} | 如果var声明了, 那么其值就是$OTHER, 否则就为null字符串 |
${var:+OTHER} | 如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串 |
${var?ERR_MSG} | 如果var没被声明, 那么就打印$ERR_MSG * |
${var:?ERR_MSG} | 如果var没被设置, 那么就打印$ERR_MSG * |
字符串操作
表达式 | 含义 |
---|---|
${#string} | $string的长度 |
${string:position} | 在$string中, 从位置$position开始提取子串 |
${string:position:length} | 在$string中, 从位置$position开始提取长度为$length的子串 |
${string#substring} | 从变量$string的开头, 删除最短匹配$substring的子串 |
${string##substring} | 从变量$string的开头, 删除最长匹配$substring的子串 |
${string%substring} | 从变量$string的结尾, 删除最短匹配$substring的子串 |
${string%%substring} | 从变量$string的结尾, 删除最长匹配$substring的子串 |
${string/substring/replacement} | 使用$replacement, 来代替第一个匹配的$substring |
${string//substring/replacement} | 使用$replacement, 代替所有匹配的$substring |
${string/#substring/replacement} | 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring |
${string/%substring/replacement} | 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring |
${varible##*string} | 从左向右截取最后一个string后的字符串 |
${varible#*string} | 从左向右截取第一个string后的字符串 |
${varible%%string*} | 从右向左截取最后一个string后的字符串 |
${varible%string*} | 从右向左截取第一个string后的字符串 |
例如,对于str=10.10.24.171:5000/xdhuxc/nginx
${str##*/} ==> nginx
${str#*/} ==> xdhuxc/nginx
${str//10.10.24.171/192.168.244.128} ==> 192.168.244.128:5000/xdhuxc/nginx
\cp
cp
命令默认是不会提示 overwrite?
的,但是 cp
的 -i
选项会提示,而一般 Linux
的启动文件 ~/.bashrc
中会把 cp
命名成
|
|
这样在 Linux
下输入 cp
命令实际上运行的是 cp -i
,加上一个 \
符号就是让此次的 cp
命令不使用别名 cp -i
运行,就不会有 overwrite?
的提示了
文件测试运算符
文件测试运算符用于检测Unix文件的各种属性
操作符 | 说明 |
---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true |
-d file | 检测文件是否是目录,如果是,则返回 true |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true |
-w file | 检测文件是否可写,如果是,则返回 true |
-x file | 检测文件是否可执行,如果是,则返回 true |
-r file | 检测文件是否可读,如果是,则返回 true |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true |
文件颜色的含义
在Linux命令行中,文件和目录的颜色有特殊的含义
1、白色,表示普通文件
2、蓝色,表示目录
3、绿色,表示可执行文件
4、红色,表示压缩文件
5、浅蓝色,表示链接文件
6、黄色,表示设备文件
7、灰色,表示其他文件
8、红色闪烁,表示链接的文件有问题