我的unix脚本有什么问题

时间:2014-02-10 04:39:56

标签: bash unix

#!/bin/bash

while echo -n "Player's name?"
    read name
    [ $name != 'ZZZ' ]
do
    searchresult=$(grep [$name] playername)
    if [ $searchresult = 0 ]
    then
        echo -n "if See target (T/t) or team name (M/m)?"
        while [ [ $target!="T" ] || [ $team!="M" ] ]

            read team
            read target

            do
                echo "Please enter only T or M."
            done
            if $target="T"
            then
                grep [ $name ] targetselected
            else
                grep [ $name ] teamselected
            fi

    else
        echo 'no such player'
    fi

done
echo You are now exited search

运行时错误说

  

第10行 - 如果[$ searchresult = 0];有这么多论点,

那是什么意思?我该如何解决?

5 个答案:

答案 0 :(得分:2)

引用变量名称:

"$searchresult"

此外,您在脚本中还有其他失败。

  • 如果您不需要,请从greps中删除括号
  • 中重写条件

答案 1 :(得分:1)

在脚本的if语句中使用-eq instead =或使用-z选项检查空字符串。

答案 2 :(得分:1)

如果您在正在使用'grep'的三个文件中包含数据样本,那将非常有帮助!

你误解了

variable=$(command)

操作。 '$()'操作将命令的标准输出分配给变量,而不是命令的退出代码。如果您想使用原始脚本,请使用退出代码,请尝试以下方法:

grep [$name] playername > /dev/null 2>&1
searchresult=$?

'test'中的'='运算符(也称为'[]')用于字符串。你真的想要使用'-eq'运算符,它用于整数。

没有数据,我无法弄清楚脚本的其余部分应该是什么样子。事实上,它对我来说真的很奇怪。

由于你正在使用bash,我可以提出改进输入检查的建议。

target=UnSeT
while [ $target = "UnSeT" ]
do
    read -p "if See target (T/t) or team name (M/m)?" target
    case "$target" in
        [Tt]) target="T";;
        [Mm]) target="M";;
        *) target="UnSeT"; echo "Please enter T or M.";;
    esac
done

答案 3 :(得分:0)

grep返回多个单词,因此shell将if语句解释为具有如此多的标记。如果您只想检查是否匹配,请执行以下操作:

if grep "$name" playername &> /dev/null; then
    # ....

答案 4 :(得分:0)

您的脚本有多处问题。最令人震惊的问题是你需要引用你的变量。

例如,如果$name包含带空格的值,则会得到奇怪的结果:

name='a value'
grep [$name] file

最终会在[a中对value](这不是一个有效的正则表达式)进行求值(几乎肯定不存在)。

引用修正,但在[...]中使用grep也很奇怪。例如,

name='abc'
grep "[$name]" file

会在file中找到任何位置包含a的行,或者b位于其中的任何位置,或c位于其中的任何位置。这很难成为你想要的。

如果您打算搜索文字字符串,

grep -F "$name" file

那样做。

这是尝试更惯用地重写脚本。

#!/bin/sh

while true; do
    read -p "Player's name? " name
    case $name in "ZZZ" | "") break ;; esac
    if grep -F -q "$name" playername; then
        # Not sure what the logic should be here?
        while true; do
            read -p "See target (T/t) or team name (M/m)? " choice
            case $choice in
                [Tt]) file=targetselected; break ;;
                [Mm]) file=teamselected; break ;;
            esac
            echo "Only enter T/t or M/m.  Try again."
        done
        grep -F "$name" "$file"
    else
        echo 'no such player'
    fi
done

此脚本中没有特定于Bash的内容,因此我将shebang行更改为/bin/sh

然而,逻辑似乎很尴尬。我想你的球员文件看起来像这样:

Maisy
Tallulah
Cyril
Eddie

和团队一样

Tallulah,Chickens,Astronauts
Maisy,Obnoxity,Fallacious
Cyril,Rodents
Eddie,Dirt,False,Breakfast of Champions

然后,如果你搜索“全部”,你会在第一个文件中找到“Tallulah”,但是从团队文件中打印出Maisy和Tallulah,因为它们都包含文本“all”在线上。最好直接搜索团队或目标文件,可能使用Awk而不是grep

awk -F, -v q="$1" '$1 ~ q' "$file"

如果没有输出,则播放器首先不存在。

随着您越来越熟悉Unix shell,您将需要避免强制交互式对话的工具。相反,您可能希望拥有一个这样的简单工具:

#!/bin/sh
file=players
while true; do
    case $1 in
        -[Tt]) shift; file=targetselected;;
        -[Mm]) shift; file=teamselected;;
        *) break;;
    esac
done
awk -F, -v q="$1" '$1 ~ q' "$file"

易于作为较大脚本中的组件使用,易于从命令历史记录中回忆,如果您真的需要,可以轻松添加一个但不是很多不同的GUI,并且(一旦您习惯了它)使用。