diff --git a/mms/mms_process.c b/mms/mms_process.c index 29a9140..e5474ab 100644 --- a/mms/mms_process.c +++ b/mms/mms_process.c @@ -197,14 +197,32 @@ void closeChannel(chnl_usr_t *chnl_usr) ALL_RCB_INFO *all_rcb_info; RCB_INFO *rcb_info; ST_RET ret; - if(chnl_usr->net_info->user_info) - { + //lnk20260617防止复用崩溃 + /*if(chnl_usr->net_info->user_info) + { all_rcb_info = (ALL_RCB_INFO *)chnl_usr->net_info->user_info; + all_rcb_info = chnl_usr->all_rcb_info; + while((rcb_info = (RCB_INFO *)list_get_first(&all_rcb_info->rcb_info_list)) != NULL) rcb_info_destroy (rcb_info); chk_free(all_rcb_info); chnl_usr->net_info->user_info=NULL; + }*/ + if (chnl_usr->all_rcb_info) + { + all_rcb_info = chnl_usr->all_rcb_info; + + while ((rcb_info = (RCB_INFO *)list_get_first(&all_rcb_info->rcb_info_list)) != NULL) { + rcb_info_destroy(rcb_info); + } + + chk_free(all_rcb_info); + chnl_usr->all_rcb_info = NULL; } + + chnl_usr->net_info->user_info = NULL; + + //lnk20260617防止复用崩溃 chnl_usr->net_info->rem_vmd = NULL; echo_warn("---------start disconnectFromServer!\n"); ret = mms_disconnectFromServer(chnl_usr->net_info,&chnl_usr->m_reqCtrl); @@ -219,6 +237,9 @@ void closeChannel(chnl_usr_t *chnl_usr) mvl_free_req_ctrl(chnl_usr->m_reqCtrl); + //lnk20260617防止复用崩溃 + chnl_usr->all_rcb_info = NULL; + chnl_usr->net_info->user_info = NULL; chnl_usr->net_info = NULL; @@ -1729,7 +1750,9 @@ void CheckNextNotConnectedChannel() echo_warn("chnl_usr->net_info->user_info is not NULL\n"); } - chnl_usr->net_info->user_info = all_rcb_info; + //lnk20260617防止复用崩溃 + //chnl_usr->net_info->user_info = all_rcb_info; + chnl_usr->chnl->ied->status = STATUS_NORMAL; chnl_usr->chnl->status = STATUS_NORMAL; diff --git a/mms/mmscli_rpt.c b/mms/mmscli_rpt.c index d79ad51..d19edf9 100644 --- a/mms/mmscli_rpt.c +++ b/mms/mmscli_rpt.c @@ -1228,8 +1228,30 @@ ST_VOID u_iec_rpt_ind_data(MVL_VAR_ASSOC** info_va, log_var_data(info_va[va_num], &mms_dec_data); //assert(add_mms_dec_data== (uint32_t)&mms_dec_data); rptinfo = find_rptinfo_from_net_rcb_info(net_info, rcb_info); + + if (rptinfo == NULL) { + chnl_usr_t* chnl_usr_tmp = net_info ? (chnl_usr_t*)net_info->user_info : NULL; + + printf("[RPT][ERROR] cannot find rptinfo, net_info=%p user_info=%p rcb_info=%p RptID=%s\n", + (void*)net_info, + net_info ? (void*)net_info->user_info : NULL, + (void*)rcb_info, + (rcb_info && rcb_info->RptID) ? rcb_info->RptID : "NULL"); + + return; + } + + //rptinfo->m_LastDataTime = sGetMsTime();//WW 2023-08-29 去除 LD_info = rptinfo->LD_info; + + if (LD_info == NULL) { + printf("[RPT][ERROR] rptinfo->LD_info NULL, rptinfo=%p RptID=%s\n", + (void*)rptinfo, + (rcb_info && rcb_info->RptID) ? rcb_info->RptID : "NULL"); + return; + } + chnl_usr = net_info->user_info; ied = chnl_usr->chnl->ied; @@ -2009,7 +2031,13 @@ ST_RET u_iec_rpt_ind(MVL_COMM_EVENT* event) } /* Get "all_rcb_info" from "user_info". User must set "user_info" when conn established.*/ - all_rcb_info = (ALL_RCB_INFO*)event->net_info->user_info; + //lnk20260617防止复用崩溃 + //all_rcb_info = (ALL_RCB_INFO*)event->net_info->user_info; + chnl_usr_t *chnl_usr = (chnl_usr_t*)event->net_info->user_info; + if (chnl_usr == NULL || chnl_usr->all_rcb_info == NULL) { + return; + } + all_rcb_info = chnl_usr->all_rcb_info; /* Check "all_rcb_info" to see if any RCB has been enabled. */ if (all_rcb_info == NULL || all_rcb_info->rcb_info_list == NULL) diff --git a/mms/mmsclient.c b/mms/mmsclient.c index c037f29..29cb62a 100644 --- a/mms/mmsclient.c +++ b/mms/mmsclient.c @@ -860,8 +860,24 @@ ST_UCHAR TrgOps [1]; /* 8 bit bitstring */ if(ret == SD_SUCCESS) { - list_add_last(&((ALL_RCB_INFO *)clientNetInfo->user_info)->rcb_info_list, rcb_info); /* add RCB to list*/ - } + //lnk20260617防止复用崩溃 + //list_add_last(&((ALL_RCB_INFO *)clientNetInfo->user_info)->rcb_info_list, rcb_info); /* add RCB to list*/ + chnl_usr_t *chnl_usr = (chnl_usr_t *)clientNetInfo->user_info; + + if (chnl_usr == NULL || chnl_usr->all_rcb_info == NULL) { + printf("[RPT_REGISTER][ERROR] invalid user_info=%p all_rcb_info=%p dom=%s rcb=%s\n", + clientNetInfo ? clientNetInfo->user_info : NULL, + chnl_usr ? chnl_usr->all_rcb_info : NULL, + dom_name ? dom_name : "NULL", + rcb_name ? rcb_name : "NULL"); + + rcb_info_destroy(rcb_info); + rcb_info = NULL; + return NULL; + } + + list_add_last(&chnl_usr->all_rcb_info->rcb_info_list, rcb_info); + } else{ rcb_info_destroy(rcb_info); rcb_info = NULL; diff --git a/mms/rdb_client.h b/mms/rdb_client.h index 60b1cd5..2cdce45 100644 --- a/mms/rdb_client.h +++ b/mms/rdb_client.h @@ -375,6 +375,8 @@ struct chnl_usr_t{ double m_ClosedMsTime; //上次通道关闭时间 double m_LastPosRespTime; //上次肯定响应的时间 int m_NegRespTimes; // 累计否定响应次数 + + ALL_RCB_INFO *all_rcb_info;//lnk20260617防止复用崩溃 }; diff --git a/mms/rdb_ext_utils.c b/mms/rdb_ext_utils.c index db88443..4969cc7 100644 --- a/mms/rdb_ext_utils.c +++ b/mms/rdb_ext_utils.c @@ -232,9 +232,20 @@ rptinfo_t* find_rptinfo_from_net_rcb_info(MVL_NET_INFO *net_info,RCB_INFO *rcb_i rptinfo_t *rptinfo = NULL; int cpuno,rpt_no; - chnl_usr = net_info->user_info; + if (net_info == NULL || rcb_info == NULL) { + return NULL; + } + + chnl_usr = (chnl_usr_t*)net_info->user_info; + if (chnl_usr == NULL || chnl_usr->chnl == NULL || chnl_usr->chnl->ied == NULL) { + return NULL; + } + ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); + if (ied_usr == NULL || ied_usr->LD_info == NULL) { + return NULL; + } for(cpuno=0 ; cpunocpucount; cpuno++) { LD_info = &(ied_usr->LD_info[cpuno]); diff --git a/pt61850netd_pqfe.pro b/pt61850netd_pqfe.pro index 726b62e..b0c55fd 100644 --- a/pt61850netd_pqfe.pro +++ b/pt61850netd_pqfe.pro @@ -69,23 +69,26 @@ unix { INCLUDEPATH += ./source/include/apr-linux - LIBS += -L/FeProject/lib - LIBS += -L/FeProject/lib/pgodbc - DEFINES += DEBUG_SISCO VERSION = 1.0.0 - - LIBS += -lrt -lpthread - LIBS += ./lib/libmmslib.a + LIBS += -L$$PWD/lib - LIBS += ./lib/libcurl.so \ - ./lib/libmxml.so \ - ./lib/librocketmq.so \ - ./lib/libhttprun.so \ - ./lib/liblog4cplus.so - LIBS += -lapr-1 -laprutil-1 -ljclite - LIBS += -lrdkafka++ + QMAKE_LFLAGS += -Wl,-rpath,/FeProject/lib + + LIBS += -lrt -lpthread + + LIBS += ./lib/libmmslib.a + + LIBS += -lcurl \ + -lmxml \ + -lrocketmq \ + -lhttprun \ + -llog4cplus \ + -lapr-1 \ + -laprutil-1 \ + -ljclite \ + -lrdkafka++ } #install diff --git a/set_process.sh b/set_process.sh index 063a925..24653c2 100644 --- a/set_process.sh +++ b/set_process.sh @@ -7,6 +7,14 @@ # @author: lunankun #前置all的重置或者新增都是由稳态的第一个进程来处理,所有进程收到这条消息后先判断自己的进程号是否是1,而且是稳态,否则不处理,所有操作均由这个进程完成, +# 默认使用正式版 +FE_BIN="${FE_BIN:-pt61850netd_pqfe}" + +# 如果最后一个参数是 debug,则使用调试版,并传给 detached 子进程 +if [ "$#" -gt 0 ] && [ "${!#}" = "debug" ]; then + export FE_BIN="pt61850netd_pqfed" + set -- "${@:1:$(($#-1))}" +fi if [ -z "$SETSID" ]; then export SETSID=1 @@ -44,6 +52,48 @@ fi echo $$ > "$LOCK_FILE" trap "rm -f $LOCK_FILE" EXIT +start_fe_by_runtime_debug() { + local RUNTIME_CF_FILE="/FeProject/etc/runtime.cf" + local LINE BINPATH BIN SPECIAL SLEEPSEC STARTFLAG CMD_STR + + log "[DEBUG_START] start processes from $RUNTIME_CF_FILE" + + while IFS= read -r LINE; do + [ -z "$LINE" ] && continue + [ "${LINE:0:1}" = "#" ] && continue + + BINPATH=$(echo "$LINE" | awk -F '^' '{printf $1}' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') + BIN=$(echo "$LINE" | awk -F '^' '{printf $2}' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') + SPECIAL=$(echo "$LINE" | awk -F '^' '{printf $4}' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') + SLEEPSEC=$(echo "$LINE" | awk -F '^' '{printf $5}' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') + STARTFLAG=$(echo "$LINE" | awk -F '^' '{printf $7}' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') + + if echo "$BIN" | grep -q '^fe_watchdog'; then + log "[DEBUG_START] skip watchdog: $BIN" + continue + fi + + [ "$STARTFLAG" = "IGNORE_START" ] && continue + [ -z "$BINPATH" ] || [ -z "$BIN" ] && continue + [ -z "$SLEEPSEC" ] && SLEEPSEC=0 + + sleep "$SLEEPSEC" + + CMD_STR="cd $BINPATH && ./$BIN $SPECIAL" + log "[DEBUG_START] $CMD_STR" + + nohup setsid sh -c "$CMD_STR" >>"$LOGFILE" 2>&1 < /dev/null & + done < "$RUNTIME_CF_FILE" +} + +start_fe_by_mode() { + if [ "$FE_BIN" = "pt61850netd_pqfed" ]; then + start_fe_by_runtime_debug + else + /FeProject/boot/start_fe.sh + fi +} + get_ini_value() { local key="$1" local line @@ -96,7 +146,7 @@ check_remote_conn_released() { for i in $(seq 1 20); do if ! ss -ntp 2>/dev/null \ | grep "${REMOTE_IP}:${REMOTE_PORT}" \ - | grep -E 'pt61850netd_pqfe|fe_watchdog|fe_main' >/dev/null; then + | grep -E "${FE_BIN}|fe_watchdog|fe_main" >/dev/null; then log "[OK] Remote ${REMOTE_IP}:${REMOTE_PORT} released" return 0 fi @@ -104,7 +154,7 @@ check_remote_conn_released() { log "[WAIT] Remote ${REMOTE_IP}:${REMOTE_PORT} still exists... ($i/20)" ss -ntp 2>/dev/null \ | grep "${REMOTE_IP}:${REMOTE_PORT}" \ - | grep -E 'pt61850netd_pqfe|fe_watchdog|fe_main' \ + | grep -E "${FE_BIN}|fe_watchdog|fe_main" \ | tee -a "$LOGFILE" sleep 1 done @@ -116,7 +166,7 @@ check_remote_conn_released() { log "[FAIL] Remote ${REMOTE_IP}:${REMOTE_PORT} still exists:" ss -ntp 2>/dev/null \ | grep "${REMOTE_IP}:${REMOTE_PORT}" \ - | grep -E 'pt61850netd_pqfe|fe_watchdog|fe_main' \ + | grep -E "${FE_BIN}|fe_watchdog|fe_main" \ | tee -a "$LOGFILE" return 1 @@ -280,7 +330,7 @@ kill_process_by_name() { wait_all_exit() { for i in $(seq 1 30); do - COUNT=$(ps -ef | grep -E 'pt61850netd_pqfe|fe_watchdog' | grep -v grep | wc -l) + COUNT=$(ps -ef | grep -E "${FE_BIN}|fe_watchdog" | grep -v grep | wc -l) if [ "$COUNT" -eq 0 ]; then echo "All FE processes exited" return 0 @@ -304,16 +354,16 @@ handle_reset() { #kill_process_by_name "/FeProject/bin/fe_watchdog" # 关闭旧的 stat 进程 - #kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_stat_data" + #kill_process_by_name "/FeProject/bin/${FE_BIN} -d cfg_stat_data" # 关闭旧的 recall 进程 - #kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_recallhis_data" + #kill_process_by_name "/FeProject/bin/${FE_BIN} -d cfg_recallhis_data" # 关闭旧的 3s 进程 - #kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_3s_data" + #kill_process_by_name "/FeProject/bin/${FE_BIN} -d cfg_3s_data" # 关闭旧的 comtrade 进程 - #kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_soe_comtrade" + #kill_process_by_name "/FeProject/bin/${FE_BIN} -d cfg_soe_comtrade" /FeProject/boot/stop_fe.sh @@ -336,23 +386,22 @@ handle_reset() { #看门狗固定放在第一个,防止stop时会把要杀死的进程重启 sed -i "2a\\$(printf '/FeProject/bin/ ^ fe_watchdog -m 18192 ^ ^ ^ 1 ^ IGNORE_RESTART ^\n')" /FeProject/etc/runtime.cf # 进程号为 1,按固定格式添加 - sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s 1_1^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf - sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s 1_1^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf - sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf - sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf - + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_stat_data -s 1_1^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_recallhis_data -s 1_1^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_3s_data^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_soe_comtrade^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf else #看门狗固定放在第一个,防止stop时会把要杀死的进程重启 sed -i "2a\\$(printf '/FeProject/bin/ ^ fe_watchdog -m 18192 ^ ^ ^ 1 ^ IGNORE_RESTART ^\n')" /FeProject/etc/runtime.cf # 进程号大于 1,按 -s ${i}_ 格式添加 for i in $(seq 1 $1); do # 在 runtime.cf 中插入对应的配置行,直接插入变量替换结果 - sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf - sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_stat_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_recallhis_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf done #以下部分没有多进程 - sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf - sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_3s_data^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_soe_comtrade^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf fi @@ -363,8 +412,8 @@ handle_reset() { sync # 重新启动服务 - - /FeProject/boot/start_fe.sh + start_fe_by_mode + #/FeProject/boot/start_fe.sh echo "****** reset all in $1******" >>"$LOGFILE" elif [ "$2" == "stat" ]; then @@ -373,19 +422,20 @@ handle_reset() { # 根据进程号来添加新的进程配置 for i in $(seq 1 $1); do - sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_stat_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf done # 关闭旧的看门狗进程 kill_process_by_name "/FeProject/bin/fe_watchdog" # 关闭旧的 stat 进程 - kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_stat_data" + kill_process_by_name "/FeProject/bin/${FE_BIN} -d cfg_stat_data" #sleep 5 # 启动服务不影响其他功能的进程 - /FeProject/boot/start_fe.sh + start_fe_by_mode + #/FeProject/boot/start_fe.sh echo "****** reset stat in $1******" >>"$LOGFILE" elif [ "$2" == "recall" ]; then @@ -394,18 +444,19 @@ handle_reset() { # 根据进程号来添加新的进程配置 for i in $(seq 1 $1); do - sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_recallhis_data -s ${i}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf done # 关闭旧的看门狗进程 kill_process_by_name "/FeProject/bin/fe_watchdog" # 关闭旧的 recall 进程 - kill_process_by_name "/FeProject/bin/pt61850netd_pqfe -d cfg_recallhis_data" + kill_process_by_name "/FeProject/bin/${FE_BIN} -d cfg_recallhis_data" #sleep 5 # 启动服务不影响其他功能的进程 - /FeProject/boot/start_fe.sh + start_fe_by_mode + #/FeProject/boot/start_fe.sh echo "****** reset recall in $1******" >>"$LOGFILE" else @@ -429,22 +480,22 @@ handle_add() { # 如果 $1 在 1 和 10 之间,进入处理逻辑 if [ "$2" == "all" ]; then # 检查是否已存在该条目,避免重复添加 - if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then - sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + if ! grep -q "/FeProject/bin/ ^ ${FE_BIN} -d cfg_stat_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_stat_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf fi - if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then - sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + if ! grep -q "/FeProject/bin/ ^ ${FE_BIN} -d cfg_recallhis_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_recallhis_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf fi elif [ "$2" == "stat" ]; then # 检查是否已存在该条目,避免重复添加 - if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then - sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_stat_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + if ! grep -q "/FeProject/bin/ ^ ${FE_BIN} -d cfg_stat_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_stat_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf fi elif [ "$2" == "recall" ]; then # 检查是否已存在该条目,避免重复添加 - if ! grep -q "/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then - sed -i "2a/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf + if ! grep -q "/FeProject/bin/ ^ ${FE_BIN} -d cfg_recallhis_data -s ${1}_${1}^" /FeProject/etc/runtime.cf; then + sed -i "2a/FeProject/bin/ ^ ${FE_BIN} -d cfg_recallhis_data -s ${1}_${1}^ ^ ^ 1 ^ ^" /FeProject/etc/runtime.cf fi else echo "****** process add type null ******"