我怎样才能在bash中修复我的功能

时间:2014-11-21 22:19:32

标签: bash

我是新来的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

1 个答案:

答案 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