Unix bash 错误 - 需要二元运算符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40939134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:29:49  来源:igfitidea点击:

Unix bash error - binary operator expected

bashshellunixcommand

提问by pogba123

So below is the code i have in my bash script. I'm getting an error saying binary operator expected when i give the command 2 arguments (doesnt give error when i give 1 argument). It does change the file permissions when i give 2 arguments because i can see it when i do ls -l but it still gives me this error. How do i fix it?

所以下面是我在我的 bash 脚本中的代码。当我给命令 2 个参数时,我收到一个错误,提示二元运算符预期(当我给 1 个参数时不会给出错误)。当我提供 2 个参数时,它确实会更改文件权限,因为当我执行 ls -l 时我可以看到它,但它仍然给我这个错误。我如何解决它?

for file in $@
do
    chmod 755 $file
done

if [ -z $@ ]
then
        echo "Error. No argument."
        exit $ERROR_CODE_1
fi

i have added this now

我现在已经添加了这个

if [ ! -f "$*" ]
then
       echo "Error. File does not exist"
       exit $ERROR_NO_FILE
fi

But now when i enter more than 1 argument it just does everything in the if statement (i.e. prints error.file does not exist) even when the file does exist.

但是现在当我输入 1 个以上的参数时,即使文件确实存在,它也会执行 if 语句中的所有操作(即打印 error.file 不存在)。

回答by Jeff Schaller

Doing it another way: just ask how many parameters were passed:

换一种方式:只需询问传递了多少参数:

...
if [ $# -eq 0 ]
...

You get the error in your code because the $@ variable expands to multiple words, which leaves the testcommand looking like this:

由于 $@ 变量扩展为多个单词,您的代码中会出现错误,这使test命令看起来像这样:

[ -z parm1 parm2 parm3 ... ]

[ -z parm1 parm2 parm3 ... ]

回答by Barmar

$@is expanding to all the arguments, with spaces between them, so it looks like:

$@扩展到所有参数,它们之间有空格,所以它看起来像:

if [ -z file1 file2 file3 ]

but -zexpects just one word after it. You need to use $*and quote it, so it expands into a single word:

-z期望在它之后只有一个字。您需要使用$*并引用它,因此它扩展为一个单词:

if [ -z "$*" ]

This expands into:

这扩展为:

if [ -z "file1 file2 file3" ]

Or just check the number of arguments:

或者只是检查参数的数量:

if [ $# -eq 0 ]

You should also put this check before the forloop. And you should quote the argument in the forloop, so you don't have problems with filenames that have spaces:

您还应该在for循环之前进行此检查。并且您应该在for循环中引用该参数,这样您就不会遇到带有空格的文件名的问题:

for file in "$@"

回答by andlrc

Wrap your parameters in double quotes to avoid word splitting and pathname expansion:

将参数用双引号括起来以避免分词和路径名扩展:

for file in "$@"
do
    chmod 755 "$file"
done

if [ -z "$*" ] # Use $* instead of $@ as "$@" expands to multiply words.
then
        echo "Error. No argument."
        exit "$ERROR_CODE_1"
fi

You can however change the code a little:

但是,您可以稍微更改代码:

for file # No need for in "$@" as it's the default
do
    chmod 755 "$file"
done

if [ "$#" -eq 0 ] # $# Contains numbers of arguments passed
then
    >&2 printf 'Error. No argument.\n'
    exit "$ERROR_CODE_1" # What is this?
fi