shell脚本宏定义、赋值、命令执行结果

最近想写个shell脚本,实现一个监测功能,然后退出

遇到几个问题:
1、主shell内部包含管道命令时,会创建其他子shell,无法退出(子shell有循环)

2、shell变量赋值和“宏定义”的问题

以下原代码,test是假设的一个系统调用

#!/bin/sh
heart()
{
	while true
	do
		printf '\n'
		sleep 1
	done
}

watch()
{
	(heart) | test | while read line
	do
		case "$line" in
			*'exit'*)
			exit
			;;
		...
	done
}

watch

上面会执行完,exit后,ps发现还有两个进程存在
分别是heart和test的。

一番百度后,了解了shell脚本中,管道“|” 的命令会放在子shell中执行,就是另外开一个shell跑。

我需要在退出的时候, 把这个shell起的子shell也一起退出。

有什么好办法呢?
看到有办法说$$返回的是子shell pid,但是我这里有多个子shell,只返回了一个pid也不行

目前我用了一个办法:脚本查找指定进程pid,杀死

所以有了下面的优化版代码,增加exitsh

#!/bin/sh

#pid
pid=$(pgrep -f test)
sh_pid=$(pgrep -f $0)

heart()
{
	while true
	do
		printf '\n'
		sleep 1
	done
}
exitsh()
{
	echo -e "pid:$pid  $sh_pid\n\n"
	kill -9 $pid
	kill -9 $sh_pid
	exit
}

watch()
{
	(heart) | test | while read line
	do
		case "$line" in
			*'exit'*)
			exitsh
			;;
		...
	done
}

watch

看起来没问题,但是结果发现,却杀不死,一看打印pid是空的

???

哪里出问题了?百度都是这样跑的啊。。。

最后发现。。。。

pid=$(pgrep -f test)

这句放在文件前面,已经赋值了,并不是宏定义,而是变量赋值,前面一开始的时候test还没有运行,所以是空的

这里插入一句:$()和`` 功能一样是一样的

那么我要做类似宏定义怎么办?

又看了一番[单引号,双引号,反引号的区别],参考别人的文章(https://www.jb51.net/article/33495.htm)

再把脚本改一下

#!/bin/sh

#pid
pid="pgrep -f test"
sh_pid="pgrep -f $0"

heart()
{
	while true
	do
		printf '\n'
		sleep 1
	done
}
exitsh()
{
	echo -e "pid:$($pid)  $($sh_pid)\n\n"
	kill -9 $($pid)
	kill -9 $($sh_pid)
	exit
}

watch()
{
	(heart) | test | while read line
	do
		case "$line" in
			*'exit'*)
			exitsh
			;;
		...
	done
}

watch

这下终于可以了,主shell里面就可以在任意位置调用 ( ( (pid),就可以得到pid的值了

shell脚本命令异常捕捉

用 $? 取得上一条命令的返回值并判断。
Linux中0表示True,非0表示False。

因为脚本使用了多个管道命令组成
如果其中一个命令被杀掉了,导致脚本无法正常执行
此时,脚本里面需要类似errno的机制来处理

#!/bin/sh

#pid
pid="pgrep -f test"
sh_pid="pgrep -f $0"

heart()
{
	while true
	do
		printf '\n'
		sleep 1
	done
}
exitsh()
{
	echo -e "pid:$($pid)  $($sh_pid)\n\n"
	kill -9 $($pid)
	kill -9 $($sh_pid)
	exit
}

watch()
{
	(heart) | test | while read line
	//可以判断上述命令结果
	ret=$?
	if [ ret -ne 0 ];then
		echo "cmd err"
		exitsh
	fi 
	
	do
		case "$line" in
			*'exit'*)
			exitsh
			;;
		...
	done
}

watch

学习了

你可能感兴趣的:(Linux,shell)