執行

說明

執行系統指令。當指定 os 屬性時,指令只會在 Apache Ant 在指定作業系統之一上執行時執行。

請注意,您無法與分岔程式互動,唯一能將輸入傳送給它的方式是透過輸入和輸入字串屬性。另請注意,自 Ant 1.6 起,在分岔程式中嘗試讀取輸入會收到 EOF (-1)。這是 Ant 1.5 的變更,在 Ant 1.5 中,此類嘗試會被封鎖。

如果您想使用相對於專案 basedir 的路徑執行可執行檔,您可能需要在某些作業系統上使用 vmlauncher=false,但即使這樣也可能會失敗 (已回報 Solaris 8/9 有問題)。resolveexecutable 屬性應該更可靠,類似於

<property name="executable-full-path"
          location="../relative/path/to/executable"/>
<exec executable="${executable-full-path}" ...

Windows 使用者

<exec> 任務委派給 Runtime.exec,而 Runtime.exec 顯然會呼叫 ::CreateProcess。後者 Win32 函式定義了呼叫的確切語意。特別是,如果您沒有在可執行檔上加上副檔名,只會尋找 .EXE 檔案,而不是 .COM.CMD 或環境變數 PATHEXT 中列出的其他檔案類型。這只會由 shell 使用。

請注意,.bat 檔案通常無法直接執行。通常需要使用 /c 開關執行命令 shell 可執行檔 cmd

<target name="help">
  <exec executable="cmd">
    <arg value="/c"/>
    <arg value="ant.bat"/>
    <arg value="-p"/>
  </exec>
</target>

常見問題是可執行檔不在 PATH 中。如果您收到錯誤訊息 無法執行程式 "...":CreateProcess 錯誤=2。系統找不到指定的路徑。請查看您的 PATH 變數。只需直接在命令列上輸入指令,如果 Windows 找到它,Ant 也應該可以找到它。(否則請在使用者寄件清單上尋求協助。)如果 Windows 無法執行程式,請將程式的目錄新增到 PATH (set PATH=%PATH%;dirOfProgram) 或在 buildfile 中的 executable 屬性中指定絕對路徑。

Cygwin 使用者

<exec> 任務不會了解 executable 參數的路徑,例如 /bin/sh。這是因為 Ant 執行的 JVM 是標準 Windows 可執行檔,不了解 Cygwin 環境 (即,不會載入 cygwin1.dll)。唯一的解決方法是在 Cygwin 下編譯 JVM (風險自負)。例如,請參閱 cygwin 的 OpenJDK 建置說明

OpenVMS 使用者

使用 executable<arg> 元素指定的命令會在暫時的 DCL 腳本中執行,就像指定的內容一樣。這有一些影響

請注意,HP 提供的 JVM 沒有遵循 OpenVMS 的結束代碼慣例。如果您使用此工作執行 JVM,工作可能會錯誤地宣稱發生錯誤(或靜默忽略錯誤)。請勿使用此工作執行 JAVA.EXE,請使用 fork 屬性設定為 true<java> 工作,因為此工作會遵循 JVM 對結束代碼的詮釋。

RedHat S/390 使用者

已在 linux-390報告,透過 Ant Exec 工作呼叫的 shell 腳本必須指定其詮釋器,也就是說,腳本必須以類似以下的內容開始

#!/bin/bash

否則工作會失敗,如下所示

[exec] Warning: UNIXProcess.forkAndExec native error: Exec format error
[exec] Result: 255

在類 Unix 系統上以背景程序執行 Ant

如果您以背景程序執行 Ant(例如 ant &),並使用將 spawn 設定為 false<exec> 工作,您必須提供明確的輸入給分岔的程序,否則 Ant 會暫停,因為它會嘗試從標準輸入中讀取。

參數

