为什么这个示例脚本会在令牌附近输出错误?

时间:2013-08-05 05:43:44

标签: linux shell

在这里输入图像描述我试图看看shell脚本是如何工作的,以及如何运行它们,所以我从一本名为“Wicked Cool Shell Scripts”库的书中提取了一些示例代码

我逐字写了代码,但是我从Linux得到了一个错误,我在编译代码时说:

  

'd.sh:第3行:意外标记`{

附近的语法错误      

'd.sh:第3行:`gmk(){

在此之前,我在换行符上有大括号,但我仍然得到:

  

'd.sh:第3行:意外令牌附近的语法错误

     

'd.sh:第3行:`gmk()

#!/bin/sh
#format directory- outputs a formatted directory listing 
gmk()
 {
#Give input in Kb, output converted to Kb, Mb, or Gb for best output format
    if [$1 -ge 1000000]; then
        echo "$(scriptbc -p 2 $1/1000000)Gb"
    elif [$1 - ge 1000]; then
        echo "$$(scriptbc -p 2 $1/1000)Mb"
    else
        echo "${1}Kb"
        fi
}

    if [$# -gt 1] ; then 
        echo "Usage: $0 [dirname]" >&2; exit 1
    elif [$# -eq 1] ; then 
        cd "$@"
        fi

    for file in *

    do 
        if [-d "$file"] ; then
            size = $(ls "$file"|wc -l|sed 's/[^[:digit:]]//g')
        elif [$size -eq 1] ; then
            echo "$file ($size entry)|"
        else
            echo "$file ($size entries)|"
    fi
        else
            size ="$(ls -sk "$file" | awk '{print $1}')"
            echo "$file ($(gmk $size))|"
    fi
    done | \
      sed 's/ /^^^/g' |\
      xargs -n 2 |\
      sed 's/\^\^\^/ /g' | \
      awk -F\| '{ printf "%39s %-39s\n", $1, $2}'
      exit 0

    if [$#-gt 1]; then 
        echo "Usage :$0 [dirname]" >&2; exit 1
    elif [$# -eq 1]; then 
        cd "$@"
    fi

    for file in *
        do
            if [ -d "$file" ] ; then
                size =$(ls "$file" | wc -l | sed 's/[^[:digit:]]//g')
            if [ $size -eq 1 ] ; then
                echo "$file ($size entry)|"
            else
                echo "$file ($size entries)|"
                fi
            else
                size ="$(ls -sk "$file" | awk '{print $1}')"
                echo "$file ($(convert $size))|"
                fi
done | \
    sed 's/ /^^^/g' | \
    xargs -n 2 | \
    sed 's/\^\^\^/ /g' | \
    awk -F\| '{ printf "%-39s %-39s\n", $1, $2 }'

    exit 0

the code as it appears in the book

2 个答案:

答案 0 :(得分:0)

sh 非常对空格敏感。特别是赋值(=周围没有空格)和测试([ ]中必须有空格)。

此版本运行,但由于缺少scriptbc而在我的机器上运行失败。

您将elsif放在应该是if的位置。

小心开始和结束之间的列对齐。如果你不匹配它们很容易让你误入歧途思考这是如何工作的。

此外,在脚本顶部附近添加set -x非常调试它正在做什么的好方法 - 它将导致解释器输出它所在的每一行在它之前运行。

#!/bin/sh
#format directory- outputs a formatted directory listing
gmk()
{
#Give input in Kb, output converted to Kb, Mb, or Gb for best output format
    if [ $1 -ge 1000000 ]; then
        echo "$(scriptbc -p 2 $1/1000000)Gb"
    elif [ $1 -ge 1000 ]; then
        echo "$(scriptbc -p 2 $1/1000)Mb"
    else
        echo "${1}Kb"
    fi
}

if [ $# -gt 1 ] ; then
    echo "Usage: $0 [dirname]" >&2; exit 1
elif [ $# -eq 1 ] ; then
    cd "$@"
fi

for file in *
do
    if [ -d "$file" ] ; then
        size=$(ls "$file"|wc -l|sed 's/[^[:digit:]]//g')
        if [ $size -eq 1 ] ; then
            echo "$file ($size entry)|"
        else
            echo "$file ($size entries)|"
        fi
    else
        size="$(ls -sk "$file" | awk '{print $1}')"
        echo "$file ($(gmk $size))|"
    fi
done | \
  sed 's/ /^^^/g' |\
  xargs -n 2 |\
  sed 's/\^\^\^/ /g' | \
  awk -F\| '{ printf "%39s %-39s\n", $1, $2}'
  exit 0

答案 1 :(得分:0)

顺便说一句,关于这本书告诉你修改你的PATH变量,这真的是一个坏主意,取决于它建议你做什么。为了清楚起见,永远不要将当前目录添加到PATH变量,除非您打算将该目录设置为所有脚本的永久位置等。如果要将其设置为脚本的永久位置,请确保将位置添加到PATH变量的END,而不是开头,否则您将产生一个主要的安全问题。

Linux和Unix不会将您当前的位置(通常称为您的PWD或目前的工作目录)添加到路径中,因为有人可能会创建一个名为'ls'的脚本,例如,它可以运行恶意而不是实际的' ls'命令。在PWD中执行某些操作的正确方法是在前面添加“./”(例如./my_new_script.sh)。这基本上表明你真的想从你的PWD运行一些东西。可以把它想象成“就在这里”。 '。'实际上代表你当前的目录,换句话说就是“这里”。