`\ Time`,` t \ ime` và` \ cd` thực sự làm gì? (vui vẻ với dấu gạch chéo ngược trong shell)


9

Trong khi thảo luận về sự khác biệt giữa /usr/bin/timevà vỏ (bash và zsh) tích hợp time, một người nào đó đã đề cập rằng người ta có thể sử dụng \timenhư một tốc ký để có được /usr/bin/time.

Đầu tiên nó có vẻ như một lối tắt ngây thơ tốt đẹp, nhưng sau đó một số câu hỏi được đưa ra:

  • Tại sao làm t\imeviệc quá?
  • Tại sao \cdthay đổi thư mục, mặc dù /usr/bin/cdkhông?

Vì vậy, rõ ràng, \fookhông tương đương với $(which foo). Câu hỏi là ngay bây giờ:

Là hành vi được quan sát của \foocả bash và zsh theo bất kỳ cách nào được bao phủ bởi định nghĩa POSIX của shell, và nếu vậy, tại sao nó lại hoạt động như vậy?


Chú thích 1: /usr/bin/cdlà, trên hệ thống của tôi,

#!/bin/sh
builtin cd "$@"

Đồng thời xem unix.stackexchange.com/questions/12762/ Nhật Lưu ý rằng lệnh \ được ghi lại cụ thể chức năng tcsh có nghĩa là bỏ qua các bí danh cho lệnh.
đơn giản

Câu trả lời:


14

t\imehoặc \cd(hay "tim"ehay 'cd'hay ${-##*}timehay ${-+time}và mọi sự kết hợp khác trích dẫn và mở rộng bạn có thể nghĩ rằng cuối cùng sẽ giải quyết cho timehay cd), đó là: một cách khác để ghi cdtime.

Tuy nhiên, điều đó cuối cùng sẽ giải quyết cdhoặc timesau một thời gian phân tích cú pháp và phân tích cú pháp shell. Đặc biệt, điều đó xảy ra rất lâu sau khi nhận dạng từ khóa shell và thay thế bí danh .

Vì vậy, tại thời điểm shell đang tìm kiếm từ khóa trong ngôn ngữ của nó, nó không được công nhận ti\metimetừ khóa shell. Vì vậy, một

ti\me echo test

sẽ được shell nhận ra là một lệnh đơn giản trái ngược với timetừ khóa theo sau là một lệnh đơn giản.

Sau đó, trích dẫn ti\mesẽ được xử lý (ở đây dấu gạch chéo ngược đang trích dẫn mký tự không cần trích dẫn, ký tự trích dẫn sẽ bị xóa, bạn nhận được time) và một time lệnh sẽ được tra cứu giống như bất kỳ lệnh nào khác (trong danh sách nội dung , các chức năng và các tập tin thực thi trong $PATH. Rất có thể sẽ /bin/timeở đây)

Đối với cd, không có cdtừ khóa trong ngôn ngữ shell, chỉ là một cdlệnh dựng sẵn (được ưu tiên hơn ngôn ngữ của bạn /usr/bin/cd). Tuy nhiên, nếu bạn định nghĩa một bí danh cho cd(như alias cd=pushd), tương tự một lần nữa. Vì việc thay thế bí danh được thực hiện từ rất sớm, trước khi xóa trích dẫn, nếu bạn có một bí danh cho cdvà không phải là một \cd(lưu ý rằng không có nhiều shell cho phép các bí danh có dấu gạch chéo ngược trong đó), sau đó bằng cách viết:

\cd dir

bạn đang đảm bảo cdbí danh của bạn không được thay thế.

Nói tóm lại, trích dẫn một tên lệnh hoặc bất kỳ phần nào của nó ngăn không cho nó được xem như là một từ khóa shell (từ khóa là điều thích while, for, if, {... timelà một từ khóa trong một số chỉ vỏ), và bỏ qua một bí danh bạn có thể cho nó .

Tuy nhiên, nó không bắt buộc lệnh đó phải giải quyết tệp thực thi $PATH, lệnh vẫn được tìm kiếm trước tiên trong số các hàm (mà bạn có thể làm việc bằng cách thực hiện command time cmd...) và nội dung (mà bạn có thể làm việc xung quanh bằng cách thực hiện env time cmd..., mặc dù tôi không biết một shell có timelệnh dựng sẵn ).

Lưu ý rằng trích dẫn cũng có thể có ảnh hưởng đến hành vi của các lệnh nội trú đặc biệt của typeset/ declare/ export/ local... gia đình ở một số vỏ. Xem các trích dẫn có cần thiết cho việc gán biến cục bộ không? để biết chi tiết.


Vì vậy, sự khác biệt giữa timecddẫn đến sự khác biệt trong hành vi được quan sát là đó timelà một từ khóacdlà một lệnh dựng sẵn ?
Jonas Schäfer

1
@JonasWielicki, đó timelà một từ khóa và cdkhông phải vậy. (và nếu bạn có bí danh cho cdhoặc time, đó sẽ là một vấn đề khác). Đó cdlà dựng sẵn hay không không có tỷ lệ mắc tại thời điểm này (liên quan đến ảnh hưởng của trích dẫn). Tuy nhiên, một số shell có một số nội dung nằm giữa các từ khóa và nội dung do việc phân tích cú pháp của chúng được thực hiện khác với các nội dung khác. Đó là trường hợp của export/ typeset/ declare. Tôi có lẽ nên thêm một số lưu ý về nó trong câu trả lời này.
Stéphane Chazelas
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.