BASH脚本:接受多个标志

时间:2014-01-11 00:45:53

标签: linux bash scripting

我有这个问题,我正在做一个菜单式的程序,用户应根据想要做的操作输入不同的数字。 现在我需要在命令中放入多个标志,但我似乎无法让它工作。 Catch:我不能直接在一个变量中输入标志,我可能必须让这个案例列表能够随意退出)

function fileCpy {
   printf "Choices:\n1. Interactive copy, answer yes/no before doing the copy: \n2. Make backups of existing destination files\n3. Preserve file attributes\n4. Do a recursive copy\n0. Return to main menu\n"
        #read choices
    read $a
    read $b
    read $c
    for choices in $choice ; do
      case "$choices" in
          1)
        a=-i ;;
          2)
        b=--backup ;;
          3)
        c=-p ;;
          #4)
        #4= -R -v;;
          0)
         main;;
    esac
    echo "$a"
    echo "$b"
    echo "$c"
    printf "\nType the name of the file you wish to copy/backup: "
    read $fl1
    printf "\nType the destination file: "
    read $des1
    cp $a $b $c $fl1 $des1
  done
}

2 个答案:

答案 0 :(得分:1)

一个问题是read $a等错误:如果您需要阅读,则应编写read a。就目前而言,读取的值存储在变量中,其名称存储在$a

另一个问题是,对于无辜的用户来说,他们应该在脚本继续之前输入3行信息,但是三条read行迫使这些信息强制显示。

另一个问题是您没有阅读$choice(通过read choice),因此for循环无关。

另一个问题是您的脚本将继承任何环境变量的值,这些变量恰好与您正在使用的变量的名称相同。

另一个问题是您没有引用文件名。除非你的名字包含空格或其他类似的尴尬字符,否则它们无关紧要。

化妆品问题是printf声明非常长。每行使用一个printf。或者使用echo。滚动页面的RHS的东西很糟糕(虽然我不认为80个字符是行的固定长度,但是对于长度超过80的行有一个二次惩罚 - 如(长度-80) 2 < / sup>增加,较长线的疼痛增加。

在另一个层面上,界面显得格外怪诞。作为shell脚本的练习,它是有道理的。作为如何设计好的shell脚本的练习,这是一个非常糟糕的设计。

可能有意义的设计是:

  1. 将变量设置为空:a=""; b=""; c="";等。
  2. 提供类似于现在给出的一系列选择,但添加一个选项来执行命令,另一个选择放弃发货。
  3. 有一个读取选项的循环,并设置标记。
  4. 当用户选择执行时,退出循环并提示输入文件名。
  5. 如果一切顺利,请执行命令。
  6. 请注意,您应该检查read命令是否有效;如果他们不这样做,则不安全(不要损坏任何东西)。


    将所有这些放在一起(略有不同,但总体效果相同 - 见证了local对变量的使用):

    fileCpy()
    {
        local a b c file dest
        echo "Choices:"
        echo "0. Return to main menu"
        echo "1. Interactive copy, answer yes/no before doing the copy"
        echo "2. Make backups of existing destination files"
        echo "3. Preserve file attributes"
        echo "4. Do a recursive copy"
        echo "5. Execute the copy"
        while printf "Your choice: " && read choice
        do
            [ -z "$choice" ] && return 1 # Empty input - failure
            case "$choice" in
            (0) return 0;;
            (1) a="-i";;
            (2) b="--backup";;
            (3) c="-p";;
            (4) d="-R";;
            (5) break;;
            (*) echo "Unrecognized response ($choice); please enter 0..5";;
            esac
        done
        [ "$choice" != 5 ] && return 1 # EOF - failure
        printf "Type the name of the file you wish to copy/backup: "
        read file
        [ -z "$file" ] && return 1 # Empty file name - failure
        printf "Type the name of the destination file/directory:   "
        read dest
        [ -z "$dest" ] && return 1 # Empty file name - failure
        cp $a $b $c "$file" "$dest"
    }
    

    测试代码:

    echo "a=$a b=$b c=$c file=$file dest=$dest"
    if fileCpy
    then : OK
    else echo "Failed"
    fi
    echo "a=$a b=$b c=$c file=$file dest=$dest"
    

    最后一个块是一个简单的测试工具。它报告函数内部使用的变量的值,运行函数,报告函数是否失败,并重新回显变量以证明它们尚未设置。

    除非你付钱让我这样做,否则我不会使用该界面,但它或多或少都符合训练目标。

答案 1 :(得分:0)

如果你想做菜单,你可以使用select构造(或case/esac)。有关信息,请参阅here