Làm cách nào để thay đổi đối số dòng lệnh trong Bash?


94

Có cách nào để thay đổi các đối số dòng lệnh trong tập lệnh Bash. Ví dụ: giả sử một tập lệnh Bash được gọi theo cách sau:

./foo arg1 arg2  

Có cách nào để thay đổi giá trị của arg1 trong script không? Nói, một cái gì đó như

$1="chintz"

Câu trả lời:


150

Bạn phải đặt lại tất cả các đối số. Để thay đổi ví dụ $3:

$ set -- "${@:1:2}" "new" "${@:4}"

Về cơ bản, bạn đặt tất cả các đối số thành giá trị hiện tại của chúng, ngoại trừ (các) đối số mà bạn muốn thay đổi. set --cũng được chỉ định bởi POSIX 7 .

Các "${@:1:2}"ký hiệu được mở rộng để hai (vì thế 2trong các ký hiệu) đối số vị trí bắt đầu từ bù đắp 1(tức $1). Nó là cách viết tắt "$1" "$2"trong trường hợp này, nhưng nó hữu ích hơn nhiều khi bạn muốn thay thế ví dụ "${17}".


1
Vì vậy, để đổi $ 3, tôi cũng phải đổi $ 1 và $ 2, phải không? Và thay đổi chúng thành gì? "Đặt lại" nghĩa là gì?
Sriram

Cảm ơn vì thủ thuật! Tôi gặp khó khăn khi sử dụng điều này cho các tên tệp có dấu cách nhúng. Đối với bất kỳ ai khác có thể gặp phải vấn đề đó, hãy thử đặt evallên hàng đầu về vấn đề này .
cxw

2
Điều này là ok khi bạn biết vị trí của tham số bạn muốn thay đổi. Điều gì sẽ xảy ra nếu bạn thực sự không biết nó và cần thay đổi nó một cách linh hoạt? Tôi đã thử với $ set - "$ {: 1: $ pivot}" nhưng nó không chấp nhận một biến ở đó.
Daniele Segato

1
Làm cách nào để làm điều tương tự từ bên trong một hàm? Giải pháp của bạn dường như không hoạt động khi được gọi từ bên trong một hàm.
Hashken

2
Bạn không thể thay đổi các tham số vị trí của tập lệnh từ bên trong một hàm - các đối số riêng của hàm ẩn chúng. Tuy nhiên, bạn có thể lưu trữ chúng trong một mảng và hoạt động trên đó.
thkala

23

Tối ưu hóa tính dễ đọc và khả năng bảo trì, bạn có thể tốt hơn nên chỉ định $1$2cho các biến có ý nghĩa hơn (tôi không biết input_filename = $1output_filename = $2hoặc điều gì đó) và sau đó ghi đè một trong các biến đó ( input_filename = 'chintz'), giữ nguyên đầu vào cho tập lệnh, trong trường hợp cần thiết ở nơi khác.


Tôi muốn một cách tiếp cận mà tôi có thể thay đổi chính một trong các đối số đầu vào. Tôi cần làm điều đó vì tôi muốn trả về một giá trị từ tập lệnh. Câu trả lời do thkala gợi ý đã hoạt động tốt. Cảm ơn vì sự trả lời!!!
Sriram

3
@Johnsyweb Đồng ý. Vì lợi ích dễ đọc, phương pháp của bạn là phương pháp tốt hơn.
Dss

1
"Bạn tốt hơn" luôn phụ thuộc vào trường hợp sử dụng, mà không được cung cấp.
Scott

2
@Scott 7 tuổi và nhiều kinh nghiệm hơn tôi khi viết câu trả lời này, tôi có xu hướng đồng ý với bạn.
Johnsyweb

Ví dụ trong đó điều này sẽ không hoạt động (ngoài việc sử dụng một cái gì đó như $ FIRST_PARAMETER): việc sử dụng và ý nghĩa của tham số tùy thuộc vào giá trị thực tế.
Igor Stoppa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.