_get_gt_mask、cat_mask、_get_other_mask

import torch

# 定义获取标签掩码的函数
def _get_gt_mask(logits, target):
    print("原始 logits:\n", logits)
    print("目标 target:\n", target)
    
    # 将 target 拉平为一维张量
    target = target.reshape(-1)
    print("拉平后的 target:\n", target)
    
    # 创建一个和 logits 大小相同的全零张量,然后根据 target 将对应的类别位置设置为1
    mask = torch.zeros_like(logits).scatter_(1, target.unsqueeze(1), 1).bool()
    print("生成的标签掩码 mask:\n", mask)
    
    # 返回根据 target 设置的标签掩码
    return mask

# 定义组合掩码的函数
def cat_mask(t, mask1, mask2):
    print("输入张量 t:\n", t)
    print("标签掩码 mask1:\n", mask1)
    print("非标签掩码 mask2:\n", mask2)
    
    # 计算 mask1 对应的 t 值,sum(dim=1) 表示在类别维度上进行求和
    t1 = (t * mask1).sum(dim=1, keepdims=True)
    print("标签类别的加权和 t1:\n", t1)
    
    # 计算 mask2 对应的 t 值
    t2 = (t * mask2).sum(1, keepdims=True)
    print("非标签类别的加权和 t2:\n", t2)
    
    # 将两个值拼接成新的张量
    rt = torch.cat([t1, t2], dim=1)
    print("拼接后的结果 rt:\n", rt)
    return rt

# 示例:假设有3个样本和5个类别的logits
logits = torch.tensor([[2.0, 1.0, 0.1, 3.0, 0.5],
                       [1.0, 3.0, 2.5, 0.5, 0.3],
                       [0.5, 2.2, 1.1, 4.0, 1.5]])

# 对应的标签 target
target = torch.tensor([3, 1, 4])  # 每个样本的正确类别是3, 1, 4

# 获取标签掩码
gt_mask = _get_gt_mask(logits, target)

# 获取非标签掩码
def _get_other_mask(logits, target):
    print("原始 logits:\n", logits)
    print("目标 target:\n", target)
    
    # 将 target 拉平为一维张量
    target = target.reshape(-1)
    print("拉平后的 target:\n", target)
    
    # 创建一个和 logits 大小相同的全1张量,然后根据 target 将对应的类别位置设置为0
    mask = torch.ones_like(logits).scatter_(1, target.unsqueeze(1), 0).bool()
    print("生成的非标签掩码 mask:\n", mask)
    
    return mask

other_mask = _get_other_mask(logits, target)

# 假设有某些 softmax 结果
t = torch.softmax(logits, dim=1)
print("Softmax 后的 logits (概率值):\n", t)

# 使用标签掩码和非标签掩码进行组合
combined = cat_mask(t, gt_mask, other_mask)
print("最终组合后的结果:\n", combined)

 

