为什么这个带有'while [expr]`的bash脚本不会运行?

时间:2013-03-05 22:33:06

标签: bash fibonacci

当我尝试运行脚本时,我收到“第9行:[2:命令未找到”错误。这是我的第一个bash脚本,所以我是一个完全的初学者。

#!/bin/bash

num1=0
num2=1

count=2


while [$count -le $1]
do
num3='expr $num1+$num2'
num1=$num2
num2=$num3
count='expr $count+1'

done

echo "Fib Num: $num3"

3 个答案:

答案 0 :(得分:6)

[]周围添加空格。 [是一个命令,所以它必须是一个单独的单词。来自man bash

test expr
[ expr ]
       Return a status of 0 or 1 depending on  the  evaluation  of  the
       conditional  expression expr.  Each operator and operand must be
       a separate argument.  Expressions are composed of the  primaries
       described  above  under  CONDITIONAL EXPRESSIONS.

答案 1 :(得分:3)

试试这个:

$ cat t.sh

节目:

#!/bin/bash

num1=0
num2=1

count=2

while [ $count -le $1 ]; do
  num3=$(expr $num1 + $num2)
  num1=$num2
  num2=$num3
  let count++;
done

echo "Fib Num: $num3"

结果:

$ bash t.sh 9
Fib Num: 34

[]需要空格,而expr命令应该包含在$()中,而不是单引号。你可能打算使用反引号(`),但不要再使用反引号了。

由于你正在使用bash,你也可以简化增加计数,如图所示。

答案 2 :(得分:1)

作为参考,这里有类似于“通常”的理想答案。

#!/usr/bin/env bash

# Bash/ksh93
# Theoretically also zsh/mksh, but both have bugs that break it.
function fib1 {
    # It is critical to validate user input if it will be used in an arithmetic
    # expression.
    [[ $1 == +([[:digit:]]) ]] || return 1

    # Demonstrates an accumulating version to print the intermediary results.
    typeset i=1 f=(0 1)
    while (( i < $1 )); do
        # Don't use expr(1) unless you're coding for Bourne.
        (( f[i] = f[i-1] + f[i++] ))
    done
    echo "${f[@]}"
}

fib1 "$1"

令人困惑的是,除了语法错误之外,即使使用expr shebang,您也会使用奇怪的/bin/bash。您应该阅读bash手册,而不是阅读建议的内容。

#!/bin/sh

# POSIX (posh/bash/zsh/all kshes)
# It's easier to write a let wrapper than re-type test expressions repeatedly.
# This emulates let precisely, but it's not important to understand everything
# going on here. Breaks in dash because of its lack of support for the
# otherwise ubiquitously supported comma operator, and busybox because of a bug in
# its environment assignments.
let() {
    IFS=, command eval test '$(($*))' -ne 0
}

fib2() {
    # Uglier validation for POSIX
    case $1 in
        *[^[:digit:]]*|'')
            return 1
    esac

    # Using globals for simplicity
    count=$1 n1=0 n2=1
    while let count-=1; do
        let n1=n2 n2=${n1}+n2
    done

    printf 'Fib Num: %d\n' "$n2"
}

fib2 "$1"

我的算术斐波那契在某种程度上是一种好奇心。

# Bash/ksh93/zsh
# Could be more elegant but includes bug workarounds for ksh/zsh
 $ a=a[++n%20]=a[n]+a[n-1],a[0] a[n=2]=1; let a a=0; echo "${a[@]}"
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584

# Less portable because of bugs. Works in Bash.
 $ a=('a[a[n]=a[n-1]+a[n-2],n++/20]' 2 0 1); echo "${a[@]:n=4,a}"
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584