Tại sao dấu gạch chéo ngược được bao gồm trong tập lệnh shell này?


21

Trong bản sao của conda.shtập lệnh, tôi thấy các dòng sau:

if [ -n "${_CE_CONDA}" ] && [ -n "${WINDIR+x}" ]; then
    SYSP=$(\dirname "${CONDA_EXE}")
else
    SYSP=$(\dirname "${CONDA_EXE}")
    SYSP=$(\dirname "${SYSP}")
fi

Tôi tò mò là tại sao có một dấu gạch chéo ở phía trước các dtrong dirname. Tôi không tin nó là cần thiết. Việc sử dụng dấu gạch chéo ngược này cũng xuất hiện ở những nơi khác trong tệp nguồn. Có một lý do để làm điều này mà tôi đang thiếu?


Câu trả lời:


30

Backslash sẽ ngăn chặn việc mở rộng bí danh, tức là nó thực thi lệnh gốc và đảm bảo rằng phiên bản bí danh không chạy. Các tập lệnh có thể vô tình chạy với mở rộng bí danh khi hệ thống đã được đặt shopt -s expand_aliases(chỉ BASH) hoặc nếu nó được thực thi bằng cách sử dụng source.

./conda.sh          # usually no alias expansion (unless `shopt -s expand_aliases` in BASH)
source ./conda.sh   # alias expansion
. ./conda.sh        # alias expansion

Một số sysadins muốn đặt dấu gạch chéo ngược vào mọi thứ như một biện pháp phòng ngừa chống lại tác dụng phụ của bí danh, chỉ trong trường hợp nó được đặt bí danh ở một nơi khác và bí danh được mở rộng như đã giải thích trước đây. Ví dụ: nếu hệ thống đã đặt điều này alias dirname='dirname -z'ở đâu đó và điều kiện cho phép mở rộng bí danh, thì một tập lệnh cố gắng gọi dirname sẽ không may gọi dirname -zthay, đó không phải là tập lệnh dự định.

Nếu chắc chắn rằng bí danh đó không tồn tại, chúng ta có thể xóa tất cả dấu gạch chéo ngược và nó sẽ hoạt động tốt.

Ngoài ra, người ta có thể sử dụng commandthay vì phiên bản dấu gạch chéo ngược để triệt tiêu bí danh. Do đó, thay vì \dirname, người ta có thể sử dụng command dirname, có thể trông dễ đọc hơn. (Đối với các lệnh tích hợp như cd, người ta nên sử dụng builtinthay thế). Tôi thích điều này thay vào đó, vì nó cũng bỏ qua chức năng có cùng tên cũng như bất kỳ bí danh nào.


1
Cũng đáng chú ý là unalias -a, trong đó loại bỏ tất cả các bí danh.
Centimane

19
@Centimane Có nhưng đảm bảo thực hiện \unalias -ađể ngăn chặn việc mở rộng bí danh
Ben C

Sysadmin cũng có thể đã viết /usr/bin/dirname?
RonJohn

@RonJohn Có, anh ấy có thể có trong trường hợp cụ thể này. Tuy nhiên, đối với một số chương trình, các bản phân phối khác nhau đặt chúng vào các thư mục khác nhau. Một ví dụ xuất hiện /bin/edtrong Ubuntu là /usr/bin/edtrên CentOS. Đưa vào một đường dẫn đầy đủ làm cho tập lệnh ít di động hơn.
doneal24

@ doneal24 Điều gì về một cái gì đó như thế DIRNAME=$(which dirname), vì whichkhông thấy bí danh?
RonJohn

20

Nếu conda.shmột tệp có nghĩa là có nguồn gốc, thì dấu gạch chéo ngược là để bỏ qua các bí danh. Bash thường vô hiệu hóa mở rộng bí danh để thực thi tập lệnh, nhưng đối với các tệp có nguồn gốc, có thể chạy trong các vỏ tương tác, thì không phải vậy. Vì vậy, chỉ dirnamecó thể chạy một bí danh có tên dirname, nhưng \dirnamesẽ bỏ qua việc mở rộng bí danh và chạy một chức năng hoặc lệnh có tên dirname. (Tuy nhiên, không chỉ dấu gạch chéo ngược, bất kỳ trích dẫn nào cũng được.)


5
Hoặc command dirname.
Kusalananda

7
( \command dirname, chỉ trong trường hợp ai đó cũng tạo bí danh command.): |
muru

Tại sao nó bỏ qua bí danh? Là chức năng này là một trường hợp đặc biệt của một cái gì đó, hoặc nó đã phải được mã hóa cứng thành bash (tức là một hack)?
extremeaxe5

@ extremeaxe5 bash không thực hiện mở rộng bí danh nếu (bất kỳ phần nào) của từ được trích dẫn.
muru

1
@ extremeaxe5 nếu bạn hỏi tại sao tính năng này tồn tại, tôi không biết. Đó là trong tiêu chuẩn POSIX tuy nhiên: "tên lệnh từ [...] sẽ được kiểm tra để xác định xem nó là một thể viện chứng , tên bí danh hợp lệ"
muru
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.