简体   繁体   English

调用bash脚本会在if语句和变量赋值时生成错误

[英]calling bash script generates error on if statement and variable assignment

I'm trying to execute a very simple program (round numbers to lowest integer divisible by 15) but am getting an error: 我正在尝试执行一个非常简单的程序(将数字舍入到可被15整除的最低整数),但是收到错误:

$min = date +"%M";

if [ $min%15 != 0 ]
  then
    $min - $min%1
fi

echo $min;

I call it with sh cache.sh 我用sh cache.sh调用它

I feel I've followed the syntax I've learned here but I'm getting line 9: syntax error: unexpected end of file What have I got wrong here? 我觉得我已经遵循了我在这里学到的语法但是我得到了line 9: syntax error: unexpected end of file我在这里遇到了什么错误?

That script is not valid bash syntax. 该脚本不是有效的bash语法。 I would start by finding some working examples, and perhaps an entire tutorial. 我首先会找到一些有用的例子,也许还有整个教程。 You might start with William Shotts' book, which is available online . 您可以从William Shotts的书开始,该书可在线获取

Some notes about your attempt: 有关您尝试的一些注意事项

  1. The $ is used to request replacement of a variable 1 by its value. $用于请求通过其值替换变量1 It is not a sigil that is part of the variable name, as it is in Perl or PHP. 它不是变量名称的一部分,因为它在Perl或PHP中。 So it is not used on the left-hand-side of an assignment. 因此,它不会在作业的左侧使用。

  2. The shell is primarily used to run other executables, and interprets everything through that lens. shell主要用于运行其他可执行文件,并通过该镜头解释所有内容。 If a command line looks like an invocation of another program, the shell will try to run that other program, rather than do anything shell-scripty. 如果命令行看起来像是对另一个程序的调用,那么shell将尝试运行该其他程序,而不是执行任何shell-scripty。 Therefore, the command min = date +"%M" will cause the shell to look for a program named min and execute it with three command-line arguments: = , date , and +%M . 因此,命令min = date +"%M"将使shell查找名为min的程序并使用三个命令行参数执行它: =date+%M
    In order for an assignment to be recognized as such, there cannot be any space around the = . 为了使分配被识别, =周围不能有任何空间。

  3. Without spaces, min=date +"%M" is still not right, however. 但是,没有空格, min=date +"%M"仍然不对。 The shell will just temporarily assign the literal string "date" to the variable min and then try to run a command called +%M . shell将暂时将文字字符串“date”分配给变量min ,然后尝试运行名为+%M的命令。
    If a value has spaces in it, you need quotation marks around it 2 . 如果值中包含空格,则需要在其周围加上引号2

  4. Even with quotes, however, min="date +%M" would assign to min the literal string "date +%M". 即使有报价,但是, min="date +%M"将会分配给min文本字符串“日期+%M”。 If you actually want to run the command date +"%M" and use its output as a value, then you have to request that using the command-substitution syntax, $(...) . 如果您确实想要运行命令 date +"%M"并将其输出用作值,那么您必须使用命令替换语法$(...)来请求它。 Here our friend the dollar sign is again requesting replacement by a dynamic value, but the parentheses make it a different type of request; 在这里,我们的朋友美元符号再次请求动态值替换,但括号使其成为不同类型的请求; instead of a variable's value, the expression is replaced by the output of a command. 而不是变量的值,表达式由命令的输出替换。

  5. Because of the parsing issues noted above, the built-in arithmetic operations only work in certain contexts. 由于上面提到的解析问题,内置算术运算仅适用于某些上下文。 Two ways to create a valid arithmetic context are the (( ... )) special forms and the let command. 创建有效算术上下文的两种方法是(( ... ))特殊形式和let命令。

  6. Finally, even if your script were syntactically valid, it is semantically incorrect if your goal is to round down to the nearest multiple of 15. The remainder after dividing by 1 is always zero, so your script ends by attempting to subtract 0 from min - and does nothing with the result anyway, since there's no assignment back to min . 最后,即使你的脚本在语法上是有效的,如果你的目标是向下舍入到最接近的15的倍数,那么它在语义上是不正确的。除以1后的余数总是为零,所以你的脚本最后试图从min减去0 -并且无论如何都没有对结果做任何事情,因为没有任何分配回到min If you want to round down, you have to actually subtract the remainder that you just tested. 如果要向下舍入,则必须实际减去刚刚测试的余数。 You could do it like this: 你可以这样做:

     min=$(date +%M) let rem=min%15 if (( rem != 0 )); then let min-=rem fi echo $min 

But you could also do it a bit more succinctly: 但你也可以更简洁地做到这一点:

echo $(( min=$(date +%M), min-=min%15 ))

This works without an if because subtracting 0 is harmless. 这没有if因为减去0是无害的。 The comma just lets us put two expressions inside a single set of ((...)) . 逗号只是让我们将两个表达式放在一组((...)) The second expression min-=min%15 is a modifying assignment - it means the same thing as min=min-min%15 , but saves us one instance of typing out "min". 第二个表达式min-=min%15是一个修改赋值 - 它与min=min-min%15含义相同,但是节省了一个键入“min”的实例。 Putting our friend the replacement-requesting $ in front of (( ... )) causes the whole expression to be replaced by its value, so that echo gets something to print out. 将我们的朋友放在(( ... ))前面的替换请求$会导致整个表达式被其值替换,以便echo可以打印出来。 The value of a list of expressions is the value of the last expression, and the value of an assignment is the same as the value that was assigned, so the result that is echo ed is the same as the final value of $min : the closest multiple of 15 minutes after the hour. 表达式列表的值是最后一个表达式的值,赋值的值与赋值的值相同,因此echo ed的结果与$min的最终值相同:一小时后最接近15分钟的倍数。

1 In shell terminology, variables are actually called "parameters". 1在shell术语中,变量实际上称为“参数”。 Just something to bear in mind when reading documentation. 阅读文档时要记住一些事项。

2 You actually don't need quotation marks around the %M in your command for this reason. 2你其实并不需要周围的引号%M在命令这个原因。 Everything in the shell is automatically a string; shell中的所有内容都自动为字符串; you don't need the quotes to make it one. 你不需要引号来使它成为一个。 However, they don't hurt, and putting quotation marks around things is a good habit to have, since it keeps your code from being broken by unexpected special characters in input values. 但是,它们不会受到伤害,并且在事物周围加上引号是一个很好的习惯,因为它可以防止代码被输入值中的意外特殊字符破坏。

Your script has many syntax issues. 您的脚本有许多语法问题。 In shell assignment is is 在shell中赋值是

var='val' VAR = 'VAL'

instead of 代替

$var='val' 是$ var = 'VAL'

Also there is no space around = =周围没有空格

Your correct script can be: 你的正确脚本可以是:

min=$(date +"%M")

if (( min % 15 != 0 ))
then
    echo "not fully divisible by 15"
fi

echo $min

It looks like you converted this from some other language. 看起来你用其他语言转换了这个。 Here's a working bash version. 这是一个工作的bash版本。

#!/bin/bash
min=$(date +"%M")

if [ $(($min % 15)) != 0 ] ; then
    min=$(( min - min % 1 ))
fi

echo $min;

local output: 本地输出:

~/tmp › sh ./test.sh
34
 min=`date +"%M"`;

 if [ $min%15 != 0 ]

 then

 min=$((min - min%1))

 fi

 echo $min;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM