printf在bash中发布

时间:2014-10-18 08:48:23

标签: bash printf

好的,这是代码

printf "%0.s1" $(seq $1)

很简单,它位于一个函数中,你传入一个长度,它给你一堆1。此函数然后填充0以创建32位的字符串,另一个函数更改为整数或IP。例如:

cdr2mask() {
    local BIMASK=$(printf "%-32s" $(printf "%0.s1" $(seq $1)) | tr ' ' '0')
    integerToIP $(convertbaseNumFromTo $BIMASK 2 10)
}

直接调用此函数时工作正常(参数是网络掩码中的位数,例如:24)。但是,当从以下调用时,它会失败。它给出1然后是31 0而不是正确的掩码。它正确获得1美元。我把它缩小到printf语句(顶部的那个),只有当这样调用时才返回一个1。调用cdr2mask的函数是:

ipInNetwork() {
    local IFS HOST NETWORK NETMASK CIDR
    read HOST NETWORK NETMASK <<<$*
    if [ -z "$NETMASK" ]; then
        IFS='/'
        read NETWORK CIDR <<<"$NETWORK"
        if [ -z "$CIDR" ]; then
            NETMASK="255.255.255.255"
        else
            NETMASK=$( cdr2mask "$CIDR" )
        fi
    fi
    if [ $(( $( ipToInteger $HOST ) & $( ipToInteger $NETMASK ) )) = \
    $(( $( ipToInteger $NETWORK ) & $( ipToInteger $NETMASK ) )) ]; then
        return 0;
    else
        return 1;
    fi
}

以下版本的cdr2mask工作正常,因此它不是调用者:

newcdr2mask() {
    local ONES="11111111111111111111111111111111"
    local BINUM=$(printf "%-32s" ${ONES:0:$1} | tr ' ' 0)
    integerToIP $( convertbaseNumFromTo $BINUM 2 10 )
}

oldcdr2mask () 
{
   # Number of args to shift, 255..255, first non-255 byte, zeroes
   set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
   [ $1 -gt 1 ] && shift $1 || shift
   echo ${1-0}.${2-0}.${3-0}.${4-0}
}

最后一个我没写的。当然,欢迎提出有关速度改进的建议和其他建议。我没有达到我真正想要的速度,但我只是开始优化。 “旧”方法可能仍然是最快的,但我想让其他版本工作,所以我可以测试它。这可能是一个重击错误吗?

1 个答案:

答案 0 :(得分:1)

罪魁祸首:

IFS='/'

这会将seq扩展 - seq输出换行符作为分隔符(默认情况下),并且当IFS/时,shell不对其进行分词。 (local IFS在这里没有帮助,局部变量在被调用的函数中可见。)

我不会完全设置IFS,通过做这样的事情而不是read

CIDR=${NETWORK##*/}
NETWORK=${NETWORK%/*}

(使用case语句处理包含NETWORK的{​​{1}}的案例。)