2013-07-01 67 views
12

我的網站的代碼使用這段代碼在服務器上自動部署(Ubuntu)。忽略Mac OS X中xargs的空結果

cmd = 'cd ' + checkout_dir + ' && ' + svn_command + " st | awk '{print $2}' | grep -v ^deploy | tac | xargs -r" + svn_command + " revert -R && " + svn_command + ' up -r ' + options.revision

一下這個命令的作用是它cd到檢出目錄,運行svn status,然後提取的文件名($2),從列表中(我不刪除deploy目錄及其所有文件不想恢復它)。如果沒有參數,它不運行svn revert命令,否則它會。

不幸的是,xargs -r在我的機器上無法正常工作(Mac OS X 10.8)。所以我卡在這裏,任何人都可以幫忙嗎?

+1

那是Python代碼還是什麼? – tripleee

回答

4

確實,xargs的BSD執行沒有-r標誌(--no-run-if-empty)。 Linux中的GNU版本有它。

這裏有一種方法來解決此問題,在Linux和BSD的工作方式:

... | (grep -v ^deploy || echo :) | xargs svn revert 

grep ... || echo :在中間的grep輸出將在它生成一個:線的情況下,是空的。這有點,因爲xargs仍然會運行命令svn revert :。如果您的存儲庫不包含文件:那麼這應該沒有效果,所以它可以被接受。 :可以是其他任何東西,只要您的存儲庫中沒有這樣的文件即可。

最後,如@tripleee指出的那樣,grep ... || echo :必須在(...)封閉,這是因爲:

||具有比|更高的優先級,並因此終止該(第一)的管道。

您的代碼看起來像一個Python字符串。這將是更具可讀性這樣:

kwargs = { 
    'svn': svn_command, 
    'dir': checkout_dir, 
    'revno': options.revision, 
} 
cmd = "cd {dir} && {svn} st | awk -v r=1 '$2 ! ~ /deploy/ {{ print $2; r=0 }} END {{ r || print \":\" }}' | xargs {svn} revert && {svn} up -r {revno}".format(**kwargs) 

我做了一些改變你原來的:

  • 移動grep的邏輯裏面awk,爲@tripleee建議。請注意,由於不再需要grep破解,也沒有更多的需要包裝內(...)
  • 扔下tac,因爲我沒有看到它
  • svn revert扔下-R點,因爲我不不認爲你需要它
+0

這有何幫助?問題不是空行,它是* no *行。 – tripleee

+0

@tripleee他希望使用'xargs'的'-r'標誌,但不能,因爲它在BSD中不存在。他想使用該標誌,因爲他不想在沒有參數的情況下運行'svn revert -R'。 'svn revert -R something'只會恢復「something」中的變化,而'svn revert -R'不帶參數會恢復所有內容。他不想恢復一切。 – janos

+0

我明白這個問題。 'xargs -r'可以在沒有輸入時抑制動作; 'grep .'在沒有任何東西時不會產生輸入(以及它怎麼可能?),所以在這個答案中建議的解決方法根本沒有幫助。 – tripleee

3

不漂亮,但希望有一個解決方法。

cmd = 'cd ' + checkout_dir + ' && ' + 
    'r=$(' svn_command + ' st | ' + 
     "awk '$2 !~ /^deploy/{print $2}' | tac) && " + 
    'test "$r" && ' + 
    svn_command + ' revert -R $r && ' + 
    svn_command + ' up -r ' + options.revision 

我不相信tac是必要的或有用的。出於效率和美學原因,我將第一個grep重構爲Awk腳本。

解決了一般「我xargs缺乏-r」的問題,該解決方案的要點是

stuff | xargs -r cmd 

轉換成

var=$(stuff) 
test "$var" && cmd $var 

未加引號$var只會工作,如果它不包含帶空格或其他意外的文件名;但是如果GNU擴展沒有受到同樣的問題,那麼它們就會成爲裸機。

1

-r對於xargs在OS X上不起作用,因爲它是GNU擴展。至於解決方法,你應該指定一些虛擬文件,它可以被xargs解析,或者當沒有參數時(可以在之前檢查)時不調用命令。

方法使用臨時文件(或任何其它的佔位符):

some_cmd ... | xargs svn revert $(mktemp) 

使用條件在外殼:

files=$(cd checkout_dir && ... | tac) 
if [ -n "$files" ]; then 
    echo $files | xargs && ... 
fi 

參見:xargsIgnore empty result for xargs

0

擊重新實現對付-r參數:

#!/bin/bash 
stdin=$(cat <&0) 
if [[ $1 == "-r" ]] || [[ $1 == "--no-run-if-empty" ]] 
then 
    # shift the arguments to get rid of the "-r" that is not valid on OSX 
    shift 
    # wc -l return some whitespaces, let's get rid of them with tr 
    linecount=$(echo $stdin | grep -v "^$" | wc -l | tr -d '[:space:]') 
    if [ "x$linecount" = "x0" ] 
    then 
     exit 0 
    fi 
fi 

# grep returns an error code for no matching lines, so only activate error checks from here 
set -e 
set -o pipefail 
echo $stdin | /usr/bin/xargs [email protected]