2012-01-29 37 views
269

Tôi có một kịch bản đơn giản trong đó đối số đầu tiên được dành riêng cho tên tệp và tất cả đối số tùy chọn khác sẽ được chuyển đến các phần khác của tập lệnh.Xử lý tất cả các đối số ngoại trừ đoạn đầu tiên (trong tập lệnh bash)

Sử dụng Google tôi thấy this wiki, nhưng nó cung cấp một ví dụ chữ:

echo "${@: -1}" 

tôi không thể có được bất cứ điều gì khác để làm việc, như:

echo "${@:2}" 

hoặc

echo "${@:2,1}" 

Tôi nhận được "Thay thế xấu" từ thiết bị đầu cuối.

Sự cố là gì và làm cách nào để xử lý tất cả trừ đối số đầu tiên được chuyển đến tập lệnh bash?

+4

Để gọi cho bất kỳ ai khác nhầm lẫn, sai shebang được cung cấp khiến '" {@: 2} "' không hoạt động, đó là lý do tại sao câu trả lời đúng phù hợp ở trên. – Guvante

+2

Bạn vừa sử dụng shell mặc định, là dấu gạch ngang trên Ubuntu và nhiều Linux khác. Trong dấu gạch ngang "$ {@: -1}" được hiểu là: {tham số: -word} - Sử dụng Giá trị mặc định và sử dụng từ nếu tham số không được xác định hoặc null. Vì vậy, trong dấu gạch ngang "$ {@: -1}" kết quả chính xác giống như "$ @". Để sử dụng bash, hãy sử dụng dòng đầu tiên sau trong tập tin kịch bản: #!/Bin/bash – luart

Trả lời

376

Sử dụng này:

echo "${@:2}" 

Cú pháp sau đây:

echo "${*:2}" 

sẽ làm việc là tốt, nhưng không được khuyến khích, bởi vì như @Gordon đã giải thích, rằng việc sử dụng *, nó chạy tất cả các đối số với nhau như là một đối số duy nhất có dấu cách, trong khi @ duy trì sự ngắt quãng giữa chúng (ngay cả khi một số đối số của chúng tương ứng với nhau) trong không gian). Nó không tạo sự khác biệt với echo, nhưng nó quan trọng đối với nhiều lệnh khác.

+2

Tôi nhận ra rằng shebang của tôi rất tệ: '#!/Usr/bin/env sh' Đó là lý do tại sao tôi gặp vấn đề.Ví dụ bạn làm việc tốt, giống như ở trên được cung cấp, sau khi tôi loại bỏ rằng shebang – theta

+92

Sử dụng '" $ {@: 2} "' thay thế - bằng cách sử dụng '*' chạy tất cả các đối số với nhau như một đối số duy nhất với dấu cách, trong khi '@ 'bảo toàn các khoảng ngắt giữa chúng (ngay cả khi một số đối số có chứa khoảng trắng). Sự khác biệt không đáng chú ý với 'echo', nhưng nó quan trọng đối với nhiều thứ khác. –

+0

@GordonDavisson Toàn bộ điểm ở đây là chạy các đối số với nhau. Chúng tôi có truyền tên tập tin không, bạn sẽ chính xác. 'echo' là tha thứ đủ để ghép chúng cho bạn; các lệnh khác có thể không được tốt đẹp như vậy. Không chỉ sử dụng cái này hay cái kia: tìm hiểu sự khác biệt giữa '*' và '@', và khi nào thì sử dụng chúng. Bạn nên sử dụng chúng như nhau. Một ví dụ điển hình về thời điểm này sẽ là một vấn đề: nếu '$ 3' chứa một ngắt dòng (' \ n'), nó sẽ được thay thế bằng một khoảng trống, miễn là bạn có biến '$ IFS' mặc định. – Zenexer

121

Nếu bạn muốn có một giải pháp mà cũng làm việc trong /bin/sh thử

first_arg="$1" 
shift 
echo First argument: "$first_arg" 
echo Remaining arguments: "[email protected]" 

shift [n] thay đổi các tham số vị trí n lần. A shift đặt giá trị $1 thành giá trị $2, giá trị $2 thành giá trị $3 và cứ như vậy, giảm giá trị $# một giá trị.

+21

+1: Có thể bạn nên lưu $ 1 vào một biến trước khi dịch chuyển nó đi. –

+3

Đáng ngạc nhiên 'foo = shift' không làm những gì tôi mong đợi. –

+0

Tôi biết đây là cũ, nhưng hãy thử 'foo = $ (shift)' –

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