Tại sao thay thế lịch sử bash vẫn được bật theo mặc định? [đóng cửa]


17

Có ai biết tại sao bash vẫn có tính năng thay thế lịch sử được bật theo mặc định không? My .bashrcđã bao gồm set +Hnhiều năm nhưng một số người khác vẫn bị cắn bởi tính năng này.

Cho rằng khá nhiều người đang sử dụng các thiết bị đầu cuối có tính năng sao chép bash được biên dịch bằng readlinethư viện thay thế lịch sử được bật theo mặc định chỉ trong các vỏ tương tác, có thực sự có lý do nào để có tính năng này không? Không có đoạn script hiện tại nào bị phá vỡ ngay cả khi điều này bị tắt theo mặc định cho tất cả các shell.

Hãy thử điều này nếu bạn không biết tại sao thay thế lịch sử bị hỏng:

$ set +H # disable feature history substitution
$ echo "WTF???!?!!?"
WTF???!?!!?
$ set -H # enable feature history substitution
$ echo "WTF???!?!!?"
echo WTF???echo WTF???!?!!?
WTF???echo WTF???!?!!?

(Rõ ràng tính năng này có vấn đề lớn nếu nó bị tắt theo mặc định cho tất cả các tập lệnh và một tính năng tồn tại để xác minh kết quả trước khi thực hiện : shopt -s histverify.)

Xem thêm:


16
Bạn dường như nghĩ rằng mọi người không sử dụng thay thế lịch sử. Tôi dùng nó mỗi ngày. Tôi tìm đến nhanh hơn để làm theo ls -l foo/bar/baz/weeble.cppvới less !$hơn thu hồi lệnh và chỉnh sửa nó.
Martin Bonner hỗ trợ Monica

2
@MartinBonner Vì vậy, bạn có thể kích hoạt nó. Câu hỏi là về lý do tại sao nó được bật theo mặc định , không phải tại sao nó vẫn tồn tại.
Barmar

5
@Barmar: Chắc chắn rồi. Nhưng quan điểm của tôi là thách thức giả định rằng câu hỏi được đưa ra.
Martin Bonner hỗ trợ Monica

5
Nếu chúng tôi tuân theo lý luận của bạn, mọi thứ yêu cầu thoát hoặc trích dẫn sẽ bị tắt theo mặc định. Tại sao tôi cần thoát hoặc trích dẫn một URL có chứa &? Tại sao tôi cần phải thoát hoặc trích dẫn một tên tệp có chứa một ?? Có những UI cho những người nghĩ rằng đây là một vấn đề.
jcaron

3
Tôi sử dụng !$nhiều lần trong ngày và !!cũng khá thường xuyên. Tôi phải thừa nhận rằng tôi không sử dụng các thay thế lịch sử khác nhiều như vậy, nhưng tôi chắc chắn sẽ không vui nếu hành vi mặc định của vỏ tôi đã sử dụng trong nhiều năm đột nhiên thay đổi.
jcaron

Câu trả lời:


32

Nếu bạn đã quen thuộc bash, thì việc xử lý các mô hình thay thế lịch sử sẽ không có nhiều khả năng cắn bạn hơn là xử lý bất kỳ nhân vật nào đặc biệt đối với lớp vỏ này. Tuy nhiên, nếu một người không quen thuộc với trình bao hoặc chỉ không bao giờ sử dụng các tính năng thay thế lịch sử của nó, thì rõ ràng sẽ rất bất ngờ khi các chuỗi dường như vô hại không được trích dẫn hoặc trích dẫn kép kích hoạt nó.

Trong một vỏ tương tác với các thay thế lịch sử được kích hoạt, !nhân vật đặc biệt theo cách tương tự như $nhân vật là đặc biệt, tức là ở mọi nơi trừ khi thoát ra bằng \hoặc trong các chuỗi trích dẫn đơn.

Trái ngược với $thông qua, sự thay thế lịch sử không mở rộng trong các tài liệu ở đây và vì chúng được định hướng theo dòng, nên chúng sẽ xảy ra trên các dòng trong đó sự thay thế nằm trong bối cảnh không được trích dẫn hoặc bối cảnh được trích dẫn kép (trong dòng đó khi được quét riêng) . Xem báo cáo lỗi này để biết thêm .

