$ {0% / *} trong shell script làm gì?


17

Xin lỗi nếu đây là một câu hỏi ngu ngốc, nhưng tôi đã tìm kiếm về nó mà không thành công.

Chính xác thì dòng thứ hai làm gì?

#!/bin/sh
cd ${0%/*} || exit 1

Tôi biết đầu tiên là shebang, thứ hai cố gắng thay đổi thư mục nhưng phần khó hiểu là ${0%/*}.

Bạn có thể vui lòng giải thích cho tôi dòng thứ hai?


2
Như Andrea đã giải thích trong một câu trả lời, $ {0% / *} dịch sang đường dẫn thư mục có tiền tố là tên tập lệnh trong khi gọi nó. Một cách khác là sử dụng dirnamelệnh tích hợp như$(dirname $0)
luôn luôn học

@alwayslearning: Phiên bản shell và shell nào bạn đang sử dụng dirnameđược tích hợp sẵn? Nó chắc chắn không có trong Bash v4.3.11, đây là lớp vỏ mặc định trong Ubuntu Trusty.
David Foerster

Tôi xin lỗi vì sự nhầm lẫn, chỉ cần kiểm tra đó dirnamekhông phải là một vỏ tích hợp.
luôn luôn học

Câu trả lời:


27

${0}là đối số đầu tiên của tập lệnh, tức là tên tập lệnh hoặc đường dẫn. Nếu bạn khởi chạy tập lệnh của mình dưới dạng path/to/script.sh, thì đó ${0}sẽ chính xác là chuỗi đó : path/to/script.sh.

Phần %/*sửa đổi giá trị của ${0}. Nó có nghĩa là: lấy tất cả các ký tự cho đến khi /theo sau là một tên tệp. Trong ví dụ trên, ${0%/*}sẽ được path/to.

Bạn có thể thấy nó hoạt động trên vỏ của bạn:

$ x=path/to/script.sh
$ echo "${x%/*}"
path/to

Sh hỗ trợ nhiều loại "thay thế tham số" khác. Ví dụ, đây là cách lấy tên tệp thay vì đường dẫn:

$ echo "${x##*/}"
script.sh

Nói chung, %%%hậu tố dải, trong khi ###tiền tố dải. Bạn có thể đọc thêm về sự thay thế tham số .


2
Điều này "|| exit 1" dường như là không cần thiết: nếu bây giờ sẽ thay đổi dir $? bằng 1.
Josef Klimuk

2
Thật tuyệt khi đề cập đến cấu trúc được ghi lại dưới dạng "Xóa mẫu tiền tố / hậu tố phù hợp" trong hướng dẫn. Ngoài ra, một cách hay để nhớ đó là # là shift 3 ( bên trái của $),% là shift 5 ( bên phải của $), ít nhất là trên bàn phím Hoa Kỳ.
chexum

1
@JosefKlimuk: || exit 1 thể cần thiết vì cdcó thể thoát với trạng thái 2, không phải 1, do lỗi. Tuy nhiên tôi đồng ý rằng nó không hữu ích lắm (thường các chương trình không quan tâm đến các trạng thái thoát cụ thể). Có lẽ đây là một phần của một kịch bản lớn hơn?
Andrea Corbellini

1
@AndreaCorbellini Chắc chắn đúng. Khá nhiều cách duy nhất nó có thể sử dụng hữu ích là một phần của tập lệnh lớn hơn. Một tập lệnh chỉ thay đổi thư mục hiện tại không có hiệu lực, bởi vì nó chỉ ảnh hưởng đến trình bao chạy tập lệnh đó. Quá trình cha mẹ không bao giờ nhìn thấy nó.
hvd
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.