屬性 說明 必要
command 要執行的命令,包含所有命令列參數。已棄用,請改用 executable 和巢狀 <arg> 元素 兩個屬性中必須有一個
executable 要執行的命令,不含任何命令列參數。
dir 要執行命令的目錄。 否;如果 vmlaunchertrue,則預設為目前的作業目錄,否則為專案的 basedir
os 可以執行命令的作業系統清單。如果目前的作業系統名稱包含在此清單中,則會執行命令。作業系統名稱由 JVM 決定,並設定在 os.name 系統屬性中。
osfamily <os> 條件中使用的作業系統系列。自 Ant 1.7 起
spawn 是否要分岔命令
如果您分岔一個命令,它的輸出不會記錄在 Ant 中。
當產生程序時,inputoutputerrorresult 屬性設定不會啟用。
自 Ant 1.6
否;預設為 false
output 要寫入輸出的檔案名稱。如果錯誤串流未重新導向至檔案或屬性,它會出現在此輸出中。
error 應將命令的標準錯誤重新導向至的檔案。自 Ant 1.6
logError 當您想要在 Ant 的記錄中看到錯誤輸出,且您正在將輸出重新導向至檔案/屬性時,會使用此屬性。錯誤輸出不會包含在輸出檔案/屬性中。如果您使用 errorerrorProperty 屬性重新導向錯誤,這不會有任何影響。自 Ant 1.6
append 輸出和錯誤檔案應附加或覆寫。 否;預設為 false
outputproperty 應儲存命令輸出的屬性名稱。除非錯誤串流重新導向至個別檔案或串流,否則此屬性會包含錯誤輸出。
errorproperty 應儲存命令的標準錯誤的屬性名稱。自 Ant 1.6
input 執行命令的標準輸入所取用的檔案。此屬性與 inputstring 屬性互斥。自 Ant 1.6
inputstring 作為執行命令的輸入串流的字串。此屬性與 input 屬性互斥。自 Ant 1.6
resultproperty 應儲存命令回傳碼的屬性名稱。只有在 failonerror=false 時才會有興趣。
timeout 如果命令未在指定時間內完成(以毫秒為單位),則停止命令。
failonerror 如果命令以表示失敗的回傳碼結束,則停止建置程序。 否;預設為 false
failifexecutionfails 如果無法啟動程式,則停止建置。 否;預設為 true
newenvironment 當指定新的環境變數時,不要傳播舊環境。 否;預設為 false
vmlauncher 在可用的情況下,使用 JVM 的執行設施執行命令。如果設定為 false,則會使用基礎作業系統的殼層,直接或透過 antRun 腳本。在某些作業系統中,這會讓您存取通常無法透過 JVM 存取的設施,包括在 Windows 中能夠執行腳本,而不是其關聯的直譯器。如果您想要將可執行檔的名稱指定為 dir 屬性所給目錄的相對路徑,可能也需要將 vmlauncher 設定為 false 否;預設為 true
resolveexecutable 當此屬性為 true 時,可執行檔的名稱會先與專案 basedir 進行比對,如果不存在,則會與指定的執行目錄進行比對。在 Unix 系統中,如果你只想允許執行使用者路徑中的指令,請將此設定為 false自 Ant 1.6 起 否;預設為 false
searchpath 當此屬性為 true 時,在解析可執行檔位置時,系統路徑環境變數會被搜尋。自 Ant 1.6.3 起 否;預設為 false
discardOutput 是否應完全捨棄輸出。此設定與將輸出重新導向至檔案或屬性的任何設定不相容。
如果你將此設定為 true,錯誤輸出也會被捨棄,除非你將錯誤輸出重新導向至檔案、屬性或啟用 logError自 Ant 1.10.10 起
否;預設為 false
discardError 是否應完全捨棄錯誤輸出。此設定與將錯誤輸出重新導向至檔案或屬性的任何設定,以及 logError 不相容。自 Ant 1.10.10 起 否;預設為 false

範例

