【问题标题】:Variable Syntax Error with Bash Script (Homework)Bash 脚本的变量语法错误(作业)
【发布时间】:2014-05-05 16:41:00
【问题描述】:

我目前正在为 Unix 课程做家庭作业,我已经完成了其他所有工作,但我就是不知道我做错了什么。我已经在 csh 中完成了完全相同的脚本(但我们也需要在 bash 中完成。)我已经修复了一些错误,但现在当我尝试运行它时,我得到的是“变量语法” .

我曾尝试使用双括号 for while 和 ifs 在尝试读取输入之前,我也尝试过声明输入的变量 我也试过窃听我班上的几个人,但他们中的大多数人都很笨,只是抄袭其他人。

#/!bin/bash
#
#Menunix - Bash
#
#Usage: menunixb
input = "$(1)" 
while [ $input != 5 ]
do
    echo Please choose an option
    echo 1: List Files 
    echo 2: Display today's date and time
    echo 3: Check whether a file is a directory or not
    echo 4: Create a file backup
    echo 5: Quit
    read input
    case $input in
        1) 
            ls
            ;;
        2)
            echo -n Time:
            date +"%T"
            echo Date:
            date +"%D"
            ;;
        3)
            echo What file do you wish to check
            read finput
            if [ -d $finput ] ; then
                echo $finput is a Directory
            elif [ -f $finput ] ; then
            echo $finput is a File
            else
                echo $finput does not exist
                ;;
            4)
                echo Please enter filename to backup
                read binput
                cp $binput{,.bak}
                ;;
            5)
                exit 1
            *)
                echo Please choose a valid input
                exit 1
            esac
        done
#EOF

【问题讨论】:

  • 查看代码的语法高亮。提示:引号
  • 考虑使用缩进。这使代码更具可读性,因此更易于调试。

标签: bash


【解决方案1】:

错误实际上在解释器行:

#/!bin/bash

不一样

#!/bin/bash

一旦我真正让脚本在 bash 中运行,它只是一些小的语法错误,我就完成了。

【讨论】:

  • :) 请注意,为了更便携并尊重用户对 bash 解释器的选择,有些人更喜欢 #!/usr/bin/env bash - 请参阅 stackoverflow.com/a/16365367/45375 了解优缺点。
【解决方案2】:

更新:正如 OP 所发现的,另一个问题是格式错误的 shebang 行:#/!bin/bash 而不是 #!/bin/bash(但请考虑使用 #!/usr/bin/env bash)。

提前提示:http://shellcheck.net 是一个非常方便的工具,用于检查 shell 代码中的错误。


@Ube 和@kojiro 的回答都包含重要的提示:

  • ' 用于引用,因此必须在引号内使用,或者必须转义为\'

  • bash 的变量赋值中,= 周围不允许有空格。

但还有更多:

  • 使用$1 引用第一个参数; $(1) 做了一些根本不同的事情:它使用命令替换 ($(...)) 来执行封闭的命令并返回其标准输出;因此,$(1) 尝试执行一个 - 很可能不存在 - 命令 1 并返回其输出。

  • 在 bash 中始终使用 [[ ... ]] 而不是 [ ...];它更健壮并提供更多功能;举个例子:如果$input 未定义或为空,[ $input != 5 ]中断 - 你必须用双引号来防止这种情况;相比之下,用[[ $input != 5 ]]就好了。

  • 所有case 分支必须以;; 终止(即使是只包含exit 命令的分支;)。小字:最后一个分支也是在没有;;

  • 的情况下工作
  • if [ -d $finput ] ; then ... 语句缺少结束 fi

【讨论】:

    【解决方案3】:

    我为您缩进了代码。你有几个问题:

    • 始终在 echo 语句周围使用引号。您不能使用 today's 之类的词,否则您将开始引用文件末尾的所有内容。
    • 使用缩进。我缩进了你的代码,因为它出现在我的编辑器上。注意到什么了吗?您缺少一个 fi 来结束 if 语句。

    您使用的是什么类型的系统?您应该始终使用真实的现场节目编辑器。我对在我的工作中使用记事本的开发人员进行打击。

    • 您始终可以在任何平台上使用VIM。它在 Linux 和 Mac 上提供,可在 Windows 上下载。是否自动缩进和语法突出显示,这会捕获您不完整的 if 语句和您的 today's 错误。
    • VIM 可能有点令人生畏。它很强大,但很难学习。 Notepad++ 是一个易于使用的程序编辑器,具有语法高亮和自动缩进功能。
    • 在 Mac 上,试试TextWrangler,它是免费的,包括语法高亮和自动缩进。您还可以使用随 Mac OS X 免费提供的 Xcode。
    • 在 Linux 上,您只能靠自己。大多数 Linux 用户使用 VIM、EMAC 或 Eclipse。 Kate 很受欢迎,但它是一个 KDE 应用程序。我见过一些人使用 BlueFish。大多数都是免费的、易于安装且是开源的。
    • 不是这样的秘密把戏。将set -xv 放入您的代码中。一旦 shell 插入该行,它将打印出正在执行的行和结果。您甚至可以将PS4 提示设置为\$LINENO:,这也会打印出您的shell 脚本的行号。这是一个很好的调试帮助。要关闭详细调试,请使用set +xv

    【讨论】:

      【解决方案4】:

      看看:

      input = "$(1)"
      

      您注意到等号 (=) 周围的空格了吗?这个is not allowed 在 bash 中。必须是

      input="$(1)"
      

      改为。

      【讨论】:

        【解决方案5】:

        您必须修正 echo 语句周围的引号。

        echo 2: Display today's date and time
        

        特别错误,因为它打开了一个引用,但从不关闭它。尝试引用所有这些回声线:

        echo "2: Display today's date and time"
        

        剧透:我很无聊,refactored this。随意使用它来研究在 shell 中做事的不同方式。它可能涉及您在课堂上没有介绍过的功能,但无论如何您可能会发现它很有帮助。

        【讨论】:

          猜你喜欢
          • 2019-02-17
          • 2011-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-24
          • 1970-01-01
          • 1970-01-01
          • 2010-11-05
          相关资源
          最近更新 更多