root@H500:/# cat /etc/config/upnpc config on_off 'upnpc_info' option mode 'auto' option enabled 'on' config entry 'vhttpd' option proto 'TCP' option ext_port '8800' option desc 'vhttpd' option status 'off' config config 'pub_ip' option ip 'null' config config 'communicate' option status 'failed' option timestamp '1630479342' config entry 'tp_live' option proto 'TCP' option desc 'tp_live' option status 'off' option ext_port '8800' option comm_status 'success' option timestamp '1761113129' config entry 'tp_vod' option proto 'TCP' option desc 'tp_vod' option status 'off' option ext_port '8800' option comm_status 'failed' option timestamp '1630479342' config entry 'tp_speaker' option proto 'TCP' option desc 'tp_speaker' option status 'off' option ext_port '8800' option comm_status 'failed' option timestamp '1630479342' config entry 'uhttpd' option proto 'TCP' option desc 'uhttpd' option status 'off' option ext_port '18443' option comm_status 'failed' option timestamp '1761115038' config entry 'tp_stream' option proto 'TCP' option desc 'tp_stream' option status 'off' option ext_port '21443' option comm_status 'failed' option timestamp '1761115038' 我的upnpc.sh是这样的:#!/bin/sh RUN_ONCE_FILE=/var/run/upnpc_running RUN_ONCE_FILE_RESTART=/var/run/upnpc_running_restart RUN_ONCE_FILE_STOP=/var/run/upnpc_running_stop if [ -e $RUN_ONCE_FILE ]; then exit 0 fi touch $RUN_ONCE_FILE . /lib/functions.sh . /usr/share/libubox/jshn.sh __network_ipaddr() { local __var="$1" local __family="$2" local __prefix="${3:-0}" local __tmp="$(ubus -t 2 call network wan_status 2&gt;/dev/null)" json_load "${__tmp:-{}}" json_get_type __tmp "ipv${__family}_address" if [ "$__tmp" = array ]; then json_select "ipv${__family}_address" json_get_type __tmp 1 if [ "$__tmp" = object ]; then json_select 1 json_get_var $__var address [ $__prefix -gt 0 ] && { json_get_var __tmp mask eval "export -- \"$__var=\${$__var}/$__tmp\"" } return 0 fi fi return 1 } # IP_ADDR=$(echo $(ifconfig) |cut -d ' ' -f7|cut -d ':' -f2) # IP_ADDR=$(cat /tmp/udhcpc/dhcpip) # network_get_ipaddr() { __network_ipaddr $1 4 0; } BIND_STATUS="" PUB_IP="" COMM_STATUS="" IP_ADDR="" COMPARE_RESULT=0 DELETE_STRING="" ADD_STRING="" # random method RANDOM_INDEX="" RANDOM_MIN=10000 RANDOM_MAX=30000 upnpc_mode=$(uci_get "upnpc" "upnpc_info" "mode") upnpc_enabled=$(uci_get "upnpc" "upnpc_info" "enabled") uhttpd_inner_port=$(uci_get "uhttpd" "main" "listen_https" "443") #vhttpd_inner_port=$(uci_get "cet" "vhttpd" "port" "8080") rtsp_inner_port=$(uci_get "cet" "rtsp" "port" "554") onvif_service_inner_port="2020" tp_live_inner_port="19443" tp_vod_inner_port="18443" tp_speaker_inner_port="17443" tp_stream_inner_port="21443" uhttpd_status=$(uci_get "upnpc" "uhttpd" "status") uhttpd_ext_port=$(uci_get "upnpc" "uhttpd" "ext_port") uhttpd_proto=$(uci_get "upnpc" "uhttpd" "proto") uhttpd_desc=$(uci_get "upnpc" "uhttpd" "desc") uhttpd_flag=1 uhttpd_mapping=0 rtsp_status=$(uci_get "upnpc" "rtsp" "status") rtsp_ext_port=$(uci_get "upnpc" "rtsp" "ext_port") rtsp_proto=$(uci_get "upnpc" "rtsp" "proto") rtsp_desc=$(uci_get "upnpc" "rtsp" "desc") rtsp_flag=2 rtsp_mapping=0 onvif_service_status=$(uci_get "upnpc" "onvif_service" "status") onvif_service_ext_port=$(uci_get "upnpc" "onvif_service" "ext_port") onvif_service_proto=$(uci_get "upnpc" "onvif_service" "proto") onvif_service_desc=$(uci_get "upnpc" "onvif_service" "desc") onvif_service_flag=4 onvif_service_mapping=0 tp_live_status=$(uci_get "upnpc" "tp_live" "status") tp_live_ext_port=$(uci_get "upnpc" "tp_live" "ext_port") tp_live_proto=$(uci_get "upnpc" "tp_live" "proto") tp_live_desc=$(uci_get "upnpc" "tp_live" "desc") tp_live_flag=8 tp_live_mapping=0 tp_vod_status=$(uci_get "upnpc" "tp_vod" "status") tp_vod_ext_port=$(uci_get "upnpc" "tp_vod" "ext_port") tp_vod_proto=$(uci_get "upnpc" "tp_vod" "proto") tp_vod_desc=$(uci_get "upnpc" "tp_vod" "desc") tp_vod_flag=16 tp_vod_mapping=0 tp_speaker_status=$(uci_get "upnpc" "tp_speaker" "status") tp_speaker_ext_port=$(uci_get "upnpc" "tp_speaker" "ext_port") tp_speaker_proto=$(uci_get "upnpc" "tp_speaker" "proto") tp_speaker_desc=$(uci_get "upnpc" "tp_speaker" "desc") tp_speaker_flag=32 tp_speaker_mapping=0 tp_stream_status=$(uci_get "upnpc" "tp_stream" "status") tp_stream_ext_port=$(uci_get "upnpc" "tp_stream" "ext_port") tp_stream_proto=$(uci_get "upnpc" "tp_stream" "proto") tp_stream_desc=$(uci_get "upnpc" "tp_stream" "desc") tp_stream_flag=1 tp_stream_mapping=0 upnpc_get_mapping() { local compare_times=0 # we will try three times at most to get port mapping while [ "$compare_times" -lt 3 ] do upnpc -l &gt; "/tmp/upnpc_output" if [ -s "/tmp/upnpc_output" ] then break; else let compare_times=$compare_times+1 sleep 1 fi done } upnpc_update_comm() { local port_status=$1 local secname=$2 local port=$3 # check status local config_status local config_ext_port local config_comm_status eval config_get config_status "${secname}" status eval config_get config_ext_port "${secname}" ext_port eval config_get config_comm_status "${secname}" comm_status if [ $config_status == $port_status ] then if [ -z $port ] then return 0 elif [ $config_ext_port == $port ] then return 0 fi fi if [ $port_status == "on" ] then if [ $PUB_IP == "null" ] then if [ $config_comm_status != "failed" ] then uci set upnpc."${secname}".comm_status='failed' timestamp=`date +%s` uci set upnpc."${secname}".timestamp=$timestamp fi else if [ $config_comm_status != "unknown" ] then uci set upnpc."${secname}".comm_status='unknown' timestamp=`date +%s` uci set upnpc."${secname}".timestamp=$timestamp fi fi elif [ $port_status == "off" ] then if [ $config_comm_status != "failed" ] then uci set upnpc."${secname}".comm_status='failed' timestamp=`date +%s` uci set upnpc."${secname}".timestamp=$timestamp fi fi } # get config values from the upnpc config file upnpc_get_config() { local secname="$1" config_get "${secname}_status" "$secname" status config_get "${secname}_ext_port" "$secname" ext_port config_get "${secname}_proto" "$secname" proto config_get "${secname}_desc" "$secname" desc } # set config values base on the "upnpc -l" results upnpc_set_config_from_real() { local secname="$1" local file_path="$2" local ip local inner_port local flag=0 while read proto ext_port ip_port desc do # divide ip_port such as 192.168.0.60:8000 into 192.168.0.60 8000 ip=$(echo $ip_port | sed 's/:.*//g') inner_port=$(echo $ip_port | sed 's/.*://g') local config_inner_port local config_proto local config_desc local config_ext_port eval config_inner_port="\${${secname}_inner_port}" eval config_proto="\${${secname}_proto}" eval config_desc="\${${secname}_desc}" eval config_ext_port="\${${secname}_ext_port}" if [ "$IP_ADDR" == "$ip" ] \ && [ "$config_inner_port" == "$inner_port" ] \ && [ "$config_proto" == "$proto" ] \ && [ "$config_desc" == "$desc" ]; then if [ "manual" == "$upnpc_mode" ] then # upnp works in manual mode # we need to keep user`s config to do port mapping again uci set upnpc."$secname".status='on' flag=1 break fi # 处理一下port变化的情况 if [ $secname == "tp_live" ] \ || [ $secname == "tp_vod" ] \ || [ $secname == "tp_speaker" ]; then upnpc_update_comm "on" $secname $ext_port fi uci set upnpc."$secname".status='on' uci set upnpc."$secname".ext_port=$ext_port flag=1 break fi done < "$file_path" if [ $flag == 0 ] then if [ $secname == "tp_live" ] \ || [ $secname == "tp_vod" ] \ || [ $secname == "tp_speaker" ]; then upnpc_update_comm "off" $secname fi uci set upnpc."$secname".status='off' fi } # compare config values with the "upnpc -l" results upnpc_compare_real_config() { local secname="$1" local file_path="$2" local mode="$3" local flag=1 local ip local inner_port while read proto ext_port ip_port desc do # divide ip_port such as 192.168.0.60:8000 into 192.168.0.60 8000 ip=$(echo $ip_port | sed 's/:.*//g') inner_port=$(echo $ip_port | sed 's/.*://g') local config_inner_port local config_ext_port local config_proto local config_desc eval config_inner_port="\${${secname}_inner_port}" eval config_ext_port="\${${secname}_ext_port}" eval config_proto="\${${secname}_proto}" eval config_desc="\${${secname}_desc}" if [ "$IP_ADDR" == "$ip" ] \ && [ "$config_inner_port" == "$inner_port" ] \ && [ "$config_ext_port" == "$ext_port" ] \ && [ "$config_proto" == "$proto" ] \ && [ "$config_desc" == "$desc" ]; then if [ "auto" == "$mode" ] \ && [ "$ext_port" -le "$RANDOM_MIN" ]; then break fi if [ $secname == "tp_live" ] \ || [ $secname == "tp_vod" ] \ || [ $secname == "tp_speaker" ]; then upnpc_update_comm "on" $secname $ext_port fi uci set upnpc."$secname".status='on' flag=0 break else # delete port, if not in config if [ "$config_desc" == "$desc" ] then upnpc -d $ext_port $proto fi fi done < "$file_path" if [ "$flag" == "1" ] then local config_flag eval config_flag="\${${secname}_flag}" let COMPARE_RESULT=$COMPARE_RESULT+$config_flag fi } # decide whether to delete certain port mapping upnpc_decide_delete_string() { local secname="$1" local proto="$2" local ext_port="$3" local ip_port="$4" local desc="$5" local mode="$6" local inner_port # divide ip_port such as 192.168.0.60:8000 into 192.168.0.60 8000 inner_port=$(echo $ip_port | sed 's/.*://g') local config_inner_port local config_ext_port local config_proto local config_desc eval config_inner_port="\${${secname}_inner_port}" eval config_ext_port="\${${secname}_ext_port}" eval config_proto="\${${secname}_proto}" eval config_desc="\${${secname}_desc}" if [ "$config_inner_port" == "$inner_port" ] \ && [ "$config_ext_port" == "$ext_port" ] \ && [ "$config_proto" == "$proto" ] \ && [ "$config_desc" == "$desc" ]; then if [ "auto" == "$mode" ] \ && [ "$ext_port" -lt "$RANDOM_MIN" ]; then # need to delete this port mapping DELETE_FLAG=1 let ${secname}_mapping=0 else # do not need to delete this port mapping DELETE_FLAG=0 # mark that the port mapping of this secname has already been done let ${secname}_mapping=1 fi fi } # build ADD_STRING upnpc_build_add_string() { local secname="$1" local mode="$2" local config_ext_port local config_proto local config_desc local config_inner_port local port_mapping eval config_inner_port="\${${secname}_inner_port}" eval config_ext_port="\${${secname}_ext_port}" eval config_proto="\${${secname}_proto}" eval config_desc="\${${secname}_desc}" eval port_mapping="\${${secname}_mapping}" if [ "0" == "$port_mapping" ] then # the port mapping of this secname has not already been done # we need to do port mapping of this secname, so add to ADD_STRING if [ "auto" != "$mode" ] \ || [ "$config_ext_port" -ge "$RANDOM_MIN" ]; then ADD_STRING=$ADD_STRING" "$config_inner_port" "$config_ext_port" "$config_proto" "$config_desc fi fi } # reconfigure port mapping in auto mode upnpc_auto_reconfigure() { #RANDOM_INDEX=$(lua -e 'math.randomseed(tostring(os.time()):reverse():sub(1, 6)); print(math.random(10000, 30000))') myrand() { if [ -z "$RANDOM" ] ; then SEED=`tr -cd 0-9 </dev/urandom | head -c 8` else SEED=$RANDOM fi RND_NUM=`echo $SEED $1 $2|awk '{srand($1);printf "%d",rand()*10000%($3-$2)+$2}'` echo $RND_NUM } RANDOM_INDEX=$(myrand 20000 30000) local compare_times=0 # we will try three times at most to do port mapping while [ "$compare_times" -lt 3 ] do COMPARE_RESULT=0 config_foreach upnpc_compare_real_config entry /tmp/upnpc_output auto if [ "0" == "$COMPARE_RESULT" ] then # the port mappings have been all successful break else # the port mappings have not been all successful # we need to build ADD_STRING based on COMPARE_RESULT ADD_STRING=$IP_ADDR local flag # randomly set the external port by +1 let flag="$COMPARE_RESULT"\&"$uhttpd_flag" if [ "$flag" -ne "0" ] then uhttpd_ext_port=$RANDOM_INDEX let RANDOM_INDEX=$RANDOM_INDEX+1 ADD_STRING=$ADD_STRING" "$uhttpd_inner_port" "$uhttpd_ext_port" "$uhttpd_proto" "$uhttpd_desc fi let flag="$COMPARE_RESULT"\&"$rtsp_flag" if [ "$flag" -ne "0" ] then rtsp_ext_port=$RANDOM_INDEX let RANDOM_INDEX=$RANDOM_INDEX+1 ADD_STRING=$ADD_STRING" "$rtsp_inner_port" "$rtsp_ext_port" "$rtsp_proto" "$rtsp_desc fi let flag="$COMPARE_RESULT"\&"$onvif_service_flag" if [ "$flag" -ne "0" ] then onvif_service_ext_port=$RANDOM_INDEX let RANDOM_INDEX=$RANDOM_INDEX+1 ADD_STRING=$ADD_STRING" "$onvif_service_inner_port" "$onvif_service_ext_port" "$onvif_service_proto" "$onvif_service_desc fi let flag="$COMPARE_RESULT"\&"$tp_live_flag" if [ "$flag" -ne "0" ] then tp_live_ext_port=$RANDOM_INDEX let RANDOM_INDEX=$RANDOM_INDEX+1 ADD_STRING=$ADD_STRING" "$tp_live_inner_port" "$tp_live_ext_port" "$tp_live_proto" "$tp_live_desc fi let flag="$COMPARE_RESULT"\&"$tp_vod_flag" if [ "$flag" -ne "0" ] then tp_vod_ext_port=$RANDOM_INDEX let RANDOM_INDEX=$RANDOM_INDEX+1 ADD_STRING=$ADD_STRING" "$tp_vod_inner_port" "$tp_vod_ext_port" "$tp_vod_proto" "$tp_vod_desc fi let flag="$COMPARE_RESULT"\&"$tp_speaker_flag" if [ "$flag" -ne "0" ] then tp_speaker_ext_port=$RANDOM_INDEX let RANDOM_INDEX=$RANDOM_INDEX+1 ADD_STRING=$ADD_STRING" "$tp_speaker_inner_port" "$tp_speaker_ext_port" "$tp_speaker_proto" "$tp_speaker_desc fi let flag="$COMPARE_RESULT"\&"$tp_stream_flag" if [ "$flag" -ne "0" ] then tp_stream_ext_port=$RANDOM_INDEX let RANDOM_INDEX=$RANDOM_INDEX+1 ADD_STRING=$ADD_STRING" "$tp_stream_inner_port" "$tp_stream_ext_port" "$tp_stream_proto" "$tp_stream_desc fi # execute the upnpc comand to do the port mapping # grep the "upnpc -l" results to get only map values that are belonged to current_ip upnpc -a $ADD_STRING \ -l | grep $IP_ADDR &gt; /tmp/upnpc_output let compare_times=$compare_times+1 fi done } # reconfigure port mapping upnpc_reconfigure() { config_load upnpc config_get upnpc_mode upnpc_info mode config_get PUB_IP pub_ip ip IP_ADDR=$(echo $(ifconfig) |cut -d ' ' -f7|cut -d ':' -f2) if [ -e /tmp/upnpc_pre_ip ] then PRE_IP=`cat /tmp/upnpc_pre_ip` else PRE_IP="" fi if [ -z "$IP_ADDR" ] \ && [ -z "$PRE_IP" ]; then # current ip and preview ip are all empty cat /tmp/upnpc_output &gt; /tmp/upnpc_output1 elif [ "$IP_ADDR" == "$PRE_IP" ] \ || [ -z "$PRE_IP" ] then # preview_ip is equal to current_ip # so we do not need to check PRE_IP PRE_IP="" # grep the "upnpc -l" results to get only map values that are belonged to current_ip cat /tmp/upnpc_output | grep "$IP_ADDR" &gt; /tmp/upnpc_output1 elif [ -z "$IP_ADDR" ] then # grep the "upnpc -l" results to get only map values that are belonged to preview_ip cat /tmp/upnpc_output | grep "$PRE_IP" &gt; /tmp/upnpc_output1 else # grep the "upnpc -l" results to get only map values that are belonged to preview_ip and current_ip cat /tmp/upnpc_output | grep -E "$IP_ADDR|$PRE_IP" &gt; /tmp/upnpc_output1 fi # grep the "upnpc -l" results to get only map values that are belonged to preview_ip and current_ip cat /tmp/upnpc_output | grep -E "$IP_ADDR|$PRE_IP" &gt; /tmp/upnpc_output1 config_foreach upnpc_get_config entry local ip while read proto ext_port ip_port desc do # divide ip_port such as 192.168.0.60:8000 into 192.168.0.60 8000 # and get the ip value such as "192.168.0.60" ip=$(echo $ip_port | sed 's/:.*//g') if [ "$IP_ADDR" == "$ip" ] then # this port mapping is belonged to IP_ADDR DELETE_FLAG=1 config_foreach upnpc_decide_delete_string entry $proto $ext_port $ip_port $desc $upnpc_mode if [ "1" == "$DELETE_FLAG" ] then # this port mapping is not useful, delete it # package the DELETE_STRING with the form: ext_port proto DELETE_STRING=$DELETE_STRING" "$ext_port" "$proto fi fi if [ "$PRE_IP" == "$ip" ] then # this port mapping is belonged to PRE_IP, delete it # package the DELETE_STRING with the form: ext_port proto DELETE_STRING=$DELETE_STRING" "$ext_port" "$proto fi done < "/tmp/upnpc_output1" # begin to build ADD_STRING ADD_STRING=$IP_ADDR config_foreach upnpc_build_add_string entry $upnpc_mode # begin to build upnpc_string local upnpc_string if [ -n "$DELETE_STRING" ] then # DELETE_STRING is not empty, add to upnpc_string upnpc_string=$upnpc_string" -d "$DELETE_STRING fi if [ "$IP_ADDR" != "$ADD_STRING" ] then # ADD_STRING is not default, add to upnpc_string upnpc_string=$upnpc_string" -a "$ADD_STRING fi # add -l to upnpc_string to list all the port mappings upnpc_string=$upnpc_string" -l" # execute the upnpc comand to do the port mapping # grep the "upnpc -l" results to get only map values that are belonged to current_ip upnpc $upnpc_string | grep $IP_ADDR &gt; /tmp/upnpc_output # save current ip into /tmp/upnpc_pre_ip echo $IP_ADDR &gt; /tmp/upnpc_pre_ip if [ "auto" == "$upnpc_mode" ] then # upnp works in auto mode, if failed # we need to use randomly port to do port mapping again upnpc_auto_reconfigure fi # set upnpc config file based on the "upnpc -l" results config_foreach upnpc_set_config_from_real entry /tmp/upnpc_output uci commit upnpc rm -f "/tmp/upnpc_output1" rm -f "/tmp/upnpc_output" } # the following function will be called outside asynchronously # so we need to add lock to prevent them from being called at the same time # maintain port mapping upnpc_maintain() { config_load cloud_brd config_get BIND_STATUS bind status config_load upnpc config_get upnpc_enabled upnpc_info enabled config_get upnpc_mode upnpc_info mode config_get PUB_IP pub_ip ip timestamp=`date +%s` echo $timestamp &gt;/dev/console if [ "$BIND_STATUS" == "1" ] then if [ "$upnpc_enabled" == "on" ] then IP_ADDR=$(echo $(ifconfig) |cut -d ' ' -f7|cut -d ':' -f2) if [ -n "$IP_ADDR" ] then lock "/var/run/upnpc" #upnpc -l &gt; "/tmp/upnpc_output" upnpc_get_mapping # grep the "upnpc -l" results to get only map values that are belonged to current_ip cat /tmp/upnpc_output | grep $IP_ADDR &gt; /tmp/upnpc_output1 COMPARE_RESULT=0 config_foreach upnpc_compare_real_config entry /tmp/upnpc_output1 $upnpc_mode if [ $COMPARE_RESULT == 0 ] then uci commit upnpc # do not need to maintain # save current ip into /tmp/upnpc_pre_ip echo $IP_ADDR &gt; /tmp/upnpc_pre_ip rm -f "/tmp/upnpc_output1" rm -f "/tmp/upnpc_output" else # need to maintain, reconfigure upnpc upnpc_reconfigure fi lock -u "/var/run/upnpc" fi fi else upnpc_stop fi } # stop port mapping upnpc_stop() { if [ -e $RUN_ONCE_FILE_STOP ]; then exit 0 fi touch $RUN_ONCE_FILE_STOP lock "/var/run/upnpc" config_load upnpc config_get PUB_IP pub_ip ip # network_get_ipaddr IP_ADDR IP_ADDR=$(echo $(ifconfig) |cut -d ' ' -f7|cut -d ':' -f2) local DELETE_STRING local PRE_IP local ip if [ -e /tmp/upnpc_pre_ip ] then PRE_IP=`cat /tmp/upnpc_pre_ip` else PRE_IP="" fi # grep the "upnpc -l" results to get only map values that are belonged to preview_ip and current_ip upnpc -l | grep -E "$IP_ADDR|$PRE_IP" &gt; "/tmp/upnpc_output" while read proto ext_port ip_port desc do # divide ip_port such as 192.168.0.60:8000 into 192.168.0.60 8000 # and get the ip value such as "192.168.0.60" ip=$(echo $ip_port | sed 's/:.*//g') if [ "$ip" == "$IP_ADDR" ] \ || [ "$ip" == "$PRE_IP" ]; then DELETE_STRING=$DELETE_STRING" "$ext_port" "$proto fi done < "/tmp/upnpc_output" if [ -n "$DELETE_STRING" ] then upnpc -d $DELETE_STRING \ -l | grep $IP_ADDR &gt; "/tmp/upnpc_output" fi config_foreach upnpc_set_config_from_real entry /tmp/upnpc_output uci commit upnpc rm -f /tmp/upnpc_output lock -u "/var/run/upnpc" rm $RUN_ONCE_FILE_STOP } # restart port mapping upnpc_restart() { if [ -e $RUN_ONCE_FILE_RESTART ]; then exit 0 fi touch $RUN_ONCE_FILE_RESTART config_load cloud_brd config_get BIND_STATUS bind status config_load upnpc config_get upnpc_enabled upnpc_info enabled if [ "$BIND_STATUS" == "1" ] then if [ "$upnpc_enabled" == "on" ] then lock "/var/run/upnpc" upnpc -l &gt; "/tmp/upnpc_output" upnpc_reconfigure lock -u "/var/run/upnpc" else upnpc_stop fi else upnpc_stop fi rm $RUN_ONCE_FILE_RESTART } case "$1" in maintain) upnpc_maintain ;; esac rm $RUN_ONCE_FILE,upnp.c代码:/***************************************************************************** * Copyright@ 2019-2021 TP-LINK TECHNOLOGIES CO., LTD. * File Name: ulinkied_upnp.c * Author: Mengmingzhan * Version: 1.0 * Description: * * information. * * History: * 2021-01-06: File created. *****************************************************************************/ #include "upnp.h" #include "udsd.h" #include <time.h&gt; #include <lib-tpcom/lib_tpcom.h&gt; #include <lib-tpcom/err_code.h&gt; #include <stdio.h&gt; #include <unistd.h&gt; #include <sys/socket.h&gt; #include <arpa/inet.h&gt; #include <string.h&gt; #include <sys/ioctl.h&gt; #include <net/if.h&gt; typedef struct _UPNPC_ENTRY_INFO { char proto[16]; char desc[16]; char ip[32]; char inner_port[8]; char ext_port[8]; } UPNPC_ENTRY_INFO; static int get_local_ip(char *ip) { FILE *fp = NULL; // char ipaddr[20] = {0}; if ((fp = fopen("/tmp/udhcpc/dhcpip", "r")) == NULL) { DBG_ERR( "open dhcpip file fail.\n"); goto END; } fseek(fp, 0L, SEEK_END); int len = ftell(fp); fseek(fp, 0L, SEEK_SET); fread(ip, 1, len-1, fp); fclose(fp); return 1; END: if (fp) fclose(fp); return 0; } void udsd_get_upnp_info(struct ubus_app *svr_ubus_app, struct blob_buf* bBuf, struct blob_attr *msg) { int ret = 0; int result = 0; char enabled[10] = {0}; char mode[10] = {0}; struct uci_context *uci_ctx = tpuci_open(); if(!uci_ctx) { result = UPNP_OTHER_ERROR; goto failed; } /* enabled */ ret = tpuci_get_val_string(uci_ctx, enabled, sizeof(enabled), "upnpc", "upnpc_info", "enabled"); if (0 != ret){ DBG_ERR( "get upnpc enabled failed.\n"); result = UPNP_PARAM_ENABLED_ERROR; goto failed; } if(strcmp(enabled, "on") && strcmp(enabled, "off")){ DBG_ERR( "upnp enabled config arg failed.\n"); result = UPNP_PARAM_ENABLED_ERROR; goto failed; } blobmsg_add_string(bBuf, "enabled", enabled); /* mode */ ret = tpuci_get_val_string(uci_ctx, mode, sizeof(mode), "upnpc", "upnpc_info", "mode"); if (0 != ret){ DBG_ERR( "get upnpc mode failed.\n"); result = UPNP_PARAM_MODE_ERROR; goto failed; } if(strcmp(mode, "auto")){ DBG_ERR( "upnp enabled config arg failed.\n"); result = UPNP_PARAM_MODE_ERROR; goto failed; } blobmsg_add_string(bBuf, "mode", "auto"); failed: tpuci_close(uci_ctx); common_end(bBuf, result); return; } void udsd_set_upnp_info(struct ubus_app *svr_ubus_app, struct blob_buf* bBuf, struct blob_attr *msg) { int ret = 0; int result = 0; char *enabled_str = NULL; char *mode_str = NULL; if (!bBuf) { DBG_ERR( "arg err\n"); return; } struct uci_context *uci_ctx = tpuci_open(); if (!msg || !uci_ctx) { DBG_ERR( "msg || uci_ctx err\n"); result = UPNP_OTHER_ERROR; goto failed; } struct blobmsg ( blobmsg_string enabled, blobmsg_string mode ) (req, msg, false); char *json_str = blobmsg_format_json(msg, true); if (json_str) { DBG_ERR("Received params: %s\n", json_str); free(json_str); } if (!req.enabled) { DBG_ERR( "set upnpc blobmsg err\n"); result = UPNP_PARAM_ENABLED_ERROR; goto failed; } if (!req.mode) { DBG_ERR( "set upnpc blobmsg err\n"); result = UPNP_PARAM_MODE_ERROR; goto failed; } enabled_str = blobmsg_get_string(req.enabled); mode_str = blobmsg_get_string(req.mode); /* enabled */ if(strcmp(enabled_str, "on") && strcmp(enabled_str, "off")){ DBG_ERR( "upnpc enabled config arg failed.\n"); result = UPNP_PARAM_ENABLED_ERROR; goto failed; } ret = tpuci_set_val(uci_ctx, enabled_str, "upnpc", "upnpc_info", "enabled", 1); if (0 != ret){ DBG_ERR( "set upnp enabled format uci err\n"); result = UPNP_PARAM_ENABLED_ERROR; goto failed; } /* mode */ if(strcmp(mode_str, "auto")){ DBG_ERR( "upnpc mode config arg failed.\n"); result = UPNP_PARAM_MODE_ERROR; goto failed; } ret = tpuci_set_val(uci_ctx, mode_str, "upnpc", "upnpc_info", "mode", 1); if (0 != ret){ DBG_ERR( "set upnp mode format uci err\n"); result = UPNP_PARAM_MODE_ERROR; goto failed; } system(". /lib/upnpc/upnpc.sh; upnpc_restart"); failed: tpuci_close(uci_ctx); common_end(bBuf, result); return; } void udsd_get_upnp_status(struct ubus_app *svr_ubus_app, struct blob_buf* bBuf, struct blob_attr *msg) { int ret = 0; int i = 0; int result = 0; char ipaddr[20] = {0}; char status[20] = {0}; char proto[20] = {0}; char desc[20] = {0}; int inner_port = 0; int ext_port = 0; // char mode[8] = {0}; FILE *fp = NULL; char buf[128] = {0}; char *lines[LINES_MAX] = {0}; char *read_buf = NULL; int lines_cnt = 0; int flag[7] = {0}; UPNPC_ENTRY_INFO entries_info; int part_num = 0; char *entry[] = {"uhttpd", "rtsp", "onvif_service", "tp_live", "tp_vod", "tp_speaker", "tp_stream"}; int fix_port[] = {443, 554, 2020, 19443, 18443, 17443, 21443}; struct uci_context *uci_ctx = tpuci_open(); if(!uci_ctx) { result = UPNP_OTHER_ERROR; goto failed; } /* ipaddr */ if ( 0 == get_local_ip(ipaddr) || NULL == ipaddr) { DBG_ERR( "get upnpc local ip failed.\n"); result = UPNP_PARAM_IPADDR_ERROR; goto failed; } fp = popen("upnpc -l", "r"); if (!fp) { goto failed; } while (NULL != (read_buf = fgets(buf, 128, fp)) && strlen(read_buf) != 0) { lines[i] = strdup(read_buf); DBG_ERR("line: %s\n", lines[i]); i++; /* 最大支持16行数据,超过则做截断处理 */ if (i &gt;= LINES_MAX) { break; } } lines_cnt = i; struct blob_buf b_tmp = {NULL}; blobmsg_buf_init(&b_tmp); for (i = 0; i < lines_cnt; i++) { if (strstr(lines[i], ipaddr)) { part_num = sscanf(lines[i], "%15[^ ]%*[ ]%7[^ ]%*[ ]%31[^:]:%7[^ ]%*[ ]%15s", entries_info.proto, entries_info.ext_port, entries_info.ip, entries_info.inner_port, entries_info.desc); if (part_num == 5) { if (0 == strlen(ipaddr)) { sscanf(entries_info.ip, "%s", ipaddr); } void *table = NULL; if (NULL != (table = blobmsg_open_table(&b_tmp, entries_info.desc))) { //DBG_ERR("desc: %s\n", entries_info.desc); blobmsg_add_u32(&b_tmp, "ext_port", atoi(entries_info.ext_port)); blobmsg_add_u32(&b_tmp, "inner_port", atoi(entries_info.inner_port)); blobmsg_close_table(&b_tmp, table); //DBG_DBG_BLOB(b_tmp.head); } } } } blobmsg_add_string(bBuf, "ipaddr", ipaddr); struct blobmsg ( blobmsg_table uhttpd, blobmsg_table rtsp, blobmsg_table onvif_service, blobmsg_table tp_live, blobmsg_table tp_vod, blobmsg_table tp_speaker, blobmsg_table tp_stream, ) (info, b_tmp.head, false); if (info.uhttpd) flag[0] = 1; if (info.rtsp) flag[1] = 1; if (info.onvif_service) flag[2] = 1; if (info.tp_live) flag[3] = 1; if (info.tp_vod) flag[4] = 1; if (info.tp_speaker) flag[5] = 1; if (info.tp_stream) flag[6] = 1; //DBG_ERR( "flag: %d, %d, %d\n", flag[0],flag[1],flag[2]); void *array; void *table; if (NULL != (array = blobmsg_open_array(bBuf, "entry_list"))) { for (i = 0; i < 6; i++) { /* proto */ ret = tpuci_get_val_string(uci_ctx, proto, sizeof(proto), "upnpc", entry[i], "proto"); if (0 != ret){ DBG_ERR( "get upnpc proto failed.\n"); result = UPNP_PARAM_PROTO_ERROR; goto failed; } /* desc */ ret = tpuci_get_val_string(uci_ctx, desc, sizeof(desc), "upnpc", entry[i], "desc"); if (0 != ret){ DBG_ERR( "get upnpc desc failed.\n"); result = UPNP_PARAM_DESC_ERROR; goto failed; } /* status */ if (0 == flag[i]) { strcpy(status, "off"); }else { strcpy(status, "on"); } /* ext_port */ if (0 == flag[i]) { ext_port = 0; }else { if (0 == i) { struct blobmsg ( blobmsg_int32 ext_port, ) (src, info.uhttpd, false); if (src.ext_port) ext_port = blobmsg_get_u32(src.ext_port); } if (1 == i) { struct blobmsg ( blobmsg_int32 ext_port, ) (src, info.rtsp, false); if (src.ext_port) ext_port = blobmsg_get_u32(src.ext_port); } if (2 == i) { struct blobmsg ( blobmsg_int32 ext_port, ) (src, info.onvif_service, false); if (src.ext_port) ext_port = blobmsg_get_u32(src.ext_port); } if (3 == i) { struct blobmsg ( blobmsg_int32 ext_port, ) (src, info.tp_live, false); if (src.ext_port) ext_port = blobmsg_get_u32(src.ext_port); } if (4 == i) { struct blobmsg ( blobmsg_int32 ext_port, ) (src, info.tp_vod, false); if (src.ext_port) ext_port = blobmsg_get_u32(src.ext_port); } if (5 == i) { struct blobmsg ( blobmsg_int32 ext_port, ) (src, info.tp_speaker, false); if (src.ext_port) ext_port = blobmsg_get_u32(src.ext_port); } if (6 == i) { struct blobmsg ( blobmsg_int32 ext_port, ) (src, info.tp_stream, false); if (src.ext_port) ext_port = blobmsg_get_u32(src.ext_port); } } /* inner_port */ inner_port = fix_port[i]; /* add info */ if (NULL != (table = blobmsg_open_table(bBuf, NULL))) { blobmsg_add_u32(bBuf, "inner_port", inner_port); blobmsg_add_string(bBuf, "status", status); blobmsg_add_string(bBuf, "proto", proto); blobmsg_add_string(bBuf, "desc", desc); blobmsg_add_u32(bBuf, "ext_port", ext_port); blobmsg_close_table(bBuf, table); } else { DBG_ERR("blobmsg_open_table failed.\n"); result = UPNP_OTHER_ERROR; } } blobmsg_close_array(bBuf, array); } else { DBG_ERR("blobmsg_open_array failed.\n"); result = UPNP_OTHER_ERROR; } failed: tpuci_close(uci_ctx); common_end(bBuf, result); blob_buf_free(&b_tmp); pclose(fp); for (i = 0; i < lines_cnt; i++) { SAFE_FREE(lines[i]); } return; } void udsd_get_pub_ip(struct ubus_app *svr_ubus_app, struct blob_buf* bBuf, struct blob_attr *msg) { int ret = 0; int result = 0; char pubip[20] = {0}; struct uci_context *uci_ctx = tpuci_open(); if(!uci_ctx) { result = UPNP_OTHER_ERROR; goto failed; } ret = tpuci_get_val_string(uci_ctx, pubip, sizeof(pubip), "upnpc", "pub_ip", "ip"); if (0 != ret){ DBG_ERR( "get upnpc pub_ip failed.\n"); result = UPNP_PARAM_PUBIP_ERROR; goto failed; } blobmsg_add_string(bBuf, "ip", pubip); failed: tpuci_close(uci_ctx); common_end(bBuf, result); return; } void udsd_get_upnp_commstatus(struct ubus_app *svr_ubus_app, struct blob_buf* bBuf, struct blob_attr *msg) { int ret = 0; int result = 0; int timestamp = 0; char desc[15] = {0}; char status_str[10] = {0}; char *comm[] = {"uhttpd", "rtsp", "onvif_service", "tp_live", "tp_vod", "tp_speaker", "tp_stream"}; struct uci_context *uci_ctx = tpuci_open(); if(!uci_ctx) { result = UPNP_OTHER_ERROR; goto failed; } void *array; void *table; int i = 0; if (NULL != (array = blobmsg_open_array(bBuf, "comm_list"))) { for (i = 0; i < 6; i++) { /* desc */ ret = tpuci_get_val_string(uci_ctx, desc, sizeof(desc), "upnpc", comm[i], "desc"); if (0 != ret){ DBG_ERR( "get upnpc desc failed.\n"); result = UPNP_PARAM_DESC_ERROR; goto failed; } /* comm_status */ ret = tpuci_get_val_string(uci_ctx, status_str, sizeof(status_str), "upnpc", comm[i], "comm_status"); if (0 != ret){ DBG_ERR( "get upnpc comm_status failed.\n"); result = UPNP_PARAM_COMM_STATUS_ERROR; goto failed; } /* timestamp */ ret = tpuci_get_val_int(uci_ctx, &timestamp, "upnpc", comm[i], "timestamp"); if (0 != ret){ DBG_ERR( "get upnpc timestamp failed.\n"); result = UPNP_PARAM_COMM_TIMESTAMP_ERROR; goto failed; } /* add info */ if (NULL != (table = blobmsg_open_table(bBuf, NULL))) { blobmsg_add_string(bBuf, "desc", desc); blobmsg_add_string(bBuf, "comm_status", status_str); blobmsg_add_u32(bBuf, "timestamp", timestamp); blobmsg_close_table(bBuf, table); } else { DBG_ERR("blobmsg_open_table failed.\n"); result = UPNP_OTHER_ERROR; } } blobmsg_close_array(bBuf, array); } else { DBG_ERR("blobmsg_open_array failed.\n"); result = UPNP_OTHER_ERROR; } failed: tpuci_close(uci_ctx); common_end(bBuf, result); return; } void udsd_set_upnp_commstatus(struct ubus_app *svr_ubus_app, struct blob_buf* bBuf, struct blob_attr *msg) { if (!bBuf) { DBG_ERR( "arg err\n"); return; } int ret = 0; int result = 0; char *status_str = NULL; char *desc = NULL; int timestamp = 0; time_t time_now = 0; struct uci_context *uci_ctx = tpuci_open(); if (!msg || !uci_ctx) { DBG_ERR( "msg || uci_ctx err\n"); result = UPNP_OTHER_ERROR; goto failed; } struct blobmsg ( blobmsg_string comm_status, blobmsg_string desc, blobmsg_int32 timestamp ) (req, msg, false); char *json_str = blobmsg_format_json(msg, true); if (json_str) { DBG_ERR("Received params: %s\n", json_str); free(json_str); } if (!req.comm_status) { DBG_ERR( "set upnpc blobmsg err\n"); result = UPNP_PARAM_COMM_STATUS_ERROR; goto failed; } if (!req.timestamp) { DBG_ERR( "set upnpc blobmsg err\n"); result = UPNP_PARAM_COMM_TIMESTAMP_ERROR; goto failed; } if (!req.desc) { DBG_ERR( "set upnpc blobmsg err\n"); result = UPNP_PARAM_DESC_ERROR; goto failed; } status_str = blobmsg_get_string(req.comm_status); desc = blobmsg_get_string(req.desc); timestamp = blobmsg_get_u32(req.timestamp); DBG_ERR( "status_str:%s\n",status_str); DBG_ERR( "desc:%s\n",desc); DBG_ERR( "timestamp:%d\n",timestamp); /* comm_status */ if(strcmp(status_str, "failed") && strcmp(status_str, "success") && strcmp(status_str, "unknown")){ DBG_ERR( "upnpc config arg failed.\n"); result = UPNP_PARAM_COMM_STATUS_ERROR; goto failed; } ret = tpuci_set_val(uci_ctx, status_str, "upnpc", desc, "comm_status", 1); if (0 != ret){ DBG_ERR( "set upnp comm_status format uci err\n"); result = UPNP_PARAM_COMM_STATUS_ERROR; goto failed; } /* timestamp */ time_now = time(NULL); if (timestamp - time_now &gt; 86400 || time_now - timestamp &gt; 86400) { DBG_ERR("timestamp too large or small."); result = UPNP_PARAM_COMM_TIMESTAMP_ERROR; goto failed; } ret = tpuci_set_val_int(uci_ctx, timestamp, "upnpc", desc, "timestamp", 1); if (0 != ret){ DBG_ERR( "set upnp timestamp format uci err\n"); result = UPNP_PARAM_COMM_TIMESTAMP_ERROR; goto failed; } failed: tpuci_close(uci_ctx); common_end(bBuf, result); return; } /**************************************************************************************************/ /* PUBLIC_FUNCTIONS */ /**************************************************************************************************/ static const UDSD_MOD_CMD g_udsd_cmds_upnp[] = { {UDSD_CMD_R, "get_upnp_info", udsd_get_upnp_info}, {UDSD_CMD_W, "set_upnp_info", udsd_set_upnp_info}, {UDSD_CMD_R, "get_upnp_status", udsd_get_upnp_status}, {UDSD_CMD_R, "get_pub_ip", udsd_get_pub_ip}, {UDSD_CMD_R, "get_upnp_commstatus", udsd_get_upnp_commstatus}, {UDSD_CMD_W, "set_upnp_commstatus", udsd_set_upnp_commstatus}, {UDSD_CMD_N, NULL, NULL} }; UDSD_CMD_ADD(upnp, "upnp", g_udsd_cmds_upnp); upnpc.config:config on_off 'upnpc_info' option enabled 'on' option mode 'auto' config entry 'uhttpd' option proto 'TCP' option desc 'uhttpd' option status 'off' option ext_port '18443' option comm_status 'failed' option timestamp '1761115038' config entry 'tp_stream' option proto 'TCP' option desc 'tp_stream' option status 'off' option ext_port '21443' option comm_status 'failed' option timestamp '1761115038' config entry 'tp_live' option proto 'TCP' option desc 'tp_live' option status 'off' option ext_port '18445' option comm_status 'failed' option timestamp '1761115038' config entry 'tp_vod' option proto 'TCP' option desc 'tp_vod' option status 'off' option ext_port '18446' option comm_status 'failed' option timestamp '1761115038' config entry 'tp_speaker' option proto 'TCP' option desc 'tp_speaker' option status 'off' option ext_port '18447' option comm_status 'failed' option timestamp '1761115038' config config 'pub_ip' option ip 'null' 分析下为什么cat /etc/config/upnpc得到的结果不是预期的。
最新发布
10-23
你使用 `cat /etc/config/upnpc` 得到的结果和你预期的不一致,**最可能的原因是:** 你看到的并不是 `/etc/config/upnpc` 文件本身的内容,而是系统中存在多个配置文件副本,或者 `/etc/config/upnpc` 被其他进程动态修改过,甚至可能被符号链接指向了另一个位置。 --- ## 一、可能原因分析 ### 1. **文件路径错误或被软链接覆盖** 你看到的 `/etc/config/upnpc` 文件可能并不是你预期的文件,而是被软链接指向了其他位置。 **验证方式:** ```bash ls -l /etc/config/upnpc ``` 如果输出类似: ```bash lrwxrwxrwx 1 root root 15 Jan 1 00:00 /etc/config/upnpc -&gt; /tmp/upnpc.conf ``` 说明该文件是一个软链接,实际内容在 `/tmp/upnpc.conf` 中。 --- ### 2. **`/etc/config/upnpc` 是动态生成的** 有些嵌入式设备(如 OpenWrt)会将配置文件从 `/tmp` 加载到 `/etc/config/`,但实际运行时是通过 `uci` 命令从内存中读取配置,而不是直接读取 `/etc/config/upnpc` 文件。 **验证方式:** ```bash uci show upnpc ``` 这个命令会显示当前运行时的配置,可能与文件内容不一致(因为文件未同步)。 --- ### 3. **文件未保存或被缓存** 你修改了 `/etc/config/upnpc`,但未执行 `uci commit upnpc`,导致修改未生效。 **验证方式:** ```bash uci show upnpc ``` 如果你看到的配置和文件内容不一致,说明文件没有被正确加载或保存。 --- ### 4. **多个配置文件副本** 你可能编辑了 `/etc/config/upnpc`,但系统中存在其他副本(如 `/tmp/upnpc`, `/var/etc/upnpc`, `/etc/upnpc.conf`)被实际使用。 **建议:** ```bash find / -name upnpc -o -name upnpc.conf ``` --- ### 5. **脚本或程序动态修改了配置** 你的脚本 `upnpc.sh` 和 C 程序 `upnp.c` 都在通过 `uci` 动态修改配置,这可能导致配置文件与你手动编辑的内容不一致。 **例如:** - `upnpc.sh` 会在运行时通过 `uci set upnpc.<section&gt;.<option&gt;=<value&gt;` 修改配置。 - `upnp.c` 中的 `udsd_set_upnp_info()` 函数也会修改 `upnpc_info` 的 `enabled` 和 `mode`。 --- ## 二、建议排查步骤 ### ✅ 1. 检查文件路径和软链接 ```bash ls -l /etc/config/upnpc ``` ### ✅ 2. 使用 `uci` 查看运行时配置 ```bash uci show upnpc ``` ### ✅ 3. 检查是否存在其他副本 ```bash find / -name upnpc -o -name upnpc.conf ``` ### ✅ 4. 确认配置是否已提交 ```bash uci commit upnpc ``` ### ✅ 5. 查看脚本和 C 程序是否修改了配置 - `upnpc.sh` 中的 `uci set upnpc.xxx.xxx=xxx` - `upnp.c` 中的 `tpuci_set_val()` 函数 --- ## 三、建议修复方式 ### 方法一:用 `uci` 命令修改配置(推荐) ```bash uci set upnpc.upnpc_info.mode='auto' uci set upnpc.upnpc_info.enabled='on' uci set upnpc.tp_live.ext_port='8800' uci set upnpc.tp_live.status='on' uci commit upnpc ``` ### 方法二:手动编辑配置文件并提交 ```bash vi /etc/config/upnpc uci commit upnpc ``` --- ## 四、总结 | 原因 | 说明 | 检测方式 | 修复建议 | |------|------|----------|-----------| | 软链接覆盖 | 文件被链接到其他位置 | `ls -l` | 删除软链接或修改目标文件 | | 动态配置 | `uci` 从内存加载配置 | `uci show upnpc` | 使用 `uci` 命令修改配置 | | 未提交修改 | 修改文件后未执行 `uci commit` | `uci show upnpc` vs 文件内容 | 执行 `uci commit upnpc` | | 多个副本 | 存在多个配置文件 | `find / -name upnpc` | 统一修改主配置文件 | | 程序修改 | 脚本或 C 程序修改配置 | 查看代码逻辑 | 调整逻辑或限制修改权限 | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值