falcon-agent模块代码里执行sys.CmdOutBytes命令导致的问题

慎望
2023-12-01

背景介绍

公司在open-falcon项目的agent模块提供了一个方法,方法里的主要逻辑是通过内置的sys.CmdOutBytes函数,调用linux的sh -c命令。

http.HandleFunc("/run", func(w http.ResponseWriter, r *http.Request) {
		if r.ContentLength == 0 {
			http.Error(w, "body is blank", http.StatusBadRequest)
			return
		}

		bs, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		body := string(bs)
		log.Printf("...body..." + body)
		//调用linux的sh -c命令
		out, err := sys.CmdOutBytes("sh", "-c", body)
		if err != nil {
			w.Write([]byte("exec fail: " + err.Error()))
			return
		}

		w.Write(out)
})

参数经过外部传入后,在方法变成string类型(即body变量),交给sh -c执行。
比如,传入的是echo '123',那么经过方法处理后变为sh -c "echo '123'"
传入的是一个/app/test/test.sh文件,那么经过方法处理后变为sh -c "/app/test/test.sh"

问题场景

项目中某逻辑是agent接口,传入参数的是/app/open-falcon/plugin/filebeat/filebeat.sh

根据上述分析可知,经过方法处理后变为sh -c "/app/open-falcon/plugin/filebeat/filebeat.sh"

该sh文件里包含一段解压tar包的命令,如下

tar -zxf /app/open-falcon/plugin/filebeat/filebeat-7.11.1.tar.gz

正常来说,在执行后,在/app/open-falcon/plugin/filebeat路径下,应该可以看到解压的目录。然而实际在执行后, 无法找到解压的tar目录。

问题分析

- 机器手动执行

通过xshell进入到该机器的/app/open-falcon/plugin/filebeat路径,手动执行

sh -c "/app/open-falcon/plugin/filebeat/filebeat.sh" 

脚本正常执行,且gz文件正常解压,说明脚本是没问题的。

为什么手动执行没问题呢?难道是通过agent接口执行时,会有环境变量的问题?

- source环境变量

在sh的前面加上

source /etc/profile
echo $(which tar)

通过打印,发现环境变量没问题。

难道是解压到其他目录了?

- find寻找文件

经过find / -name *filebeat*寻找,发现在/app/open-falcon里有通过sh脚本解压好的目录。

奇怪,为什么会在这个路径呢?而不是/app/open-falcon/plugin/filebeat

问题原因

因为在/app/open-falcon路径才有open-falcon的二进制执行文件,所以agent接口调用sys.CmdOutBytes("sh", "-c", body)时,其所在的路径为/app/open-falcon
而我们sh脚本里没有指定解压到哪个目录,所以最终解压的目录所在路径就为/app/open-falcon

问题解决

sh脚本改为

tar -zxf /app/open-falcon/plugin/filebeat/filebeat-7.11.1.tar.gz -C /app/open-falcon/plugin/filebeat
 类似资料: