Giải thích lệnh shell: shift $ (($ optind - 1))


30

Tôi không phải là một người Linux nhưng bị mắc kẹt trong một số Script mà tôi phải đọc cho Dự án của mình. Vì vậy, bất cứ ai có thể giúp tôi những gì lệnh này đang làm?

shift $(($optind - 1))

3
Như đã lưu ý bên dưới, OPTIND phải ở dạng chữ hoa và '$' bên trong dấu ngoặc đơn là tùy chọn.
DarkHeart

Câu trả lời:


49

shift $((OPTIND-1))(lưu ý OPTINDlà chữ hoa) thường được tìm thấy ngay sau một getopts whilevòng lặp. $OPTINDlà số lượng tùy chọn được tìm thấy bởi getopts.

Như pauljohn32 đề cập trong các ý kiến, nói đúng ra, OPTINDđưa ra vị trí của đối số dòng lệnh tiếp theo .

Từ tài liệu tham khảo GNU Bash :

tên optopts getopts [args]

getoptsđược sử dụng bởi các kịch bản shell để phân tích các tham số vị trí. optstringchứa các ký tự tùy chọn được nhận dạng; nếu một ký tự được theo sau bởi dấu hai chấm, tùy chọn dự kiến ​​sẽ có một đối số, nên được phân tách khỏi nó bằng khoảng trắng. Dấu hai chấm (':') và dấu hỏi ('?') Có thể không được sử dụng làm ký tự tùy chọn. Mỗi lần nó được gọi, getoptsđặt tùy chọn tiếp theo vào tên biến shell, khởi tạo namenếu nó không tồn tại và chỉ mục của đối số tiếp theo sẽ được xử lý thành biến OPTIND. OPTINDđược khởi tạo thành 1 mỗi lần shell hoặc script shell được gọi. Khi một tùy chọn yêu cầu một đối số, hãy đặt các đối số đó vào biến OPTARG. Vỏ không thiết lập lạiOPTIND tự động; nó phải được đặt lại thủ công giữa nhiều lệnh gọi getoptstrong cùng một lệnh gọi shell nếu sử dụng một bộ tham số mới.

Khi kết thúc các tùy chọn gặp phải, getoptsthoát với giá trị trả về lớn hơn 0. OPTINDđược đặt thành chỉ mục của đối số không phải tùy chọn đầu tiên và tên được đặt thành '?'.

getoptsthường phân tích cú pháp các tham số vị trí, nhưng nếu có nhiều đối số được đưa vào args, getoptsthay vào đó sẽ phân tích cú pháp các tham số đó.

shift n
loại bỏ n chuỗi khỏi danh sách tham số vị trí. Do đó, shift $((OPTIND-1))loại bỏ tất cả các tùy chọn đã được phân tích cú pháp getoptskhỏi danh sách tham số, và vì vậy sau thời điểm đó, $1sẽ tham chiếu đến đối số không phải tùy chọn đầu tiên được truyền cho tập lệnh.

Cập nhật

Như mikeerv đề cập trong bình luận, shift $((OPTIND-1))có thể không an toàn. Để ngăn chặn việc chia tách từ không mong muốn, v.v., tất cả các mở rộng tham số nên được trích dẫn kép. Vì vậy, hình thức an toàn cho lệnh là

shift "$((OPTIND-1))"


Có vẻ như điều này sẽ chỉ hoạt động đúng nếu tất cả các tùy chọn xảy ra trước bất kỳ đối số vị trí còn lại nào. Chính xác?
Steve Jorgensen

@SteveJorgensen: Vâng, đúng vậy. OTOH, đặt các tùy chọn sau khi đối số không tùy chọn đi ngược lại quy ước sh / bash. Nói chung, các đối số đầu tiên không bắt đầu bằng dấu gạch ngang biểu thị sự kết thúc của các tùy chọn và bất kỳ đối số tiếp theo nào bắt đầu bằng dấu gạch ngang không được coi là tùy chọn. Không phải tất cả các chương trình tuân thủ quy ước này, nhưng nó làm cho cuộc sống đơn giản hơn rất nhiều nếu bạn làm. :)
PM 2Ring

@SteveJorgensen: (tiếp) Chủ đề này được thảo luận ngắn gọn trong Tại sao một số tiện ích phân tích toán hạng trước các tùy chọn? . Như nhận xét của Gilles đối với câu trả lời của Celada, một số chương trình (như find) có thể trông giống như họ cho phép các tùy chọn sau khi không có tùy chọn, nhưng họ không: họ có các toán hạng bắt đầu bằng dấu gạch ngang.
PM 2Ring

Cảm ơn thông tin đó (& bản chỉnh sửa) @mosvy Điều đó khá bất thường IFS, nhưng tốt hơn hết là an toàn hơn là xin lỗi. ;)
PM 2Ring

@roaima nếu IFS=0123456789, shift $((OPTIND-1))(không có dấu ngoặc kép) sẽ biến thành shift ""sẽ bị bỏ qua âm thầm (in ksh) hoặc tạo ra lỗi (trong bashdash).
mosvy

8

$((...))chỉ tính toán công cụ. Trong trường hợp của bạn, nó nhận giá trị $optintvà cơ số 1.

shiftloại bỏ các tham số vị trí. Trong trường hợp của bạn, nó loại bỏ optint-1các tham số.

Để biết thêm thông tin có một cái nhìn tại help getopts, help shift, nhìn vào man bashđể "mở rộng số học", và đặc biệt là google cho getopts.

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.