D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
lib
/
vz-tools
/
tools
/
scripts
/
Filename :
functions
back
Copy
#!/bin/bash # Copyright (c) 2015-2017, Parallels International GmbH # Copyright (c) 2017-2019 Virtuozzo International GmbH. All rights reserved. # Set the sane umask umask 022 # Error codes VZ_INVALID_PARAMETER_SYNTAX=20 VZ_FS_NO_DISK_SPACE=46 VZ_FS_BAD_TMPL=47 VZ_FS_NEW_VE_PRVT=48 VZ_CHANGEPASS=74 VZ_CANT_ADDIP=34 VZ_IP_INUSE=78 VZ_SET_RATE=80 VZ_SET_ACCOUNT=81 CP='/bin/cp -fp' [ -f /etc/fedora-release ] && CP='/bin/cp -f --preserve=mode,ownership' NWSYSTEMDIR="/etc/NetworkManager" NWSYSTEMCONF="$NWSYSTEMDIR/nm-system-settings.conf" NMCONFFILE="$NWSYSTEMDIR/NetworkManager.conf" NWSYSTEMCONNECTIONS="$NWSYSTEMDIR/system-connections" NWCONFDIR="$NWSYSTEMDIR/conf.d" NWMANAGER="/etc/init.d/NetworkManager" NWMANAGER_FAILED=0 [ -f "${NWMANAGER}" ] || NWMANAGER="/etc/init.d/network-manager" SYSTEMCTL="/bin/systemctl" INITDIR="/etc/init.d" NETTOOL_LOG="/var/log/vz-nettool.log" DEBIAN_CONFIGFILE="/etc/network/interfaces" DEBIAN_CONFIGFILES="$DEBIAN_CONFIGFILE /etc/network/interfaces.d/*" NETPLAN_CFG="netplan-cfg.py" #options used in *-set_ip.sh USE_DHCPV4=0 USE_DHCPV6=0 # Prints error message and exits # Parameters: # $1 - error message # $2 - exit code # Example of usage: # error "Fatal error" 1 function error() { # print errors to stdout too ERR=$? echo "$SELFNAME ERROR: $1" exit $2 } # Puts line # NAME="value" # to config file. If NAME is found, line gets replaced, # otherwise it is added to the end of file. # Parameters: # $1 - config file # $2 - NAME # $3 - value function put_param() { local file="$1" local name="$2" local value="$3" local path path=${file%/*} if [ ! -d "${path}" ]; then mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE fi if grep -E "^$name=.*" $file>/dev/null 2>&1; then ${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE /bin/sed -e "s|^$name=.*|$name=\"$value\"|" < ${file} > ${file}.$$ if [ $? -ne 0 ]; then rm -f ${file}.$$ 2>/dev/null error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi mv -f ${file}.$$ ${file} else echo "$name=\"$value\"" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi } # Adds value to variable NAME # in config file. If NAME is found, value gets added, # otherwise it is added to the end of file. # Parameters: # $1 - config file # $2 - NAME # $3 - value function add_param() { local file=$1 local name=$2 local value=$3 local path path=${file%/*} if [ ! -d "${path}" ]; then mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE fi if grep -qe "^$name=" $file >/dev/null 2>&1; then ${CP} ${file} ${file}.$$ || \ error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE /bin/sed -e "s|^$name=\"\(.*\)\"|$name=\"\1 $value \"|" < ${file} > ${file}.$$ if [ $? -ne 0 ]; then rm -f ${file}.$$ 2>/dev/null error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi mv -f ${file}.$$ ${file} else echo "$name=\"$value\"" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi } function del_param() { local file=$1 local name=$2 local value="$3" local path path=${file%/*} if [ ! -d "${path}" ]; then mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE fi if grep -qe "^$name=" $file >/dev/null 2>&1; then ${CP} ${file} ${file}.$$ || \ error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE if [ -z "${value}" ]; then /bin/sed -e "/^${name}=.*/d" < ${file} > ${file}.$$ else sed -e "s|^${name}=\(.*\)${value}\(.*\)|${name}=\1\2|" <${file} > ${file}.$$ fi if [ $? -ne 0 ]; then rm -f ${file}.$$ 2>/dev/null error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi mv -f ${file}.$$ ${file} fi } # Puts line # NAME value # to config file. If NAME is found, line gets replaced, # otherwise it is added to the end of file. # Parameters: # $1 - config file # $2 - NAME # $3 - value function put_param2() { local file="$1" local name="$2" local value="$3" local path; path=${file%/*} if [ ! -d "${path}" ]; then mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE fi if grep -E "^\<$name\>" $file>/dev/null 2>&1; then ${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE /bin/sed -e "s|^\<$name\>.*|$name $value|" < ${file} > ${file}.$$ if [ $? -ne 0 ]; then rm -f ${file}.$$ 2>/dev/null error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi mv -f ${file}.$$ ${file} else echo "$name $value" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi } function del_param2() { local file=$1 local name=$2 local value="$3" local path path=${file%/*} if [ ! -d "${path}" ]; then mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE fi if grep -qe "^$name " $file >/dev/null 2>&1; then ${CP} ${file} ${file}.$$ || \ error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE if [ -z "${value}" ]; then /bin/sed -e "/^${name} .*/d" < ${file} > ${file}.$$ else sed -e "s|^${name} \(.*\)${value}\(.*\)|${name} \1\2|" <${file} > ${file}.$$ fi if [ $? -ne 0 ]; then rm -f ${file}.$$ 2>/dev/null error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi mv -f ${file}.$$ ${file} fi } # Puts line # NAME=( value ) # to config file. If NAME is found, line gets replaced, # otherwise it is added to the end of file. # Parameters: # $1 - config file # $2 - NAME # $3 - value function put_param3() { local file=$1 local name=$2 local value=$3 local path path=${file%/*} if [ ! -d "${path}" ]; then mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE fi if grep -E "^$name=\(.*\)" $file>/dev/null 2>&1; then ${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE if [ -z "${value}" ]; then /bin/sed -e "s|^$name=\(.*\)|$name=\( \)|" < ${file} > ${file}.$$ else /bin/sed -e "s|^$name=\(.*\)|$name=\( \"$value\" \)|" < ${file} > ${file}.$$ fi if [ $? -ne 0 ]; then rm -f ${file}.$$ 2>/dev/null error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi mv -f ${file}.$$ ${file} else if [ -z "${value}" ]; then echo "$name=( )" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE else echo "$name=( \"$value\" )" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi fi } # Adds value to array NAME # in config file. If NAME is found, value gets added, # otherwise it is added to the end of file. # Parameters: # $1 - config file # $2 - NAME # $3 - value function add_param3() { local file=$1 local name=$2 local value=$3 local path path=${file%/*} if [ ! -d "${path}" ]; then mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE fi if grep -E "^$name=\(.*\)" $file>/dev/null 2>&1; then ${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE /bin/sed -r "s|^$name=\((.*)\)|$name=\( \1 \"$value\" \)|" < ${file} > ${file}.$$ if [ $? -ne 0 ]; then rm -f ${file}.$$ 2>/dev/null error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi mv -f ${file}.$$ ${file} else echo "$name=( \"$value\" )" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi } # Removes value from array NAME # in config file. If NAME is found, value gets removed, # otherwise this is a noop function. # Parameters: # $1 - config file # $2 - NAME # $3 - value function del_param3() { local file=$1 local name=$2 local value=$3 [ ! -f $file ] && return if grep -E "^$name=\(.*\)" $file>/dev/null 2>&1; then ${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE /bin/sed -r "s|^($name=\( .*)\"$value\"(.* \))|\1\2|" < ${file} > ${file}.$$ if [ $? -ne 0 ]; then rm -f ${file}.$$ 2>/dev/null error "Can't change file $file" $VZ_FS_NO_DISK_SPACE fi mv -f ${file}.$$ ${file} else return fi } function is_netplan_controlled() { if which netplan >/dev/null 2>/dev/null; then return 0 else return 1 fi } function remove_debian_interface() { local dev="$1" local cfg="$2" local ret=0 ${CP} ${cfg} ${cfg}.$$ || \ error "Can't copy file ${cfg}" $VZ_FS_NO_DISK_SPACE awk ' NF == 0 {next} $1 == "iface" || $1 == "mapping" || $1 == "auto" || $1 ~ /allow-/ || $1 == "source" \ || $1 == "source-directory" {skip = 0} $1 == "auto" && $2 ~/'${dev}'$/ {skip = 1} $1 == "allow-hotplug" && $2 ~/'${dev}'$/ {skip = 1} $1 == "iface" && $2 ~/'${dev}'$/ {skip = 1} skip {next} {print} ' < ${cfg} > ${cfg}.$$ && cp -f ${cfg}.$$ ${cfg} diff -q ${cfg}.$$ ${cfg} > /dev/null 2>&1 ret=$? rm -f ${cfg}.$$ 2>/dev/null return $ret } function remove_debian_interfaces() { local dev="$1" local cf local ret=0 for cf in $DEBIAN_CONFIGFILES; do [ ! -f $cf ] && continue remove_debian_interface $dev $cf [ $ret -eq 0 ] && ret=$? done return $ret } function change_hostname() { local cfg="$1" local host="$2" local ip="$3" local comm='# Auto-generated hostname. Please do not remove this comment.' [ -f "${cfg}" ] || touch ${cfg} if [ "${host}" = "localhost" -o "${host}" = "localhost.localdomain" ]; then put_param2 ${cfg} "127.0.0.1" "localhost.localdomain localhost" return fi ${CP} ${cfg} ${cfg}.$$ || \ error "Can't copy file ${cfg}" $VZ_FS_NO_DISK_SPACE awk -v ip="${ip}" -v host="${host}" -v comm="${comm}" ' BEGIN {found = 0; skip = 0} $0 == comm {found = 1; next} found { if (ip == "") {ip = $1} found = 0; next; } $0 ~ "\\<" host "\\>" { if (!skip) { skip = 1; } else { next; } } {print} END { if (skip) exit 0; if (ip == "") { ip ="127.0.0.1" } print comm; alias="" if ((i=index(host, ".")) > 1) { alias=substr(host, 1, i - 1); } print ip " " host " " alias; } ' < ${cfg} > ${cfg}.$$ if [ $? -ne 0 ]; then rm -f ${cfg}.$$ 2>/dev/null error "Can't change file ${cfg}" $VZ_FS_NO_DISK_SPACE fi mv -f ${cfg}.$$ ${cfg} } function is_ipv6() { if [ "${1#*:}" != "${1}" ]; then return 0 else return 1 fi } check_dhcp() { local found= for pkg in dhcpcd dhclient; do for p in /sbin /usr/sbin; do if [ -x $p/$pkg ]; then found=1; break; fi done done [ -z "$found" ] && echo "Warning: DHCP client daemon not found" } check_dhcp_ipv6() { local found= for p in /sbin /usr/sbin; do if [ -x $p/dhcp6c ]; then found=1; break; fi done [ -z "$found" ] && echo "Warning: DHCP IPv6 client daemon not found" } regen_dhcp6c_conf() { local eths="$*" local conf="/etc/wide-dhcpv6/dhcp6c.conf" local num=0 local dev [ -d "/etc/wide-dhcpv6" ] || return /bin/rm -f $conf touch $conf for dev in $eths; do echo " interface $dev { send ia-na $num; request domain-name-servers; request domain-name; }; id-assoc na $num { }; " >> $conf let num=nom+1 done } set_wide_dhcpv6() { local ETH_DEV=$1 local config="/etc/default/wide-dhcpv6-client" local ifaces="" if [ -f $config ]; then check_dhcp_ipv6 . $config for iface in $INTERFACES; do if [ "x$iface" != "x${ETH_DEV}" ]; then ifaces="$iface " else return 0 fi done ifaces=`echo $ifaces | sed "s, $,,g"` if [ -z $ifaces ]; then echo "INTERFACES=\"${ETH_DEV}\"" > $config regen_dhcp6c_conf "${ETH_DEV}" else echo "INTERFACES=\"$ifaces ${ETH_DEV}\"" > $config regen_dhcp6c_conf "$ifaces ${ETH_DEV}" fi /etc/init.d/wide-dhcpv6-client restart >/dev/null 2>&1 /usr/sbin/update-rc.d -f wide-dhcpv6-client defaults >/dev/null 2>&1 fi } unset_wide_dhcpv6() { local ETH_DEV=$1 local config="/etc/default/wide-dhcpv6-client" if [ -f $config ]; then . $config for iface in $INTERFACES; do if [ "x$iface" != "x${ETH_DEV}" ]; then ifaces="$iface " fi done ifaces=`echo $ifaces | sed "s, $,,g"` echo "INTERFACES=\"$ifaces\"" > $config regen_dhcp6c_conf "$ifaces" fi } set_options() { local options=" ${1} " [ "${options/ dhcp }" != "${options}" ] && USE_DHCPV4=1 [ "${options/ dhcpv6 }" != "${options}" ] && USE_DHCPV6=1 } need_to_disable_network_manager() ( local path="/etc/os-release" if [ -f "$path" ]; then source "$path" VERSION_ID=${VERSION_ID//.*} # no need to disable NetworkManager for Fedora >= 21 [ "$ID" == "fedora" -a $VERSION_ID -lt 21 ] && return 1 [ "$ID" == "centos" -a $VERSION_ID -lt 7 ] && return 1 [ "$ID" == "redos" -a $VERSION_ID -lt 7 ] && return 1 [ "$ID" == "virtuozzo" -a $VERSION_ID -lt 7 ] && return 1 [ "$ID" == "cloudlinux" -a $VERSION_ID -lt 7 ] && return 1 [ "$ID" == "rhel" -a $VERSION_ID -lt 7 ] && return 1 fi return 0 ) service_command() { local service=$1 local cmd=$2 if [ -x $SYSTEMCTL ]; then $SYSTEMCTL $cmd $service > /dev/null 2>&1 else $INITDIR/$service $cmd > /dev/null 2>&1 fi } disable_network_manager() { need_to_disable_network_manager [ $? -eq 0 ] && return local nm_sysv="/etc/init.d/NetworkManager" if [ -x $SYSTEMCTL ]; then disable_network_manager_systemd else disable_network_manager_sysv fi } disable_network_manager_systemd() { local nm="NetworkManager" local timeout=15 local service=`find /etc/systemd/ -name $nm.service 2>/dev/null` local dhclient="dhclient" local dhclient_pids="" [ "x$service" = "x" ] && return # Will wait for start complete while [ $timeout -gt 0 ]; do $SYSTEMCTL status $nm [ $? -eq 0 ] && break sleep 1 timeout=$((timeout-1)) done if [ $timeout -eq 0 ]; then $SYSTEMCTL status $nm [ $? -ne 0 ] && return fi $SYSTEMCTL stop $nm $SYSTEMCTL disable $nm # Kill all dhclients, NM doesn't do it dhclient_pids=`/bin/pgrep $dhclient 2>/dev/null` for dhclient_pid in $dhclient_pids; do kill $dhclient_pid > /dev/null 2>&1 done /sbin/chkconfig network on /etc/init.d/network restart } disable_network_manager_sysv() { local nm="/etc/init.d/NetworkManager" local ret="" chkconfig --list NetworkManager | grep on ret="$?" if [ "$ret" == "0" ] ; then chkconfig NetworkManager off chkconfig network on fi $nm status | grep -q stopped ret="$?" if [ "$ret" != "0" ] ; then $nm stop /etc/init.d/network restart fi } is_device_up() { if [ -x /sbin/ip ]; then LC_ALL=C /sbin/ip -o link show dev $1 2>/dev/null | grep -wq "UP" else LC_ALL=C /sbin/ifconfig $1 2>/dev/null | grep -wq "RUNNING" fi [ $? -eq 0 ] && return 0 return 1 } generate_uuid() { local uuid if [ -x /bin/uuidgen -o -x /usr/bin/uuidgen ]; then uuid=`uuidgen 2>/dev/null` elif [ -f /proc/sys/kernel/random/uuid ]; then uuid=`cat /proc/sys/kernel/random/uuid` else uuid=`python -c 'import uuid; print uuid.uuid1()' 2>/dev/null` fi if [ "x$uuid" = "x" ]; then # Only bash... echo -n "$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))-" echo -n "$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))-$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))-" echo -n "$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))-$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))" echo "$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))$((RANDOM %10))" else echo $uuid fi } function get_suse_config_name() { # Parameters: <dev> <MAC_addr> # <dev> - name of device (example: eth1) # <MAC_addr> - MAC address of device # problem: network configs on suse 10(,9) and suse 11 contains the same information, # but have different config names # examples: # suse 10: ifcfg-eth-id-00:0c:29:90:c3:91 # suse 11: ifcfg-eth1 # opensuse 4x: ifcfg-eth1 local ETH_DEV=$1 local ETH_MAC=$2 IFCFG_DIR=/etc/sysconfig/network ETH_DEV_CFG=ifcfg-$ETH_DEV IFCFG=${IFCFG_DIR}/${ETH_DEV_CFG} [ -f $IFCFG ] && return 0 ETH_DEV_CFG=ifcfg-eth-id-$ETH_MAC IFCFG=${IFCFG_DIR}/${ETH_DEV_CFG} [ -f $IFCFG ] && return 0 # /etc/SuSE-release is deprecated and will be removed in the future if [ -f /etc/os-release ]; then RELEASE_FILE=/etc/os-release else RELEASE_FILE=/etc/SuSE-release fi #if config not found - check suse-release grep -qi "^[[:space:]]*VERSION.*10" $RELEASE_FILE [ $? -eq 0 ] && return 0 ETH_DEV_CFG=ifcfg-$ETH_DEV IFCFG=${IFCFG_DIR}/${ETH_DEV_CFG} } is_nm_present() { need_to_disable_network_manager || return 0 if [ -x '/bin/systemd' -o -x '/usr/lib/systemd/systemd' ] && [ -x '/usr/sbin/NetworkManager' ]; then return 1 fi return 0 } is_nm_active() { if [ -x $SYSTEMCTL ]; then service_command "NetworkManager" "is-active" else service_command "NetworkManager" "status" fi } nm_get_if_field() { local field=$2 local name="prl_nettool-nm-$1" out=`nmcli --field $field c show $name 2>/dev/null` [ $? -ne 0 ] && return 1 echo $out | sed s/$field:// | sed s/[[:space:]]//g } create_nm_if_config() { local path="$NWCONFDIR/60-prl_nettool_$1.conf" if [ -f "$path" ]; then return 0 fi cat > "$path" <<-EOF [main] no-auto-default+=$2 plugins-=ifcfg-rh EOF service_command NetworkManager restart NWMANAGER_FAILED=0 } nm_check_and_create() { local dev=$1 local mac=$2 local name="prl_nettool-nm-$dev" create_nm_if_config $dev $mac || return $? call_nmcli c show $name is_old=$? if [ $is_old -eq 0 ]; then old_mac=`nm_get_if_field $dev 802-3-ethernet.mac-address` || return $? if [ ${mac^^} != ${old_mac^^} ]; then call_nmcli c delete $name || return $? is_old=1 fi fi if [ $is_old -ne 0 ]; then call_nmcli c add type ethernet ifname $dev con-name $name mac $mac || return $? fi uuid=`nm_get_if_field $dev connection.uuid` || return $? # Set mac to dhcp-client-id for same dhcp identefication on interface different configs if [ $is_old -ne 0 ]; then call_nmcli c modify $uuid ipv4.dhcp-client-id "1:$mac" || return $? call_nmcli c modify $uuid ipv4.may-fail no || return $? fi echo $uuid } function nmcli_clean_ip_and_gw() { local uuid=$1 local ipv=$2 # clean IPvX addreses and gateway from connection call_nmcli c modify $uuid ipv${ipv}.gateway "" call_nmcli c modify $uuid ipv${ipv}.address "" } call_nm_script() { local from=$1 local nmscript=`echo $from | sed 's@\(.*/\)\(redhat\|debian\|suse\)@\1nm@'` if [ $nmscript = $from ]; then #scriptdir/set_dns.sh have no os prefix, handle it here nmscript=`echo $from | sed 's@\(.*/\)@\1nm-@'` fi is_nm_active if [ $? -eq 0 -a -f $nmscript ]; then $nmscript "${@:2}" return $? fi return 0 } call_nmcli() { out=`LC_ALL=C nmcli "$@" 2>&1` res=$? # NetworkManager is offline for first time if [ $res -eq 8 -a $NWMANAGER_FAILED -eq 0 ]; then # wait 30s for NetworkManager if nm-online -t 30 >/dev/null 2>&1; then out=`LC_ALL=C nmcli "$@" 2>&1` res=$? else out="$out (NetworkManager did not start in 30 seconds)" NWMANAGER_FAILED=1 fi fi [ $res -ne 0 ] && echo "[`date`]: ERROR at 'nmcli $*' called from ${BASH_SOURCE[1]}:${BASH_LINENO[1]} ${FUNCNAME[1]}(): $out" >> $NETTOOL_LOG return $res } restart_nm_wait() { killall -9 NetworkManager > /dev/null 2>&1 /usr/bin/nm-online -t 30 >/dev/null 2>&1 # For case if it was stopped $NWMANAGER restart > /dev/null 2>&1 } clean_nm_connections() { local dev=$1 local mac=$2 local macnw=$3 local nmdev="" local need_restart=0 if [ -d $NWCONFDIR ]; then echo " [main] no-auto-default+=$2 plugins-=ifupdown " > $NWCONFDIR/prl_nettool_$1.conf [ ! -f $NWCONFDIR/prl_nettool_$1.conf ] && need_restart=1 fi ls $NWSYSTEMCONNECTIONS/* >/dev/null 2>&1 if [ $? -eq 0 ]; then for i in $NWSYSTEMCONNECTIONS/*; do echo $i | grep "Wired connection" >/dev/null 2>&1 && rm -f "$i" && need_restart=1 && continue cat "$i" | grep -E "$mac|$macnw" >/dev/null 2>&1 [ $? -eq 0 ] && rm -f "$i" && continue type nmcli > /dev/null 2>&1 || continue for nmdev in `nmcli c show 2>/dev/null | grep "^$(basename '$i')" | awk -v device=0 '{if (device == 0) {device=index($0, "DEVICE"); next}; print substr($0, device)}'`; do [ "x$nmdev" = "x$dev" ] && rm -f "$i" && need_restart=1 && break done done fi [ $need_restart -eq 1 ] && restart_nm_wait } nm_connection_reload() { local dev=$1 type nmcli > /dev/null 2>&1 || return nmcli connection reload $1 > /dev/null 2>&1 } # "X.X.X.X/Z=X.X.X.Ym100" -> "X.X.X.X/Z X.X.X.Y 100" split_route() { local gw=$1 local metric=${gw##*m} [ "$metric" = "$gw" ] && metric= gw=${gw%m*} local hop=${gw##*=} [ "$hop" = "$gw" ] && hop= echo "${gw%=*} $hop $metric" } route_ip() { split_route $1 | awk -F '[ ]' '{print $1}' } route_gw() { split_route $1 | awk -F '[ ]' '{print $2}' } route_metric() { split_route $1 | awk -F '[ ]' '{print $3}' }