2013-07-01 51 views
12

Mã cho trang web của tôi sử dụng đoạn mã này để triển khai tự động trên máy chủ (Ubuntu).Bỏ qua kết quả trống cho xargs trong Mac OS X

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

gì lệnh này làm nó cd vào thư mục kiểm tra là, chạy svn status, và sau đó trích xuất tên tập tin ($2), loại bỏ các deploy thư mục và tất cả các file của mình từ danh sách (I don 't muốn hoàn nguyên nó). Nếu không có đối số, nó không chạy lệnh svn revert, nếu không nó sẽ thực hiện.

Rất tiếc, xargs -r không hoạt động trên máy của tôi (Mac OS X 10.8). Vì vậy, tôi bị mắc kẹt ở đây, bất cứ ai có thể giúp đỡ?

+1

Đó có phải là mã Python hay không? – tripleee

Trả lời

4

Thật vậy, việc triển khai BSD xargs không có cờ -r (--no-run-if-empty). Phiên bản GNU trong Linux có nó.

Dưới đây là một cách để làm việc xung quanh vấn đề này theo một cách mà các công trình trong cả Linux và BSD:

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

Các grep ... || echo : ở giữa sẽ tạo ra một dòng với một : trong nó trong trường hợp đầu ra của grep trống. Đó là một chút bẩn, vì xargs sẽ vẫn chạy lệnh svn revert :. Nếu kho lưu trữ của bạn không chứa tệp : thì điều này sẽ không có hiệu lực, vì vậy nó có thể chấp nhận được. : có thể là bất cứ điều gì khác, miễn là không có tệp như vậy trong kho lưu trữ của bạn.

Cuối cùng, như @tripleee chỉ ra, grep ... || echo : phải được kèm theo trong vòng (...), bởi vì:

các || có độ ưu tiên cao hơn |, và do đó chấm dứt (đầu tiên) đường dẫn.

Mã của bạn trông giống như một chuỗi Python. Nó sẽ dễ đọc hơn theo cách này:

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) 

tôi đã thực hiện một số thay đổi ban đầu của bạn:

  • Moved logic của grep bên awk, như @tripleee gợi ý. Chú ý rằng kể từ khi grep hack được không cần thiết nữa, đó cũng là không cần phải quấn trong (...)
  • bỏ tac, như tôi không nhìn thấy điểm trong đó
  • bỏ -R từ svn revert, bởi vì tôi don Không nghĩ rằng bạn cần nó
+0

Điều này giúp ích gì? Vấn đề không phải là dòng trống, đó là các dòng * no *. – tripleee

+0

@tripleee Anh ta muốn sử dụng cờ '-r' của' xargs', nhưng không thể, bởi vì nó không tồn tại trong BSD. Anh ta muốn sử dụng cờ vì anh ta không muốn chạy 'svn revert -R' mà không có đối số. 'svn revert -R something' sẽ hoàn nguyên các thay đổi trong" cái gì đó "chỉ, và' svn revert -R' mà không có đối số sẽ hoàn nguyên mọi thứ. Anh ta không muốn hoàn nguyên mọi thứ. – janos

+0

Tôi hiểu câu hỏi. 'xargs -r' rất hữu ích để ngăn chặn hành động khi không có đầu vào; 'grep .' không có gì để tạo đầu vào khi không có gì (và nó có thể như thế nào?), do đó, cách giải quyết được đề xuất trong câu trả lời này không giúp gì cả. – tripleee

3

Không đẹp, nhưng hy vọng một cách giải quyết khác.

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 

Tôi không tin rằng tac là cần thiết hoặc hữu ích.Tôi đã tái cấu trúc grep đầu tiên thành kịch bản Awk vì lý do hiệu quả và thẩm mỹ.

Để giải quyết chung "của tôi xargs thiếu -r" vấn đề, ý chính của giải pháp là chuyển đổi

stuff | xargs -r cmd 

vào

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

Các thể viện chứng $var sẽ chỉ làm việc nếu nó không chứa tên tập tin có dấu cách hoặc bất ngờ khác; nhưng sau đó xương trần xargs mà không có phần mở rộng GNU bị cùng một vấn đề.

1

-r cho xargs không hoạt động trên OS X, vì đây là phần mở rộng của GNU. Đối với cách giải quyết khác, bạn nên chỉ định một số tệp giả có thể được phân tích bằng xargs hoặc để không gọi lệnh khi không có đối số (có thể được kiểm tra trước đó).

Phương pháp sử dụng tập tin tạm thời (hoặc bất kỳ giữ chỗ khác):

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

Sử dụng điều kiện trong vỏ:

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

Xem thêm: Ignore empty result for xargs

0

Bash reimplementation của xargs đối phó với -r đối số:

#!/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]