2010-09-28 27 views
369

Giả sử tôi đã định nghĩa hàm abc() sẽ xử lý tất cả logic liên quan đến việc phân tích các đối số được truyền cho tập lệnh của tôi.Làm thế nào để vượt qua tất cả các đối số thông qua kịch bản bash của tôi đến một chức năng của tôi?

Làm cách nào để vượt qua tất cả các đối số mà tập lệnh bash của tôi đã nhận được? Số lượng các params là biến, vì vậy tôi không thể chỉ hardcode đối số được truyền như thế này:

abc $1 $2 $3 $4 

chỉnh sửa: Hơn thế nữa, có cách nào cho chức năng của tôi để có thể truy cập đến các biến các đối số kịch bản?

+5

bản sao có thể có của [Vượt qua tất cả các đối số từ tập lệnh Bash sang một lệnh khác] (http://stackoverflow.com/questions/3190818/pass-all-arguments-from-bash-script-to-another-command) – Urda

Trả lời

599

peeve vật nuôi: khi sử dụng [email protected], bạn nên (hầu như) luôn luôn đặt nó trong dấu nháy kép để tránh misparsing tranh luận với các không gian trong đó:

abc "[email protected]" 
+8

Điều đó không chỉ làm việc cho 1 đối số?Nếu bạn có nhiều đối số, nó sẽ không được chuyển thành một chuỗi dài? – hepcat72

+58

@ hepcat72 No. '" $ * "' hoạt động theo cách bạn mô tả, nhưng '" $ @ "' được xử lý như một trường hợp đặc biệt bởi trình bao. Từ [hướng dẫn tham khảo bash, phần thông số đặc biệt] (http://www.gnu.org/software/bash/manual/bash.html#Special-Parameters): '@ ... Mở rộng đến các tham số vị trí, bắt đầu từ một. Khi mở rộng xảy ra trong dấu ngoặc kép, mỗi tham số sẽ mở rộng thành một từ riêng biệt. Tức là, "$ @" tương đương với "$ 1" "$ 2" ... ' –

+3

Nếu bạn muốn chuyển * tất cả trừ các đối số * đầu tiên, trước tiên bạn có thể sử dụng 'shift' để" tiêu thụ "đối số đầu tiên, sau đó vượt qua' $ @ ', danh sách các đối số còn lại cho lệnh khác – rubo77

14
abc "[email protected]" 

[email protected] đại diện cho tất cả các tham số cho tập lệnh bash của bạn.

+13

Nếu bạn không trích dẫn '$ @', bạn sẽ mất từ ​​phân tách chính xác – Daenyth

38

Dưới đây là một kịch bản đơn giản:

#!/bin/sh 

args=("[email protected]") 

echo Number of arguments: $# 
echo 1st argument: ${args[0]} 
echo 2nd argument: ${args[1]} 

$# là số đối số nhận được kịch bản. Tôi tìm thấy dễ dàng hơn để truy cập chúng bằng cách sử dụng một mảng: dòng args=("[email protected]") đặt tất cả các đối số trong mảng args. Để truy cập chúng, hãy sử dụng ${args[index]}.

+3

nó sẽ là '$ {args [0]}' cho đối số đầu tiên: o – King

+0

Cảm ơn bạn. Rất hữu ích! –

+3

Lợi ích nào khi chuyển $ @ vào một mảng cung cấp hơn là chỉ gọi các đối số theo chỉ mục (ví dụ: $ 1)? – Kingand

109

tôi cần một sự thay đổi về vấn đề này, mà tôi mong đợi sẽ có ích cho người khác:

function diffs() { 
     diff "${@:3}" <(sort "$1") <(sort "$2") 
} 

các "${@:3}" phần nghĩa là tất cả các thành viên của mảng bắt đầu từ 3. Vì vậy chức năng này thực hiện một diff được sắp xếp bằng cách đi qua hai đối số đầu tiên diff qua sắp xếp và sau đó đi qua tất cả một khác rguments để khác biệt, vì vậy bạn có thể gọi nó tương tự như khác:

diffs file1 file2 [other diff args, e.g. -y] 
+10

'' $ {@: 3} "' cũng rất tuyệt khi bạn có các tập lệnh có đối số, nhưng cũng có thể chuyển đối số cho các tập lệnh khác mà chúng gọi. Ví dụ, một dự án của tôi có một kịch bản để dễ dàng chạy chương trình, với một đối số cho lớp chính để sử dụng. Sau đó, '" $ {@: 2} "' có thể được sử dụng để chuyển các đối số còn lại cho điểm vào đó. – Kat

+4

@Kat đã đề cập đến điều này, nhưng để làm rõ (trong trường hợp bạn vẫn còn nghi ngờ): 'lệnh" $ @ "' tương đương với 'lệnh $ 1" $ {@: 2} "'. – Mahn

19

Điều đáng nói là bạn có thể chỉ định phạm vi đối số với cú pháp này.

function example() { 
    echo "line1 ${@:1:1}"; #First argument 
    echo "line2 ${@:2:1}"; #Second argument 
    echo "line3 ${@:3}"; #Third argument onwards 
} 

Tôi chưa từng thấy nó đề cập đến.

+1

Bạn chỉ có thể sử dụng '$ 1',' $ 2', ... cho hai số đầu tiên – rubo77

+0

@ rubo77 Tôi đã sửa lại từ ngữ của câu trả lời của tôi để bao gồm "phạm vi" cảm ơn. – robstarbuck

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