bash和进程
当我们首次连接到shell环境,或者执行bash命令的时候,都是在启动一个新的进程。启动者和被启动者是父子的关系。
[root@localhost ~]# find / -name zjf & [root@localhost ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 15873 15868 0 80 0 - 28977 wait pts/0 00:00:00 bash 4 R 0 15964 15873 55 80 0 - 30752 - pts/0 00:00:03 find 0 R 0 15965 15873 0 80 0 - 30316 - pts/0 00:00:00 ps |
fork and exec
linux新建进程的方式是fork,fork会把父进程的内存空间拷贝一份(我的理解,应该是不包含变量)。然后拷贝的进程使用exec来加载自己要执行的代码。
工作管理
这一章节重点是记住将一个任务放到后台执行的方法。
工作管理是针对一个shell环境下的工作任务的管理.可以让一个工作在后台运行,然后查看后台运行的任务,结束任务,前置任务等。
- Ctrl-Z:该键是linux下面默认的挂起键(Suspend Key),当键入Ctrl-Z时,系统会将正在运行的程序挂起(注意是挂起,或者暂停),然后放到后台,同时给出用户相关的job信息。此时,程序并没有真正的停止,用户可以通过使用fg、bg命令将job恢复到暂停前的上下文环境,并继续执行。
- Ctrl-C:该键是linux下面默认的中断键(Interrupt Key),当键入Ctrl-C时,系统会发送一个中断信号给正在运行的程序和shell。具体的响应结果会根据程序的不同而不同。一些程序在收到这个信号后,会立即结束并推出程序,一些程序可能会忽略这个中断信号,还有一些程序在接受到这个信号后,会采取一些其他的动作(Action)。当shell接受到这个中断信号的时候,它会返回到提示界面,并等待下一个命令。
- Ctrl-D:该键是Linux下面标准输入输出的EOF。在使用标准输入输出的设备中,遇到该符号,会认为读到了文件的末尾,因此结束输入或输出。
通过使用'&'操作符让Job在后台运行
使用jobs命令,来查看当前系统中的Job
bg:将后台暂停(挂起)的任务继续运行。如果不传入工作编号,那么会
ctrl + Z和 bg命令的一般使用场景:如果你在运行job前,并不知道该job的运行情况,但在job运行了以后,发现这个是耗时的任务,并想将其放入到后台运行,这样你可以在这个任务运行的同时,完成一些其他的事情,那么你可以这样做:使用挂起键(Suspend Key,通常是Ctrl-Z)将该任务挂起(也就是暂停),然后使用'bg'命令在后台让该job恢复执行。
[root@localhost /]# tar -czf usr.jar /usr & [root@localhost /]# tar -czf usr1.jar /usr ^Z(这里代表按了CTRL+Z) [2]+ 已停止 tar -czf usr1.jar /usr [root@localhost /]# bg [2]+ tar -czf usr1.jar /usr & [root@localhost /]# tar: 从硬连接目标中删除开头的"/" jobs [1]- 运行中 tar -czf usr.jar /usr & [2]+ 运行中 tar -czf usr1.jar /usr & |
使用'bg %job number'来指定你需要对哪一个job进行操作,这里'%'告诉系统后面的数字是一个job number(不要'%'可能也可以)。
使用fg命令,将在后台的job换到前台
当你需要将在后台的job换到前台时,使用'fg %job number'命令(也可以不要'%'也可以)。
这里讲述的两种讲工作放到后台运行的方式,都是相当于把一个子进程放到后台,但是这个子进程是由父进程创建的,所以一旦关闭来父进程(如shell终端),那么后台运行的工作也会被kill。
kill命令
-2 类似于CTRL+C 发送终端终止
-9 强制终止。
-15 正常终止。这个是默认的。
也就是说,我们正常使用kill ,如果不行可以使用-2,还不行才考虑使用-9.
进程管理
进程查看的命令比较杂乱,可以记常用的两个。
ps -l :查看当前shell下的进程。
ps aux:注意没有-,查看所有的线程。
其中,ps -l和ps aux的输出大部分一样,不过每一列的名称完全不同。
所以使用,我们查看ps -l的时候,可以查看有哪些进程在运行就够了。
如果要看明细,可以使用ps aux | grep 来筛选。
ps aux的例子:
[root@localhost ~]# ps aux | head -n 5 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.2 52864 6716 ? Ss 16:43 0:05 /usr/lib/systemd/systemd --switched-root --system --deserialize 23 root 2 0.0 0.0 0 0 ? S 16:43 0:00 [kthreadd] root 3 0.1 0.0 0 0 ? S 16:43 0:43 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< 16:43 0:00 [kworker/0:0H] |
USER: 行程拥有者
PID: pid
%CPU: 占用的 CPU 使用率
%MEM: 占用的记忆体使用率
VSZ: 占用的虚拟内存大小
RSS: 占用的物理内存(不包含虚拟内存)大小
TTY: 启动进程的终端的次要装置号码 (minor device number of tty)
STAT: 该行程的状态:
START: 行程开始时间
TIME: 执行的时间
COMMAND:所执行的指令
stat 中的参数意义如下:
- D 不可中断 Uninterruptible(usually IO)
- R 正在运行,或在队列中的进程
- S 处于休眠状态
- T 停止或被追踪
- Z 僵尸进程
- W 进入内存交换(从内核2.6开始无效)
- X 死掉的进程
pstree
展示进程树
[root@localhost ~]# pstree systemd─┬─ModemManager───2*[{ModemManager}] ├─NetworkManager───3*[{NetworkManager}] ├─2*[abrt-watch-log] ├─abrtd ├─accounts-daemon───2*[{accounts-daemon}] ├─alsactl ├─at-spi-bus-laun─┬─dbus-daemon───{dbus-daemon} │ └─3*[{at-spi-bus-laun}] ├─at-spi2-registr───{at-spi2-registr} ├─atd ├─auditd─┬─audispd─┬─sedispatch │ │ └─{audispd} │ └─{auditd} ├─avahi-daemon───avahi-daemon ├─chronyd ├─colord───{colord} ├─crond ├─2*[dbus-daemon───{dbus-daemon}] ├─dbus-launch ├─dconf-service───2*[{dconf-service}] ├─firewalld───{firewalld} ├─gdm─┬─gdm-simple-slav─┬─Xorg───2*[{Xorg}] │ │ ├─gdm-session-wor─┬─gnome-session─┬─gnome-settings-───3*[{gnome-settings-}] │ │ │ │ ├─gnome-shell───6*[{gnome-shell}] │ │ │ │ └─3*[{gnome-session}] │ │ │ └─2*[{gdm-session-wor}] │ │ └─2*[{gdm-simple-slav}] │ └─2*[{gdm}] ├─goa-daemon───3*[{goa-daemon}] ├─ibus-daemon─┬─ibus-dconf───2*[{ibus-dconf}] │ ├─ibus-engine-sim───{ibus-engine-sim} │ └─2*[{ibus-daemon}] ├─ibus-x11───{ibus-x11} ├─iprdump ├─iprinit ├─iprupdate ├─ksmtuned───sleep ├─libvirtd───10*[{libvirtd}] ├─lsmd ├─lvmetad ├─mission-control───2*[{mission-control}] ├─mysqld_safe───mysqld───20*[{mysqld}] ├─polkitd───5*[{polkitd}] ├─pulseaudio───2*[{pulseaudio}] ├─rhsmcertd ├─rpc.statd ├─rpcbind ├─rsyslogd───2*[{rsyslogd}] ├─rtkit-daemon───2*[{rtkit-daemon}] ├─smartd ├─sshd─┬─sshd───bash │ └─sshd───bash───pstree ├─systemd-journal ├─systemd-logind ├─systemd-udevd ├─tuned───4*[{tuned}] ├─upowerd───2*[{upowerd}] └─vmtoolsd───{vmtoolsd} |
top命令
使用方式
top -d 2:展示系统各项指标的使用排名情况,这里默认为CPU的排名,每2秒刷新一次。
在真个界面,可以按P查看cpu排名,按m切换为内存排名。
查看内存使用情况
free -g 以gb为单位展示
free -m 以mb为单位展示
[root@localhost ~]# free -m total used free shared buffers cached Mem: 2834 2755 79 8 0 1750 -/+ buffers/cache: 1004 1830 Swap: 2063 0 2063 |
total:表示物理内存总量(total = used + free)
used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。
free:未被分配的内存。
shared:共享内存,一般系统不会用到,这里也不讨论。
buffers:系统分配但未被使用的buffers 数量。
cached:系统分配但未被使用的cache 数量。
Mem:表示物理内存统计
-/+ buffers/cache:表示物理内存的缓存统计
used2:也就是第一行中的used – buffers-cached 也是实际使用的内存总量。 //used2为第二行
free2= buffers1 + cached1 + free1 //free2为第二行、buffers1等为第一行
free2:未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存。
Swap:表示硬盘上交换分区的使用情况,这里我们不去关心。一旦内存不足,Swap的used就会比较大。
如何识别内存不足:free2很少 或者 Swap的used比较大。
netstat
常见参数
-a (all)显示所有选项,默认不显示LISTEN相关
-t (tcp)仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化成数字。
-l 仅列出有在 Listen (监听) 的服務状态
-p 显示建立相关链接的程序名
-r 显示路由信息,路由表
-e 显示扩展信息,例如uid等
-s 按各个协议进行统计
-c 每隔一个固定时间,执行该netstat命令。
常见使用:
netstat -tap查看所有的tcp:
[root@localhost ~]# netstat -tap Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:sunrpc 0.0.0.0:* LISTEN 1929/rpcbind tcp 0 0 0.0.0.0:17046 0.0.0.0:* LISTEN 2242/rpc.statd tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN 1817/sshd tcp 0 0 zjf-pc:ssh 192.168.1.7:53037 ESTABLISHED 5678/sshd: root@pts tcp 0 52 zjf-pc:ssh 192.168.1.7:56682 ESTABLISHED 8008/sshd: root@pts tcp6 0 0 [::]:mysql [::]:* LISTEN 2535/mysqld tcp6 0 0 [::]:sunrpc [::]:* LISTEN 1929/rpcbind tcp6 0 0 [::]:unisys-eportal [::]:* LISTEN 2242/rpc.statd tcp6 0 0 [::]:ssh [::]:* LISTEN 1817/sshd |
netstat -a查看所有占用的端口:
[root@localhost ~]# netstat -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:sunrpc 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:17046 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN tcp 0 0 zjf-pc:ssh 192.168.1.7:53037 ESTABLISHED tcp 0 52 zjf-pc:ssh 192.168.1.7:56682 ESTABLISHED tcp6 0 0 [::]:mysql [::]:* LISTEN tcp6 0 0 [::]:sunrpc [::]:* LISTEN tcp6 0 0 [::]:unisys-eportal [::]:* LISTEN tcp6 0 0 [::]:ssh [::]:* LISTEN udp 0 0 0.0.0.0:sunrpc 0.0.0.0:* udp 0 0 0.0.0.0:ntp 0.0.0.0:* udp 0 0 localhost:323 0.0.0.0:* udp 0 0 0.0.0.0:passgo-tivoli 0.0.0.0:* udp 0 0 localhost:722 0.0.0.0:* udp 0 0 0.0.0.0:38078 0.0.0.0:* udp 0 0 0.0.0.0:mdns 0.0.0.0:* udp 0 0 0.0.0.0:22422 0.0.0.0:* udp6 0 0 [::]:sunrpc [::]:* udp6 0 0 [::]:ntp [::]:* udp6 0 0 localhost:323 [::]:* udp6 0 0 [::]:passgo-tivoli [::]:* udp6 0 0 [::]:56300 [::]:* raw6 0 0 [::]:ipv6-icmp [::]:* |
service
Service是一种被称为守护进程(daemon)的程序。它通常一旦启动后就在后台持续运行,通常在等待什么输入或者监控系统有什么变化。例如Apache服务器有一个叫httpd的守护进程监听80端口以等待http请求。
linux提供了一个名叫daemon的函数来初始化环境,如下:
int daemon(int nochdir, int noclose);
使用该函数需加入#include <stdlib.h>头文件包含。调用该函数之后,其后的程序将会以daemon方式运行。
编写自己的service脚本如下,然后在/etc/init.d目录下,存储这个脚本为mysqltest文件。
start(){ n=$(netstat -ntlp |grep 3307|grep -v "grep 3307"|wc -l) if [ $n -ne 0 ];then echo"server is already running!" exit0 fi mysqld_multi --defaults-extra-file=/etc/my_3307.cnf --user=root start 3307 if [ $? -eq 0 ];then echo"service mysql_3307 start successful " else echo"service mysql_3307 start fail" fi }
stop(){ n=$(netstat -ntlp |grep 3307|grep -v "grep 3307"|wc -l) if [ $n -eq 0 ];then echo"server is not running!" fi mysqld_multi --defaults-extra-file=/etc/my_3307.cnf --user=root stop 3307 if [ $? -eq 0 ];then echo"service mysql_3307 stop successful " else echo"service mysql_3307 stop fail" fi }
status(){ ps -ef |grep 3307|grep -v "grep 3307" }
case$1in start) start ;; stop) stop ;; status) status ;; *) echo'service accept arguments start|stop|status' esac |
然后就能使用service mysqltest start|stop|restart命令了。