这与其他的不同之处在于:
- 我在 shebang 中调用 bash (不是 sh):
#! /bin/bash
- 我正在运行它
./
- 文件权限正确:
755
有问题的行是:
formattedTIME=`awk '{printf("Duration:\t%02dh %02dm",($1/60/60%24),($1/60%60))}' $domPATH/duration.seconds`
的内容$domPATH/duration.seconds
是37603
我可以在命令行运行它:
formattedTIME=`awk '{printf("Duration:\t%02dh %02dm",($1/60/60%24),($1/60%60))}' duration.seconds`
Duration: 10h 26m
并得到当我的结果echo $formattedTIME
但在脚本中运行它会导致:
./time.sh: line 42: syntax error near unexpected token `('
./time.sh: line 42: ` formattedTIME=`awk '{printf("Duration:\t%02dh %02dm",($1/60/60%24),($1/60%60))}' $domPATH/duration.seconds`'
额外信息:这是在运行 Jessie 的 Raspberry Pi 2 上。
更新:错误在线8:
echo 'Cc: [email protected],[email protected],[email protected],[email protected]'' >> $domPATH/arrive.email
答案1
关于为什么命令在脚本中无法正确解析但在单独运行时却正常的一些常见趋势:
错误的根源在其他地方
shell 将在它不期望的第一件事上报告错误。在这里,它不需要一个(
,但它似乎位于带引号的字符串内。一个可能的解释是,您不在带引号的字符串中,因为第一个'
实际上关闭了较早的未关闭的引号,而不是打开一个新的'...'
引号,如下所示:
echo It's a bug
formattedTIME=`awk '{printf("Duration:\t%02dh %02dm",($1/60/60%24),($1/60%60))}' $domPATH/duration.seconds
这实际上是:
echo It'quoted-string'{printf("Duration:\t%02dh %02dm",($1/60/60%24),($1/60%60))}'...
上面未引用的内容(
是 shell 意想不到的。
对于任何未正确关闭或格式错误的结构,您都会遇到类似的问题,例如fi
没有then
...
反引号
确实不应该使用反引号。$(...)
应该使用。
反引号内,\
处理方式不同。
echo "`
echo It\\\'s OK
`"
不行。尽管echo It\\\'s OK
它本身是可以的,但由于内部反引号,前两个反斜杠变成了一个,所以它最终是echo It\\'OK
。
现代形式$(...)
不存在这些问题。
别名
别名有点像宏,它们的扩展再次经过代码解释。
像:
alias foo="echo '"
...
foo bar
echo 'baz('
会将问题隐藏在foo
别名的定义中。
还有一些更微妙的,例如:
alias foo='a;b'
cmd | foo
这不会导致语法错误,但会导致解析以意外的方式完成。
通常,函数比别名更合适
本土化
某些字节序列可以根据区域设置进行不同的解释。
例如,0xa0 字节是 ISO-8859-1 字符集中的不间断空格。在 Solaris 上,该字符恰好是空格,并且bash
恰好将所有空格视为分隔符(目前仅适用于单字节字符)。
该 0xa0 字节也恰好是几个 UTF-8 字符的一部分,例如à
.因此,您可能会发现例如一个脚本具有:
var=àdo
(用à
UTF-8 编写的)在 ISO-8859-1 语言环境的 Solaris 上运行时停止工作,因为它变成var=X do
(whereX
是该字符的第一个字节à
)。
或者你可能会发现:
echo ε
当您不在语言环境中时,以ε
BIG5-HKSCS 字符集编写的字符将停止工作,zh_HK.big5hkscs
因为它ε
实际上编码为 0xa3 0x60,其中 ASCII 和所有单字节字符集中的 0x60 是反引号字符。