Thay thế lịch sử bị vô hiệu hóa trong trình bao không tương tác (tập lệnh) vì không cần khả năng lịch sử lệnh của trình bao, không phải vì tính năng này có "vấn đề lớn". Trong một tập lệnh, lưu mọi lệnh $HISTFILEkhông có ý nghĩa và thay thế lịch sử tương tự không phải là điều bạn muốn dựa vào trong tập lệnh.

Việc có nên kích hoạt theo mặc định hay không trong các vỏ tương tác có thể được tranh luận (mặc dù tôi không hoàn toàn tin rằng một cuộc tranh luận ở đây sẽ quan trọng đối với các bashnhà phát triển). Bạn dường như nghĩ rằng hầu hết bashngười dùng đang gặp vấn đề với việc mở rộng lịch sử, nhưng không ai trong số bạn và tôi biết mức độ phổ biến của việc sử dụng chúng.

Shell Unix cho phép một người sửa đổi hành vi của shell để phù hợp với nhu cầu và sở thích cá nhân của một người. Nếu bạn muốn tắt thay thế lịch sử cho tất cả các vỏ tương tác của mình, hãy tiếp tục làm những gì bạn đang làm bằng cách sử dụng set +Htrong ~/.bashrctệp của mình hoặc vận động các bashnhà phát triển thay đổi mặc định (điều này, tôi tin rằng, sẽ gây khó chịu và nhầm lẫn cho nhiều người hơn nó sẽ giúp ).


2
@MikkoRantalainen Bạn dường như nghĩ rằng sự thay thế lịch sử không phải là thứ mà phần lớn bashngười dùng đang sử dụng. Tôi không nghĩ ai trong chúng ta cũng biết nó phổ biến như thế nào. Tôi đề nghị rằng nếu bạn cảm thấy mạnh mẽ về điều này, bạn hãy gửi một yêu cầu tính năng / lỗi đến bashdanh sách gửi thư. Xem savannah.gnu.org/mail/?group=bash
Kusalananda

8
Đúng. Vấn đề thực sự không phải là về sự thay thế lịch sử, mà là về thực tế là hai câu trích dẫn của Cameron trong Bash không thực sự trích dẫn theo nghĩa các ngôn ngữ khác sử dụng thuật ngữ này, mà hoạt động giống như một loại dấu ngoặc đơn đặc biệt. @MikkoRantalainen, hãy tạo thói quen đặt bất cứ điều gì mà bạn không muốn Bash diễn giải theo bất kỳ cách đặc biệt nào trong các trích dẫn duy nhất !
leftaroundabout

5
@leftaroundabout Nó phụ thuộc vào ý của bạn bằng cách diễn giải. Hầu hết các ngôn ngữ diễn giải các ký tự điều khiển trong chuỗi cho đầu ra (nhưng được cấp, không giống như trong trình bao khi chỉ xáo trộn các chuỗi xung quanh). Các quy tắc trích dẫn của Perl cũng hoạt động khá giống với shell (nội suy biến). Như với bất kỳ ngôn ngữ lập trình nào, sẽ giúp ích nếu người ta có thể nhớ ngôn ngữ nào hiện đang làm việc.
Kusalananda

5
" quan điểm của tôi là vậy! hiếm khi được sử dụng ký tự đặc biệt " Tôi nói rằng đó là cách khác ... !nó hiếm khi được sử dụng như một nhân vật bình thường - bỏ qua WTFs - số người bị bắt gặp vượt xa bởi số người vẫn sử dụng nó để thay thế lịch sử.
TripeHound

3
-1 vì làm chệch hướng đổ lỗi cho trích dẫn không đúng. Kể từ khi !không đặc biệt để nhất Bourne giống như vỏ, cũng không phải trong bashkịch bản, có nhiều con đường mà mọi người một cách hợp lý có thể biết rằng "$my_var some text!!"sẽ mở rộng $my_varnhưng không phải là !!. Tôi đã làm quen với lớp vỏ giống Bourne busybox ashvà cuộc gặp gỡ đầu tiên với bashsự thay thế lịch sử tôi bị nó cắn khi tôi đang cố gắng thực hiện một số bước nhanh trong lớp vỏ tương tác. Những người thành thạo trong việc sử dụng di động và viết kịch bản các vỏ giống như Bourne thường bị nó cắn ít nhất một lần khi sử dụng bash.
mtraceur

9

Lịch sử thay thế là hữu ích. Lấy ví dụ

% make-me-a-sandwich
make-me-a-sandwich: Permission denied
% sudo !!
Ok.

2
Vì thế? Nếu bạn thấy nó hữu ích, bạn có thể kích hoạt nó trong .bashrc.
Barmar


