Bash

意外標記“(”附近的另一個語法錯誤

  • November 14, 2016

這一個與其他的不同:

  1. 我在shebang中呼叫bash(不是sh):#! /bin/bash
  2. 我正在執行它./
  3. 文件權限正確:755

有問題的行是:

formattedTIME=`awk '{printf("Duration:\t%02dh %02dm",($1/60/60%24),($1/60%60))}' $domPATH/duration.seconds`

的內容$domPATH/duration.seconds37603

我可以在命令行執行它:

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: xxx@xxxx.xxx,xxx@xxxx.xxx,xxx@xxxx.xxx,xxx@xxxx.xxx'' >> $domPATH/arrive.email

關於為什麼命令在腳本中無法正確解析但在單獨執行時可以正常解析的一些常見趨勢:

錯誤的來源在別處

shell 將在它不期望的第一件事上報告錯誤。在這裡,它不需要 a (,但它似乎在帶引號的字元串中。一種可能的解釋是,您不在帶引號的字元串中,因為第一個'實際上關閉了較早的未關閉引號,而不是'...'像以下那樣打開新的:

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))}'...

上面未引用(的內容是外殼出乎意料的。

對於任何未正確關閉或格式錯誤的結構,您都會遇到類似的問題,例如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 doX該字元的第一個字節在哪裡à)。

或者你可能會發現:

echo ε

ε當您不在語言環境中時,用 BIG5-HKSCS 字元集編寫的內容將停止工作zh_HK.big5hkscs,因為它ε實際上被編碼為 0xa3 0x60,其中 ASCII 中的 0x60 和所有單字節字元集都是反引號字元。

引用自:https://unix.stackexchange.com/questions/323119