Linux 进程与管道的相关tips

Linux 进程与管道的相关tips

 

安装psmisc

# yum install psmisc

安装完成后即可查看pstree:

# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
      ├─VGAuthService
      ├─auditd───{auditd}
      ├─chronyd
      ├─crond
      ├─dbus-daemon───{dbus-daemon}
      ├─firewalld───{firewalld}
      ├─irqbalance
      ├─login───bash
      ├─lvmetad
      ├─polkitd───6*[{polkitd}]
      ├─2*[redis-server───4*[{redis-server}]]
      ├─rsyslogd───2*[{rsyslogd}]
      ├─sshd─┬─4*[sshd───bash───redis-cli]
      │     ├─5*[sshd───sftp-server]
      │     └─sshd───bash───pstree
      ├─systemd-journal
      ├─systemd-logind
      ├─systemd-udevd
      ├─tuned───4*[{tuned}]
      └─vmtoolsd───{vmtoolsd}

 

在当前bash中再次开启一个bash

# /etc/bash

此时再看pstree:

systemd─┬─NetworkManager───2*[{NetworkManager}]
      ├─VGAuthService
      ├─auditd───{auditd}
      ├─chronyd
      ├─crond
      ├─dbus-daemon───{dbus-daemon}
      ├─firewalld───{firewalld}
      ├─irqbalance
      ├─login───bash
      ├─lvmetad
      ├─polkitd───6*[{polkitd}]
      ├─2*[redis-server───4*[{redis-server}]]
      ├─rsyslogd───2*[{rsyslogd}]
      ├─sshd─┬─4*[sshd───bash───redis-cli]
      │     ├─5*[sshd───sftp-server]
      │     └─sshd───bash───bash───pstree
      ├─systemd-journal
      ├─systemd-logind
      ├─systemd-udevd
      ├─tuned───4*[{tuned}]
      └─vmtoolsd───{vmtoolsd}
       

可以看到在sshd这一行的bash后面又多了一个bash,此为刚才的bash创建的一个子进程。

推出此进程,回到原来的bash:

# exit

 

进程对数据的保护

声明并初始化num变量:

# num=1

查看num变量:

# echo $num

得到1

然后创建新的bash

再使用echo查看num变量时,num变量成为了空

由此可得:进程间的数据是不共享的。

 

管道的pid($$ 与 $BASHID的区别)

 

获取当前进程id:

# echo $$

也可以

# echo $BASHID

1).

使用管道让进程id在more中输出:

# echo $$  |   more

2).

另一种获取进程的方法:

# echo $BASHID  |  more

两种方式返回的pid值并不一样:

直接获取返回的两个值是相同的,而通过管道获取的两个值不同,其中只有1)方法正确的返回了直接获取方式返回的值相同的值,而2)方式返回的与前三个值不同。

原因:

这里通过管道获取值的时候,$$方式是bash在读到命令就直接用自己的pid替换了$$,如果这里假设bash的进程号是1234567,后续的操作相当于管道左边创建了进程"echo 1234567",输出的就是1234567,右边输入的自然就是1234567;

而$BASHID方式则不替换,直接在管道左边创建进程"echo $BASHID",当真正执行这段代码的进程(也就是左边进程)执行到此时,再去获取当前执行的进程的id,那么结果自然就不是刚才的读取命令的bash而是其他的进程了。

 

export数据

在子进程中若想获取父进程的数据,则需要父进程执行export操作:

实验:

1.创建脚本程序test.sh

#!/bin/bash

echo $$
echo $num
num=999
echo num:$num

sleep 30

echo num:$num

上述脚本执行的操作:

输出自己的进程号;

输出num变量的值(第一处);

将num值改为999;

输出num的值(第二处);

阻塞30秒;

获取num的值(第三处);

结束。

2.添加脚本程序的属性:

# chmod +x test.sh

3.设置变量num,并且export,之后查看当前进程:

# num=1
# export num
# echo $$

4.开始后台执行脚本:

# ./test.sh &
[1] 2650
[root@192 XXX]# 2650
num:1
num:999

5.执行到此处,快速查看num变量:

# echo $num
1

6.等待后台脚本程序执行完成,最终输出:

# num:999
说明:

父进程中使用export于num变量后,其子进程也可以获取到num的值,但是当子进程要修改num的值时,并不是直接在原来的num地址里修改,而是新注册了一块新地址赋值为修改值,然后将子进程中的num指针指向新地址,因此后面出现的父进程与子进程的num不一样。

 

posted @ 2021-08-29 18:51  飞杨煎生物  阅读(77)  评论(0)    收藏  举报