3
@Barmar và nếu bạn thấy nó không hữu ích, bạn có thể vô hiệu hóa nó. Hài hước làm thế nào đối xứng hoạt động.
hobbs

3
@hobbs Nếu bạn không biết rằng nó tồn tại, làm thế nào bạn biết để vô hiệu hóa nó?
Barmar

2
Câu trả lời này thực hiện tốt công việc giải thích một lý do tại sao tính năng này hữu ích. Tôi nghĩ OP muốn hiểu tại sao tính hữu dụng này đủ để biện minh cho hành vi này, mặc dù OP (và những người khác, chẳng hạn như những người hỏi một số câu hỏi liên quan trên stackexchange này) thấy hành vi này đáng ngạc nhiên / bất ngờ.
mtraceur

4

Quán tính xã hội / văn hóa.

Câu hỏi này nằm trong không gian vấn đề con người làm việc như thế nào, vì vậy tôi sẽ trả lời từ góc độ đó, mà không đưa ra bất kỳ ý kiến ​​nào về việc liệu tính năng này có nên được bật theo mặc định hay không.

Để bắt đầu, để chắc chắn rằng bạn hiểu được khía cạnh khác, hãy xem xét rằng sự phiền toái mà bạn cảm thấy phải đi ra ngoài để tắt tính năng, là sự khó chịu mà họ sẽ cảm thấy nếu phải rời khỏi để bật các tính năng.

Kết hợp những điều trên với thực tế là đủ bashngười dùng sử dụng tính năng này, các đề xuất loại bỏ hoặc tắt nó theo mặc định sẽ gặp phải sự phản kháng từ những người đã sẵn sàng sử dụng tính năng này theo mặc định.

Ngoài ra, bashlà shell mặc định cho nhiều người (không chỉ theo nghĩa đăng nhập mặc định hoặc shell hệ thống, mà theo nghĩa tâm lý). Nếu khung tham chiếu của bạn để trích dẫn shell là bash, nếu đó là shell bạn đã học trước tiên, thì thực tế đó !là một ký tự shell đặc biệt sẽ mang lại cảm giác tự nhiên và tự động cho bạn (hoặc ít nhất, khi bạn lần đầu tiên học nó, nó sẽ chỉ là một phần của cách thức của cái vỏ là, chỉ cần một điều để chấp nhận giữa nhiều người).

Và nếu bạn nghĩ về nó, rất nhiều bashngười dùng có thể gặp phải cú pháp thay thế lịch sử trong bối cảnh tích cực : họ đọc về nó hoặc ai đó cho họ thấy và họ thấy sự hữu ích có thể có của nó, khi họ mới học bash.

Nó chỉ đến từ thế giới ngoại vi của những chiếc vỏ giống như Bourne khác, mà bạn bị cắn bởi !sự đặc biệt do đó có xu hướng xem nó một cách tiêu cực: Bởi vì nếu bạn đã từng sử dụng đạn pháo mà bạn chưa bao giờ có tính năng này, thì trước tiên bạn tiếp xúc với nó sẽ là khi nó làm phiền bạn khi bạn đang cố gắng hoàn thành công việc một cách vội vàng.

TL; DR: Hầu hết người dùng có thể không quan tâm mạnh mẽ mặc định là gì, một số người dùng thích tính năng này và có lợi thế mạnh mẽ của nó là như vậy và không có đủ người chủ động ủng hộ tính năng này khắc phục điều đó.


2
Không, nó không chỉ khi đến từ các vỏ khác. Tôi đã biết đến tính năng này trong nhiều năm qua tại bashvà vẫn bị cắn bất ngờ, như single trích dẫn không phải lúc nào làm việc trên !vì sự tan vỡ bashthực hiện.
Philippos

@Philippos Điều đó thật đáng sợ (tốt, không chính xác là đáng sợ ... nhưng một số loại tiêu cực đau khổ). Cảm ơn đã chỉ ra điều này. Tôi sẽ cố gắng xem lại câu trả lời này sau để đưa ra quan điểm của bạn vào câu trả lời của tôi một khi tôi đã nghĩ ra một cách tốt để tích hợp nó.
mtraceur

2

Tại sao thay thế lịch sử bash vẫn được bật theo mặc định?

Bởi vì nhiều người sử dụng nó và những người sử dụng shell bash tương tác có lẽ nên biết các quy tắc để tránh các vấn đề và thường sẽ thấy nó giúp ích nhiều hơn là gây tổn thương.

