我是新来的bash脚本有耐心。
我有这个代码,它扫描域的端口,并将其显示给用户,它自己完美地工作,但当我添加功能给它时,给我错误。我在这里做错了什么?
check_parms () {
case $# in
1) ports='1-1023'
host=$1 ;;
2) ports=$1
host=$2 ;;
*) echo 'Usage: portscan [port|range] host'
exit 1 ;;
esac
}
# check port range
check_ports () {
if [ "$(echo $ports | grep '^[1-9][0-9]*-[1-9][0-9]*$')" != "" ]; then
firstport=$(echo $ports | cut -d- -f1)
lastport=$(echo $ports | cut -d- -f2)
elif [ "$(echo $ports | grep '^[1-9][0-9]*$')" != "" ]; then
firstport=$ports
lastport=$ports
else
echo "$ports is an invalid port(s) value"
exit 2
fi
}
# check firstport > lastport
check_order () {
if [ $firstport -gt $lastport ]; then
echo $firstport is larger than $lastport
exit 3
fi
}
# check host value
check_host () {
regex='^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$'
if [ "$(echo $host | grep '[A-Za-z]')" != "" ]; then
response=$(host $host)
if [[ "$response" =~ "timed out" || "$response" =~ "not found" ]]; then
echo host $host not found
exit 4
fi
elif [[ ! $host =~ $regex ]]; then
echo $host is an invalid host address
exit 5
fi
}
# check if host is reachable using ping
check_ping () {
if [[ "$(ping -c 1 -W 2 -n $host)" =~ "0 received" ]]; then
echo $host is unreachable
exit 6
fi
}
# start the scan
do_scan () {
echo -n "Scanning "
for p in $(seq $firstport $lastport)
do
echo -n .
x=$((echo >/dev/tcp/$host/$p) >/dev/null 2>&1 && echo "$p open")
if [ "$x" != "" ]; then
y="${y}
$x"
fi
done
}
# show results of scan
show_results () {
echo -e "\n$y\n"
exit 0
}
check_parms $#
check_ports $ports
check_order $firstport $lastport
check_host $host
check_ping $host
do_scan $host $firstport $lastport
show_results
答案 0 :(得分:2)
你传递和使用函数参数的方式没有意义。我认为那个公然错误的是第一个:
check_parms () {
case $# in
1) ports='1-1023'
host=$1 ;;
2) ports=$1
host=$2 ;;
*) echo 'Usage: portscan [port|range] host'
exit 1 ;;
esac
}
#... then in the main program:
check_parms $#
要理解这个问题,假设主脚本使用两个参数运行:" 5-50"和" 10.10.10.10"。行check_parms $#
运行check_params并将参数数量(2)作为参数传递给它。好到目前为止。然后在check_params中,它运行case $# in
,但此时我们在check_params中,所以$#
指的是传递给check_params 的参数数量,而不是数字传递给主脚本。 check_params只传递了一个参数(数字2),因此$#
为1,它执行1)
情况,将端口设置为" 1-1023"并接待" 2"。这根本不是你想要的。
如果您希望check_params能够看到传递给主脚本的相同参数,则必须使用check_params "$@"
将相同的参数传递给它。
传递给其他函数的论据似乎没有被使用;这不一定会造成麻烦,但它会导致令人困惑的代码(以及令人困惑的代码会导致错误)。考虑一下例如check_order函数。您将$firstport
和$lastport
作为参数传递(意味着在check_order中,$1
设置为$firstport
的值,$2
设置为值{ $lastport
),但是你不会在check_order中使用这些参数;相反,您直接使用$firstport
和$lastport
,忽略参数。由于它们是相同的,它并不重要,但如果有人后来尝试将其用于其他内容(check_order $currentport 1023
),则会检查$firstport
和{{1}而不是它应该检查的样子。
解决方案:更改函数以使用其参数,而不是直接访问全局变量。 (或者明确地使用全局变量并停止假装将它们作为参数传递;但是全局变量通常很糟糕,所以这是更糟糕的选择。)像这样:
$lastport