<exec dir="${src}" executable="cmd.exe" os="Windows 2000" output="dir.txt">
  <arg line="/c dir"/>
</exec>

指定為巢狀元素的參數

arg

命令列引數應指定為巢狀 <arg> 元素。請參閱 命令列引數

env

可以透過巢狀 <env> 元素指定要傳遞至系統指令的環境變數。

屬性 說明 必要
key 環境變數的名稱。
注意自 Ant 1.7 起,對於 Windows,名稱不區分大小寫。
value 環境變數的文字值。 其中之一
path 類似 PATH 的環境變數值。你可以使用 ;: 作為路徑分隔符號,而 Ant 會將其轉換為平台的當地慣例。
file 環境變數的值。會由 Ant 替換為檔案的絕對檔名。

redirector

自 Ant 1.6.2 起

可以指定巢狀 I/O Redirector。一般來說,重新導向器的屬性行為與任務層級中可用的對應屬性相同。最顯著的特殊性來自於保留 <exec> 屬性以維持向後相容性。任何檔案對應都會使用 null 來源檔案進行;因此,並非所有對應器類型都會傳回結果。當沒有傳回結果時,重新導向規格將會回歸到任務層級的屬性。在實務上,這表示可以為輸入、輸出和錯誤輸出檔案指定預設值。

錯誤和回傳代碼

預設情況下,<exec> 的回傳代碼會被忽略;當你將 failonerror 設為 true 時,任何表示失敗的回傳代碼(作業系統特定)都會導致建置失敗。或者,你可以將 resultproperty 設為某個屬性的名稱,並將其指定給結果代碼(當然,除非不可變更)。

如果嘗試啟動程式時發生作業系統相依的錯誤代碼,則 <exec> 會停止建置,除非 failifexecutionfails 設為 false。你可以使用它來執行某個程式(如果它存在),否則不執行任何動作。

這些錯誤代碼是什麼意思?嗯,它們是作業系統相依的。在 Windows 電腦上,你必須查看 文件error=2 表示「找不到此程式」,這通常表示它不在路徑中。任何時候你從任何 Ant 任務中看到此類錯誤,通常不是 Ant 錯誤,而是電腦上的某些組態問題。

範例

在 X Window System 的顯示器 1 上啟動 emacs

<exec executable="emacs">
  <env key="DISPLAY" value=":1.0"/>
</exec>

${basedir}/bin 加入系統命令的 PATH 中。

<property environment="env"/>
<exec ... >
  <env key="PATH" path="${env.PATH}:${basedir}/bin"/>
</exec>

使用指定的 ${file} 啟動 ${browser},並結束 Ant 程序。瀏覽器將保持開啟狀態。

<property name="browser" location="C:/Program Files/Internet Explorer/iexplore.exe"/>
<property name="file" location="ant/docs/manual/index.html"/>

<exec executable="${browser}" spawn="true">
    <arg value="${file}"/>
</exec>

將字串 blah before blah 傳送給 cat 執行檔,使用 <inputfilterchain> 在輸入時將 before 替換為 after。輸出會傳送給檔案 redirector.out,並儲存在同名的屬性中。類似地,錯誤輸出會傳送給檔案和屬性,兩者都命名為 redirector.err

<exec executable="cat">
    <redirector outputproperty="redirector.out"
                errorproperty="redirector.err"
                inputstring="blah before blah">
        <inputfilterchain>
            <replacestring from="before" to="after"/>
        </inputfilterchain>
        <outputmapper type="merge" to="redirector.out"/>
        <errormapper type="merge" to="redirector.err"/>
    </redirector>
</exec>

注意:不要嘗試使用簡單的 arg 元素指定引數,並用空格分隔它們。這只會產生一個包含整個字串的單一引數。

逾時:如果指定逾時,則在達到逾時時,子程序會被終止,並將訊息列印到記錄檔。執行的回傳值會是 -1,如果 failonerror=true,則會停止建置,否則會被忽略。