.Bashrc của tôi đã bao gồm set + H trong nhiều năm nhưng một số người khác vẫn bị cắn bởi tính năng này.

Vì vậy, đây là một tính năng bạn không sử dụng, điều đó không có nghĩa là phần lớn người dùng không sử dụng nó. Bạn có thể kiến ​​nghị thay đổi mặc định, nhưng bạn phải xem A) phần người quan tâm và B) tỷ lệ người thích theo cách của bạn. Những người quan tâmkhông thích nó có lẽ đã bị vô hiệu hóa. Thay đổi nó sẽ giúp ích khi họ có được một tài khoản trên một máy tính mới. Những người quan tâmlàm như vậy sẽ phải cập nhật cài đặt của họ trên mọi máy tính họ sử dụng và mọi tài khoản họ nhận được trong tương lai.

Cho rằng khá nhiều người đang sử dụng thiết bị đầu cuối với các tính năng sao chép-dán

Theo tôi, một lựa chọn mạnh mẽ hơn ...

Có thực sự có lý do để có tính năng này không? Không có đoạn script hiện tại nào bị phá vỡ ngay cả khi điều này bị tắt theo mặc định cho tất cả các shell.

Vâng, mọi người thấy nó hữu ích. Có ích gì khi sử dụng điều khiển từ xa mà bạn đã từng có thể vừa thức dậy và thay đổi kênh?

(Rõ ràng tính năng này có vấn đề lớn nếu nó bị tắt theo mặc định cho tất cả các tập lệnh và một tính năng tồn tại để xác minh kết quả trước khi thực hiện: shopt -s histverify.)

Lịch sử không thực sự có ý nghĩa trong các kịch bản, nhưng quan trọng hơn là nó có thể gây ra các vấn đề bảo mật. Trong trường hợp của bạn, bạn có thể tránh được vấn đề bằng cách sử dụng dấu ngoặc đơn. Tôi không nhớ điều này từng gây ra vấn đề cho tôi, vì vậy tôi không biết làm thế nào bạn có thể nói nó có 'vấn đề lớn'. Điều này có gây ra sự cố thực sự cho bạn không, hoặc bạn có thấy khó chịu khi phải đặt mặc định của mình trên một máy tính mới không?

Tôi không thấy nó khác biệt như thế nào ngoài việc phải trốn thoát hoặc sử dụng các trích dẫn đơn trong trường hợp này nếu bạn thực sự muốn nhận được một số tiền:

$ echo "Give me $50 or the cat gets it"
Give me $0 or the cat gets it

2
Xem các câu hỏi liên quan (cột bên phải); hầu hết các câu hỏi đang đánh vào tính năng này một cách tình cờ và cho rằng vỏ bị hỏng. Cá nhân tôi đã tìm hiểu về tính năng này từ lâu do thực tế là tôi đã vô tình sử dụng chuỗi ký tự gây ra đầu ra sai. Tôi đã được cứu bởi shopt -s histverifynhưng đó không phải là mặc định. Ngoài ra, việc tìm ra nguyên nhân của bản thân khá khó khăn vì thông báo lỗi là khó hiểu ("không tìm thấy sự kiện") và chuỗi ký tự kích hoạt rất khó để google tìm kiếm.
Mikko Rantalainen

1
Mọi người thực sự bị cắn bởi tính năng này bởi vì các tính năng cú pháp shell "phổ quát" như $đặc biệt bên trong "..."là một trong những điều đầu tiên mọi người tìm hiểu về shell, trong khi thực tế !là đặc biệt bên trong "..."(nhưng chỉ trong chế độ tương tác) thường ít được biết đến không được dạy như ngay lập tức / nổi bật, và là đặc bashthù. Ngoài ra, các shell giống như Bourne hầu hết có sự đối xứng giữa shell-text-in-script và text-on-the-Interactive-shell, do đó, bạn thường có thể đồng bộ từ cái này sang cái khác và nó hoạt động như nhau - và tính năng này tạo ra một trong những trường hợp ngoại lệ duy nhất
mtraceur

1
Tôi không thấy nó khác biệt như thế nào ngoài việc phải thoát hoặc sử dụng các trích dẫn đơn Đúng zsh, khi trích dẫn đơn !luôn hoạt động, nhưng không phải cho bashviệc triển khai tạo ra kết quả bất ngờ . Bạn nói, chúng ta nên biết các quy tắc , tốt, bạn đã biết quy tắc liên kết?
Philippos
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.