Từ hướng dẫn Bash ( man bash
):
Bộ chỉ huy thay thế
Thay thế lệnh cho phép đầu ra của một lệnh để thay thế
tên lệnh. Có hai hình thức:
$ (lệnh)
hoặc là
`lệnh`
Bash thực hiện việc mở rộng bằng cách thực hiện lệnh trong một lớp con
môi trường và thay thế lệnh thay thế bằng tiêu chuẩn
đầu ra của lệnh, với bất kỳ dòng mới nào bị xóa. Nhúng
dòng mới không bị xóa, nhưng chúng có thể bị xóa trong từ
chia tách. Lệnh thay thế $ (tệp cat) có thể được thay thế bằng
tương đương nhưng nhanh hơn $ (<file).
(Điều này đúng cho tất cả Bourne giống như vỏ, tức là sh
, ksh
, zsh
, bash
vv, và zsh
cũng có thể dữ liệu chụp với các nhân vật NUL nhúng theo cách này)
Lệnh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
sẽ gán tên của thư mục chứa tập lệnh (đồng thời thay đổi tất cả dấu gạch chéo ngược thành dấu gạch chéo về phía trước) cho biến basedir
. Bất kỳ lỗi, cảnh báo hoặc thông báo chẩn đoán nào khác được đưa ra luồng lỗi tiêu chuẩn sẽ vẫn được hiển thị trên thiết bị đầu cuối ( $(...)
chỉ chụp đầu ra tiêu chuẩn của lệnh).
Shell sẽ bắt đầu bằng cách thực hiện thay thế lệnh trong cùng:
echo "$0" | sed -e 's,\\,/,g'
Đầu ra của chuỗi đó sẽ được cung cấp dưới dạng một chuỗi dirname
và đầu ra của chuỗi đó sẽ được gán cho biến basedir
.
Có hai dấu ngoặc kép để đảm bảo rằng sẽ không có phân tách từ hoặc tên tệp nào được thực hiện, nếu không bạn có thể thấy rằng tập lệnh thất bại hoặc tạo đầu ra lạ khi $0
(tên của tập lệnh bao gồm đường dẫn được sử dụng để thực thi nó) chứa một khoảng trắng ký tự hoặc một tên tập tin ký tự (chẳng hạn như ?
hoặc *
).
Nói chung, nên luôn luôn trích dẫn mở rộng (mở rộng biến, thay thế lệnh và mở rộng số học). Xem câu hỏi này và câu trả lời của nó cho một lời giải thích tuyệt vời về lý do tại sao đây là một ý tưởng tốt.
Nếu tập lệnh được thực thi như
$ /usr/local/bin/script.sh
sau đó basedir
sẽ nhận được giá trị của /usr/local/bin
.
Hoặc, trên Cygwin:
$ bash c:\\Users\\Me\\script.sh
sau đó basedir
sẽ nhận được giá trị của c:/Users/Me
. Dấu gạch chéo kép trên dòng lệnh trong trường hợp này chỉ là để thoát khỏi dấu gạch chéo ngược đơn từ trình bao. Giá trị thực tế của $0
là c:\Users\Me\script.sh
.
Một cách khác để làm điều tương tự mà không sử dụng dirname
, echo
và sed
sẽ là
basedir="${0//\\//}"
basedir="${basedir%/*}"
man bash
và tìm kiếm thay thế Lệnh