2010-11-21 136 views
0

我有嚴重的問題,試圖找出如何在使用Tcl的If語句中評估表達式。這是我有:在if語句中使用Tcl評估表達式爲true

#!/bin/sh 
#The next line executes wish - wherever it is \ 
exec wish "$0" "[email protected]" 

set apid "/var/run/apache2.pid" 

set apsta [file exist $apid] 

if { $apsta == 1 } 

{ 
    set result ":)" 
} 

else 

{ 
    set result ":(" 
} 

label .status -text $result 
pack .status 

,這是我從終端獲得:

# wan27 
Error in startup script: wrong # args: no script following " $apsta == 1 " argument 
    while executing 
"if { $apsta == 1 }" 
    (file "/usr/bin/wan27" line 9) 

我只是想輸出一個幸福的笑臉如果Apache運行,是令人失望的,如果阿帕奇停止 - 基於布爾條件是否文件「/var/run/apache2.pid」的存在......

+0

你已經差不多了使用一個真正的佈雷斯風格的Tcl(選擇你自己的縮進規則,雖然,但我更喜歡3個或4個空格),因爲否則的語言結束語句在第一個換行符。你唯一的選擇是在你想要繼續的行尾添加額外的反斜槓,但是我認爲這很糟糕。 (或者,用一個很長的行寫一些命令之間的分號,醜陋的,但沒有大括號/縮進問題。) – 2010-11-22 01:10:24

+0

好吧,我現在明白了,這就解釋了「沒有腳本跟在」thingy。口譯員希望在if語句的同一行中有一個大括號。我還注意到,關鍵字如果需要用空格分隔,並且不能粘在評估符號上,如{ – fabjoa 2010-11-22 10:24:44

+0

}還要注意''[文件存在...]'返回真/假結果,所以你不需要明確地將結果與1進行比較:'if {$ apsta} {...}' – 2010-11-22 14:16:02

回答

8

一個Tcl if語句的語法是

if condition statement else statement 

必須在一行上。大括號允許延續跨行和他們的安置是必須的:

if { $apsta == 1 } { 
    set result ":)" 
} else { 
    set result ":(" 
} 

正如你它寫,TCL認爲

if { $apsta == 1 } 

並停止在那裏產生一個語法錯誤。

+0

+1:這就是問題所在。 – 2010-11-22 01:12:00

+0

就地當場!感謝msw – fabjoa 2010-11-22 10:26:26

2

MSW已經給你正確的答案,但我認爲需要更多的解釋來根據你的意見澄清你的一些其他困惑。

我將首先解釋使用非tcl術語的事情,因爲我認爲它不那麼令人困惑。

在tcl中,if不是一個聲明。 if是一個函數。這就是爲什麼左括號需要在同一行上的原因:因爲換行符會終止函數的參數列表。例如,在下面的代碼中:

a b c d 
e f 

Tcl解釋器會看到兩個函數調用。第一個使用參數b,c和d運行a,第二個使用單個參數f運行e。同樣,在以下內容中:

if a 
    b 

Tcl看到使用單個參數調用函數if。由於if期望至少有兩個參數(不是解釋器本身)會拋出一個抱怨錯誤數量參數的錯誤。

這也解釋了爲什麼if和第一個參數之間必須有一個空格。這是因爲在tcl中,變量和函數的名稱實際上允許包含空格,逗號和NUL等非打印字符。例如,您可以定義一個函數調用a{b}

proc a{b} {} {puts HA!} 
a{b} ;# <-- prints out HA! 

所以,如果你是這樣的:

if{x} {y} 

TCL將抱怨功能if{x}沒有定義。

if並不是唯一這樣工作的東西。Tcl並沒有真正的關鍵字,只是一個內置函數的標準庫,如for,foreachwhile。同樣的規則適用於所有這些規則。


並不重要:

在一個側面,在TCL的if功能的工作原理類似於C三元運算符:它返回一個值。事實上,你可以做到以下幾點:

# It is unfortunate that this "give" function is not built in. 
# We use it to return something from if without actually 
# calling return: 
proc give {x} {return $x} 

set something [if {$x} {give "Very true indeed."} {give "Unfortunately false."}]