Bash 脚本,非法编号:08
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/878218/
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
Bash script, Illegal number: 08
提问by
I'm running a pretty simple bash script in ubuntu but have come up with a problem. If needed I'll post the whole script, but I've narrowed down the problem. Basically, I want to run some code every 15 seconds, so I started with this:
我在 ubuntu 中运行了一个非常简单的 bash 脚本,但遇到了一个问题。如果需要,我会发布整个脚本,但我已经缩小了问题的范围。基本上,我想每 15 秒运行一次代码,所以我从这个开始:
time=`date +%S`
time2=$((time%15))
if [ $time2 -eq 0 ]
then
etc, etc, etc....
等等等等等等....
The problem comes up when time is 08 seconds. The script terminates with Illegal number: 08. Adding to that, when using:
当时间为 08 秒时出现问题。脚本以非法编号终止:08。添加到,使用时:
time2=$(($time%15))
instead of the illegal number error, it would terminate with Arithmetic expression: expecting EOF: "08%15"
而不是非法数字错误,它将以算术表达式终止:期望 EOF:“08%15”
I'm guessing 08 isn't interpreted as a number. Or there's some base issue, like it thinks it's in octal or something. Any help?
我猜 08 不会被解释为一个数字。或者有一些基本问题,比如它认为它是八进制或其他东西。有什么帮助吗?
采纳答案by ephemient
Shortest solution:
最短的解决方案:
time2=$(( ${time#0} % 15 ))
${var#glob}means "$varwith globremoved from the beginning if present".
${var#glob}手段“$var与glob如果存在的话从一开始就去除”。
回答by Johannes Schaub - litb
Try using the following flags instead
尝试使用以下标志代替
date +%-S
It says given the -, it won't pad. It has problems with the base, interpreting it as an octal integer.
它说鉴于-,它不会填充。它的基数有问题,将其解释为八进制整数。
Anyway, if you want to do something every 15 seconds, i find this one easier to follow:
无论如何,如果你想每 15 秒做一次,我发现这个更容易理解:
while ((1)); do
echo do something now...
sleep 15s
done
回答by TheBonsai
Force Bash to interpret the number in decimal, no matter how many padded zeros:
强制 Bash 以十进制解释数字,无论有多少填充零:
time2=$((10#$time % 15))
回答by jrrs
you're right, it was interpreting it as octal. bourne shells do that for any number with a leading 0 in an Arithmetic Substition:
你是对的,它把它解释为八进制。bourne shell 对算术替换中前导 0 的任何数字执行此操作:
#~ $ echo $(( 010 ))
8
#~ $ echo $(( 0100 ))
64
#~ $ echo $(( 10#0100 ))
100
#~ $ echo $(( 40#lolwut ))
2213236429
look in the manpage for 'base#' to see all the details about this '#-forcing' thing. you can get pretty ridiculous with it if you want to
查看“base#”的联机帮助页以查看有关此“#-forcing”的所有详细信息。如果你愿意,你可以用它变得非常荒谬
回答by pjc50
That does look like it's interpreting it as octal.
这看起来确实是将其解释为八进制。
Try date +%S | sed -e 's/^0//'
尝试 date +%S | sed -e 's/^0//'
回答by Dave Webb
Since you're only interested in "every fifteen seconds" rather than running things on the minute exactly you could use date +%s(lowercases) which will give you the number of seconds since the start of the epoch. This won't have a leading 0so your script should run fine.
由于您只对“每 15 秒”感兴趣,而不是精确地在分钟上运行,因此您可以使用date +%s(小写s)这将为您提供自纪元开始以来的秒数。这不会有前导,0因此您的脚本应该可以正常运行。
However, I would wonder about your code in a wider context. If the system is running very slow for some reason it could be possible for the script only be run second 14 and then second 16 meaning it will miss an execution.
但是,我想在更广泛的背景下了解您的代码。如果系统由于某种原因运行得很慢,则脚本可能只在第 14 秒运行,然后在第 16 秒运行,这意味着它将错过执行。
It might be worth touching a file when you do whatever it is the script does and then performing your action when then last modified date of the file is 15 or more seconds ago.
当您执行脚本所做的任何操作然后在文件的最后修改日期为 15 秒或更长时间之前执行您的操作时,可能值得触摸文件。

