2015-05-06 17 views
5

Tôi đang viết một tập lệnh bash có một số tham số tùy chọn. Tôi muốn dịch chúng và chuyển chúng sang một kịch bản khác. Tuy nhiên, tôi đang gặp khó khăn khi chuyển các tham số tùy chọn một cách duyên dáng.Làm cách nào để chuyển các tham số tùy chọn cho một lệnh khác trong tập lệnh bash?

Dưới đây là một phác thảo của những gì tôi quản lý để làm việc trong giả:

a.sh:

if arg1 in arguments; then 
    firstArg="first argument" 
fi 
if arg2 in arguments; then 
    secondArg="second argument" 
fi 

./b.sh $firstArg $secondArg "default argument" 

Lưu ý các khoảng trống trong các đối số.

b.sh:

for arg in "[email protected]" 
do 
    echo $arg 
done 

Tôi muốn gọi b.sh, tùy chọn với firstArgsecondArg và một đối số mặc định như vậy:

./b.sh $firstArg $secondArg "default argument" 

Vấn đề ở đây là nếu $firstArg hoặc $secondArg là các chuỗi có dấu cách, chúng sẽ được biểu diễn dưới dạng nhiều đối số và đầu ra sẽ có dạng như sau:

first 
argument 
second 
argument 
default argument 

Được rồi, đó là dễ dàng để sửa chữa, chúng ta hãy nắm bắt được toàn bộ chuỗi của các đối số bằng cách thêm dấu ngoặc kép quanh nó như vậy:

./b.sh "$firstArg" "$secondArg" "defaultArg" 

Vấn đề là nếu, ví dụ, firstArg không được thiết lập, nó kết quả trong một dòng trống (vì nó sẽ giải thích "" như một tham số), do đó sản lượng sẽ được cái gì đó như:

(blank line here) 
second argument 
defaultArg 

tôi cũng đã cố gắng xây dựng một chuỗi và đi qua nó để kịch bản shell, nhưng nó không dường như hoạt động theo cách đó (int erprets toàn bộ chuỗi như một đối số, ngay cả khi tôi thêm riêng biệt các đối số với dấu ngoặc kép).

Lưu ý rằng hãy gọi b.sh từ dòng lệnh của tôi với các đối số được trích dẫn hoạt động tốt. Có cách nào để bắt chước cách hoạt động này từ bên trong một tập lệnh bash không?

+1

Ngoài: Chỉ vì tôi sao chép dẫn của bạn và sử dụng 'mở rộng .sh' trên các tệp thực thi (tức là, các tệp có quyền + x đối với một cuộc gọi gia đình 'execv()' sẽ thành công) không có nghĩa đó là một ý tưởng hay. Nói chung, các lệnh trong UNIX không nên có bất kỳ phần mở rộng nào, cho dù chúng được cung cấp thông qua một kịch bản lệnh shell, một kịch bản Python, một nhị phân đã biên dịch, v.v. –

+0

Bạn có thể làm rõ một cách rõ ràng xem mã này có sử dụng '#!/bin/sh' hoặc '#!/bin/bash'? –

+0

Tôi đang sử dụng bash. – Andrew

Trả lời

7

Nếu bạn có nghĩa là muốn sao chép tất cả các đối số được đưa ra, nhưng thêm một người nữa:

# this works in any POSIX shell 
./b.sh "[email protected]" defaultArg 

Cách khác, để vượt qua một cách rõ ràng firstArgsecondArg, nhưng chỉ nếu chúng tồn tại (lưu ý rằng bộ-to-an-rỗng đếm -giá trị là "hiện có" ở đây):

# this works in any POSIX shell 
./b.sh ${firstArg+"$firstArg"} ${secondArg+"$secondArg"} defaultArg 

Nếu bạn muốn đối xử với set-to-an-trống-giá trị như không tồn tại:

# this works in any POSIX shell 
./b.sh ${firstArg:+"$firstArg"} ${secondArg:+"$secondArg"} defaultArg 

Một cách tiếp cận thay thế là để xây dựng một mảng các đối số:

# this requires bash or another shell with arrays and append syntax 
# be sure any script using this starts with #!/bin/bash 
b_args=() 
[[ $firstArg ]] && b_args+=("$firstArg") 
[[ $secondArg ]] && b_args+=("$secondArg") 
b_args+=("default argument") 
./b.sh "${b_args[@]}" 

Nếu bạn muốn một cái gì đó với sự linh hoạt giống như phương pháp mảng, nhưng không có vấn đề tương thích, định nghĩa một hàm; bên trong nó, bạn có thể yên tâm ghi đè "[email protected]" mà không ảnh hưởng phần còn lại của kịch bản:

runB() { 
    set -- 
    [ -n "$firstArg" ] && set -- "[email protected]" "$firstArg" 
    [ -n "$secondArg" ] && set -- "[email protected]" "$secondArg" 
    ./b.sh "[email protected]" "default argument" 
} 
+0

Không phải là trích dẫn '" $ @ "' sai ở đây? Nó sẽ không phải là chủ đề của tách từ sau đó nữa .. phải không? – hek2mgl

+0

@ hek2mgl, eh? Không, tách từ rõ ràng là không muốn ở đây. –

+0

Câu trả lời hay! Tôi không có câu hỏi chính xác khi đăng nhận xét. – hek2mgl

1

Sử dụng một mảng:

args=() 

if [ ... ]; then 
    args+=("first argument") 
fi 

if [ ... ]; then 
    args+=("second argument") 
fi 

./b.sh "${args[@]}" "default argument" 
+0

@EtanReisner Không phải vì trong ví dụ của OP '$ firstArg' có thể không được đặt ở tất cả (nhưng được sử dụng) nhưng nếu nó được đặt, nó sẽ được đặt thành chuỗi ký tự (giống như đoạn mã trên). –

+0

Ah, tôi cho rằng đó là trình giữ chỗ cho các đối số đầu tiên và thứ hai thực tế chứ không phải chuỗi ký tự (trong OP và cũng ở đây) và kể từ khi bạn bỏ qua các thử nghiệm thực tế trên các đối số, tôi đã không điền vào. không có vấn đề đó, nhưng như bằng văn bản này cũng chỉ là một nửa của một giải pháp (và tôi nghĩ rằng không hoàn toàn giải quyết nó một cách chính xác). –

+0

Tôi nhận được nơi bạn đang đến từ trên này. Tuy nhiên, OP cho './b.sh" $ firstArg "" $ secondArg "" defaultArg "' như là một giải pháp có thể (và mô tả lỗi duy nhất của nó khi truyền qua các đối số rỗng hơn là không cung cấp chúng) cho biết rằng việc sử dụng của các chuỗi ký tự '" đối số đầu tiên "' và '" đối số thứ hai "' chỉ là sloppiness trước đó trong câu hỏi. –

Các vấn đề liên quan