今天升级syndns.sh
脚本,升级为默认DNS
服务器为多个,当一个DNS
服务器探测失败后使用下一个DNS
服务器继续探测,从而大大提高了脚本的探测能力。在升级过程中,需要用到将默认DNS
服务器数组作为参数传递到函数的问题,于是有了本文。
遍历所有参数: $@
1 2 3 4
| #!/bin/bash for para in "$@" ; do echo $para done
|
在上述例子中,使用for
循环和$@
遍历传递给脚本的所有参数,并逐个输出这些参数。其优点在于简洁,但也存在缺点,即无法指定输出哪一个参数。所以,对于不需要识别参数具体位置的情况,使用变量$@
来遍历参数是个不错的方案。
参数的数量:$#
变量$#
返回参数的数量,使用它配合$@
可以指定输出确定位置的参数。例如
1 2 3 4 5 6
| test(){ local paras=("$@") for ((k = 0; k < $#; k++)); do echo ${paras[$k]} done }
|
展开数组:${arr[@]}
或
${arr[*]}
在for
的展开位置,可以使用上述两条命令,来逐一调用数组变量。例如
1 2 3
| for ipc in ${SYN_IP[*]}; do echo "$ipc" done
|
数组作为参数传递给函数
需要注意的是,在将数组作为参数传递给函数时,参数形式只能使用"${Arr[*]}"
才行。例如
1
| SYN_DN2IP "${SYN_GITHUB[*]}" "$SYN_REC"
|
syndns.sh
V2.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| #! /bin/sh
SYNDNS_DEPEND(){ for VAR in $1 ;do pacman -Qq $VAR &> /dev/null if [[ $? != 0 ]]; then sudo pacman -S $VAR fi done }
SYN_EXE="/usr/local/bin/${0%.sh}" SYN_AUTO="$HOME/.config/autostart/${0%.sh}.desktop" SYN_SUDO="/etc/sudoers.d/01_$USER" SYN_HOS="/etc/hosts" SYN_REC=$(grep "addn-hosts" /etc/dnsmasq.conf |grep "/dev/shm/") SYN_REC=${SYN_REC#*=} SYN_ADD="$HOME/.host_dns_autoadd.txt" SYN_DNSIP=(8.8.8.8 119.29.29.29)
SYN_GITHUB=(github.githubassets.com central.github.com desktop.githubusercontent.com \ assets-cdn.github.com camo.githubusercontent.com github.map.fastly.net github.global.ssl.fastly.net \ gist.github.com github.io github.com api.github.com raw.githubusercontent.com user-images.githubusercontent.com \ favicons.githubusercontent.com avatars5.githubusercontent.com avatars4.githubusercontent.com \ avatars3.githubusercontent.com avatars2.githubusercontent.com avatars1.githubusercontent.com \ avatars0.githubusercontent.com avatars.githubusercontent.com codeload.github.com \ github-cloud.s3.amazonaws.com github-com.s3.amazonaws.com \ github-production-release-asset-2e65be.s3.amazonaws.com \ github-production-user-asset-6210df.s3.amazonaws.com \ github-production-repository-file-5c1aeb.s3.amazonaws.com githubstatus.com github.community \ media.githubusercontent.com objects.githubusercontent.com raw.github.com copilot-proxy.githubusercontent.com)
SYN_DN2IP(){ for hubweb in $1; do unset SYN_IP for ((k = 0; k < ${#SYN_DNSIP[@]}; k++)); do SYN_IP="$(dig @${SYN_DNSIP[$k]} +short $hubweb)" if [[ ! "$SYN_IP" =~ "#" ]]; then k=${#SYN_DNSIP[@]} fi done if [[ ! "$SYN_IP" =~ "#" ]]; then for ipc in ${SYN_IP[*]}; do echo "$ipc $hubweb" >> $2 done fi done }
SYNDNS_PROCESS(){ cat $SYN_HOS |grep -v '^$'|grep -v '^#'|sort |uniq |sed -r 's/ * / /g' > $SYN_REC SYN_DN2IP "${SYN_GITHUB[*]}" "$SYN_REC" if [ -e $SYN_ADD ]; then cat $SYN_ADD |grep '^[0-9]' |grep -v '^$'|grep -v '^#'|sort |uniq |sed -r 's/ * / /g' >> $SYN_REC fi cat $SYN_REC |grep '^[0-9]' |grep -v '^$'|grep -v '^#'|sort |uniq |sed -r 's/ * / /g' > $SYN_REC echo "$(hostname -i) localhost:" >> $SYN_REC systemctl is-active --quiet dnsmasq if [[ $? == 0 ]]; then sudo systemctl restart dnsmasq.service else sudo systemctl start dnsmasq.service fi }
if [ $# -gt 0 ]; then if [ $1 == "-i" -o $1 == "-I" ]; then SYNDNS_DEPEND "dnsutils inetutils dnsmasq jq" sudo cp -f $0 $SYN_EXE sudo chmod +x $SYN_EXE if [ ! -e $SYN_AUTO ]; then sudo touch $SYN_AUTO cat > $SYN_AUTO <<EOF [Desktop Entry] Name=SynDns TryExec=syndns Exec=$SYN_EXE Type=Application Categories=GNOME;GTK;System;Utility;TerminalEmulator; StartupNotify=true X-Desktop-File-Install-Version=0.22 X-GNOME-Autostart-enabled=true Hidden=false NoDisplay=false EOF sudo sh -c "cat > /etc/dnsmasq.conf" <<EOA domain-needed bogus-priv resolv-file=/etc/resolv.conf no-poll interface=lo listen-address=127.0.0.1 bind-interfaces no-hosts addn-hosts=/dev/shm/dnsrecord.txt cache-size=9999 port=53 EOA fi if [ ! -e $SYN_SUDO ]; then sudo touch $SYN_SUDO sudo sh -c "cat > $SYN_SUDO" <<EOB $USER ALL=(ALL) NOPASSWD: /bin/systemctl restart dnsmasq.service, /bin/systemctl start dnsmasq.service EOB fi elif [[ $1 =~ ".json" || $1 =~ ".dom" ]]; then if [[ $1 =~ ".json" ]]; then Address=($(cat $1|jq -r '.children[]' |grep "\"uri\":")) Address=(${Address[*]#*//}) Address=(${Address[*]/\"uri\":}) Address=(${Address[*]%%/*}) Address=(${Address[*]%%\"*}) Address=(${Address[*]%%*[0-9]}) Address=(`echo ${Address[@]}|sed -e 's/ /\n/g'|sort |uniq`) elif [[ $1 =~ ".dom" ]]; then Address=($(cat $1)) fi if [ ! -e $SYN_ADD ]; then touch $SYN_ADD fi SYN_DN2IP "${Address[*]}" "$SYN_ADD" cat $SYN_ADD |grep '^[0-9]' |grep -v '^$'|grep -v '^#'|sort |uniq -u |sed -r 's/ * / /g' > $SYN_ADD SYNDNS_PROCESS fi fi
SYNDNS_PROCESS
|
参考文章