2011-06-09 77 views
3

我正在編寫一個Bash函數來啓動需要從某個文件夾啓動的服務器,但我不想啓動這個服務器來影響我當前的工作。我已經寫了以下內容:在bash函數中產生一個後臺進程

function startsrv { 
     pushd . 
     cd ${TRUNK} 
     ${SERVERCOMMAND} & 
     popd 
} 

我的變量都設置,但這種執行時,我得到關於在輸出意外分號的錯誤,看來Bash是符號開始${SERVERCOMMAND}後插入一個分號在背景中。

有什麼我可以做的,在後臺啓動${SERVERCOMMAND},同時仍然使用pushd和popd來確保我最終返回到當前目錄?

編輯:的echo ${SERVERCOMMAND}輸出,因爲它要求:

yeti --server --port 8727 

錯誤消息:

-bash: syntax error near unexpected token `;' 

回答

11

什麼是$SERVERCOMMAND價值?你必須有一個分號。

對於它的價值可以簡化PUSHD/cd到一個PUSHD:

pushd $TRUNK 
$SERVERCOMMAND & 
popd 

或者創建一個子shell這樣的CD只會影響一個命令:

(cd $TRUNK; $SERVERCOMMAND &) 
+0

的PUSHD技巧是好的,但$ {} SERVERCOMMAND沒有分號,它是等於'雪人--server --port $ {YETIPORT}'YETIPORT是數字。使用subshel​​l版本時出現同樣的錯誤。 – foxxtrot 2011-06-09 20:19:21

+0

你可以給出你正在得到的確切的錯誤信息,也可以'echo「$ SERVERCOMMAND」'並顯示它的確切值? ('$ {YETIPORT}'的變量替換應該已經被執行,所以你應該看到一個實際的端口號,而不是變量名。) – 2011-06-09 20:45:09

+0

已被添加到問題中。 – foxxtrot 2011-06-09 21:41:51

3

您還可以使用cd -

cd $TRUNK 
$SERVERCOMMAND & 
cd - 
2

${SERVERCOMMAND}分號不應該引發語法埃羅r除非bash本身存在錯誤。分號問題必須位於其他地方,在我們看不到的部分代碼中。

除了分號的問題,也有在你的代碼的一些小錯誤:

  • ${TRUNK}變量擴展沒有加引號。如果目錄名稱包含空格,bash將在調用cd之前將其拆分爲多個字段。
  • 未檢查返回值cd ${TRUNK}。如果該目錄不存在,bash將調用當前目錄中的服務器。
  • 該函數不測試${SERVERCOMMAND}是否可能無法執行(例如,未找到命令)。
  • function關鍵字和pushdpopd命令是bash特定的,因此此代碼不會在POSIX shell中運行。

這裏有一個更安全,符合POSIX標準的改寫:

log() { printf '%s\n' "$*"; } 
error() { log "ERROR: $*" >&2; } 
fatal() { error "$*"; exit 1; } 

startsrv() { 
    (
     cd "${TRUNK}" || fatal "failed to cd to '${TRUNK}'" 
     set -- ${SERVERCOMMAND} 
     command -v "$1" >/dev/null || fatal "command '$1' not found" 
     command "[email protected]" & 
    ) || exit 1 
}