“bash:

“bash:

如果没有任何命令行参数,我希望此函数返回一个随机单词。

我正在修改 linuxconfig.org 的随机字生成器,使其即使在 #$ -ne 1 时也可以运行。

function random-word {
    if [ $# -eq 0 ] ;
    then 
        echo "I only take one argument, dummy"
        # previously was exit 0
    fi

    # Constants 
    X=0
    ALL_NON_RANDOM_WORDS=/usr/share/dict/words

    # total number of non-random words available 
    non_random_words=`cat $ALL_NON_RANDOM_WORDS | wc -l` 

    # while loop to generate random words  
    # number of random generated words depends on supplied argument 
    while [ $X -lt "$1" ] 
    do 
    random_number=`od -N3 -An -i /dev/urandom | 
    awk -v f=0 -v r="$non_random_words" '{printf "%i\n", f + r * $1 / 16777216}'` 
    sed `echo $random_number`"q;d" $ALL_NON_RANDOM_WORDS 
      let "X = X + 1" 
    done

该语句执行,但出现 bash 错误:

$ bob
I only take one argument, dummy
bash: [: : integer expression expected

如何修复此问题以便不会显示 bash 错误?

答案1

while [ $X -lt "$1" ]即使没有 1 美元也会被评估。

将其余代码移至 else 块中,这样就不会发生这种情况。

function random-word {
    # from linuxconfig.org 

    if [ $# -eq 0 ] 
    then 
        echo "I need an argument, dummy"
        # To be extra friendly, give them a random word.
        echo "Here's a random word:"
        random-word 1
    else
        # Constants 
        X=0

         ...

        sed `echo $random_number`"q;d" $ALL_NON_RANDOM_WORDS 
          let "X = X + 1" 
        done
    fi
}

答案2

你不需要else块。如果您收到多个参数,您也不必失败。你只需要失败,如果你得到一场争论,然后你可以忽略其他一切,或者如果你至少没有得到一个争论就退出。

set -- "${1?ERR: Where\'s my argument?!?!}"

该声明做到了这一切。这样做的效果相同,但如果第一个参数仅为 nullstring 也会失败''

set -- "${1:?ERR: Where\'s my argument?!?!}"

当然,如果重点是从交互式 shell 调用 shell 函数,这也可能会杀死交互式 shell,因此您可以这样做:

(: "${1:?Where\'s my argument?}") || return && set -- "$1"

...这也能处理这个问题。但是,在我看来,除非绝对必要,否则 shell 函数永远不应该影响交互式 shell - 例如,如果它需要更改当前的 shell 变量或其他内容。因此,比上面的更好的方法是将函数声明为子 shell,例如:

fn() (set -- "${1:?Where\'s my argument?}" && echo "$1")

...做。

另一种方法是接受所有参数并将它们连接起来 - 因此所有参数在每种情况下都只被视为一个。你可以这样做:

fn() (                              
    : "${1:?ERR: Where\'s my argument?}"
    set -- "$*" && echo "$1" 
)
fn '' ; fn here are a lot of arguments that will all be treated as one
###OUTPUT###
sh: line 2: 1: ERR: Where's my argument?
here are a lot of arguments that will all be treated as one

我个人不太喜欢sh: line 2: 1:通常发生的情况——至少在交互式 shell 中是这样。我通常会CTRL+V CTRL+M在前面加上一个ERR:,这样它就会返回到终端中的行首并覆盖该位,但仍然将更有用的信息输出到日志中。喜欢:

fn() (                              
    : "${1:?^MERR: Where\'s my argument?}"
    set -- "$*" && echo "$1" 
)
fn ; fn 2>&1 | cat -A
###OUTPUT###
ERR: Where's my argument?
sh: line 2: 1: ^MERR: Where's my argument?$

相关内容