Dlaczego podstawianie historii bash jest nadal domyślnie włączone? [Zamknięte]

17

Czy ktoś wie, dlaczego bash nadal domyślnie włącza podstawianie historii ? Moje .bashrczawiera set +Hod wielu lat, ale niektóre inne osoby wciąż gryzą tę funkcję.

Biorąc pod uwagę, że prawie wszyscy używają terminali z funkcjami kopiuj-wklej i bash skompilowany z readlinebiblioteką, a podstawianie historii jest domyślnie włączone tylko w interaktywnych powłokach, czy naprawdę jest jakiś powód, aby mieć tę funkcję w ogóle? Żaden z istniejących skryptów nie zostałby uszkodzony, nawet jeśli byłby domyślnie wyłączony dla wszystkich powłok.

Wypróbuj to, jeśli nie wiesz, dlaczego podstawienie historii jest zerwane:

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

(Oczywiście ta funkcja ma poważne problemy, jeśli jest domyślnie wyłączona dla wszystkich skryptów i istnieje funkcja umożliwiająca sprawdzenie wyników przed wykonaniem:. shopt -s histverify)

Zobacz też:

Mikko Rantalainen
źródło
16
Wydaje ci się, że ludzie nie używają podstawiania historii. Używam tego codziennie. Uważam aby szybciej podążać ls -l foo/bar/baz/weeble.cppz less !$ni przypomnieć polecenia i edytować.
Martin Bonner wspiera Monikę
2
@MartinBonner Więc możesz to włączyć. Pytanie dotyczy tego, dlaczego jest domyślnie włączone , a nie dlaczego nadal istnieje.
Barmar,
5
@Barmar: Jasne. Ale moim celem było zakwestionowanie założenia, na którym opiera się to pytanie.
Martin Bonner wspiera Monikę
5
Jeśli będziemy postępować zgodnie z twoim rozumowaniem, wszystko, co wymaga zmiany znaczenia lub cytowania, powinno być domyślnie wyłączone. Dlaczego powinienem uciec lub zacytować adres URL zawierający &? Dlaczego powinienem uciec lub podać nazwę pliku zawierającego ?? Istnieją interfejsy dla osób, które uważają, że to problem.
jcaron
3
Używam !$kilka razy dziennie, a także !!dość często. Muszę przyznać, że nie używam tak często innych podstawień historii, ale na pewno byłbym niezadowolony, gdyby domyślne zachowanie powłoki używanej przez lata nagle uległo zmianie.
jcaron

Odpowiedzi:

32

Jeśli jesteś już zaznajomiony z tym bash, radzenie sobie z wzorcami zastępowania historii nie jest bardziej prawdopodobne, aby cię ugryźć, niż obsługa innych znaków, które są specjalne dla tej powłoki. Jeśli jednak ktoś nie jest zaznajomiony z powłoką lub po prostu nigdy nie użył jej funkcji zastępowania historii, będzie to oczywiście niespodzianka, gdy wyzwoli ją pozornie nieszkodliwy niecytowany lub podwójny ciąg.

W interaktywnej powłoce z włączonymi podstawieniami historii !znak jest wyjątkowy w prawie taki sam sposób, jak $znak jest wyjątkowy, tj. Wszędzie, chyba że jest \poprzedzony ciągiem cudzysłowu lub ciągami cudzysłowu.

W przeciwieństwie do $przejścia, zastępowanie historii nie rozwija się w dokumentach tutaj, a ponieważ są one zorientowane liniowo, dodatkowo będą miały miejsce w wierszach, w których podstawienie mieści się w kontekście bez cudzysłowu lub w kontekście podwójnego cudzysłowu (w tym wierszu, gdy skanowane osobno) . Zobacz ten raport o błędzie, aby uzyskać więcej informacji .

Podstawianie historii jest wyłączone w nieinteraktywnych powłokach (skryptach), ponieważ funkcja historii poleceń powłoki nie jest tam potrzebna, nie dlatego, że funkcja ma „poważne problemy”. W skrypcie zapisywanie każdego polecenia $HISTFILEbez sensu, podobnie jak podstawianie historii, nie jest czymś, na czym chciałbyś polegać w skrypcie.

To, czy powinno być domyślnie włączone, czy nie w interaktywnych powłokach, można dyskutować (choć nie jestem do końca przekonany, że debata tutaj miałaby duże znaczenie dla bashprogramistów). Wydaje ci się, że większość bashużytkowników ma problemy z rozszerzaniem historii, ale żaden z was i ja nie wiemy, jak często z nich korzystać.

Powłoki uniksowe pozwalają modyfikować zachowanie powłoki, aby dopasować ją do osobistych potrzeb i gustu. Jeśli chcesz wyłączyć podstawienia historii dla wszystkich interaktywnych powłok, kontynuuj robienie tego, co robisz set +Hw swoim ~/.bashrcpliku lub lobbuj bashprogramistom, aby zmienić domyślną (co, moim zdaniem, zdenerwuje i pomyli więcej osób, niż to pomoże ).

Kusalananda
źródło
2
@MikkoRantalainen Wydaje ci się, że zastępowanie historii nie jest czymś, z czego korzysta większość bashużytkowników. Nie sądzę, żeby którekolwiek z nas wiedziało, jak powszechne. Sugeruję, że jeśli czujesz się mocno na ten temat, prześlij żądanie funkcji / błędu na bashlistę mailingową. Zobacz savannah.gnu.org/mail/?group=bash
Kusalananda
8
Dobrze. Problemem nie jest w ogóle zamiana historii, ale fakt, że podwójne „cytaty” w Bash nie są tak naprawdę cytatami w tym sensie, że inne języki używają tego terminu, ale raczej działają jak specjalny rodzaj nawiasów. @MikkoRantalainen, nawyk umieszczać w pojedynczych cudzysłowach wszystko, czego Bash nie chce interpretować w żaden szczególny sposób !
lewo około
5
@leftaroundabout To zależy od tego, co rozumiesz przez tłumaczenie. Większość języków interpretuje znaki kontrolne w ciągach znaków wyjściowych (ale przyznawane, nie w taki sam sposób, jak w powłoce, gdy tylko tasuje się łańcuchy) Reguły cytowania Perla działają dodatkowo podobnie do powłoki (interpolacja zmienna). Jak w przypadku każdego języka programowania, pomaga zapamiętać, w jakim języku aktualnie się pracuje.
Kusalananda
5
Chodzi mi o to, że! jest tak rzadko używaną postacią specjalną ” Powiedziałbym, że jest na odwrót… !jest tak rzadko używana jako normalna postać, że - pomijając echa WTF - liczba ludzi, którzy zostali złapani, jest znacznie większa przez liczbę osób, które nadal używają go do zastąpienia historii.
TripeHound
3
-1 za odwrócenie winy na niewłaściwe cytowanie. Ponieważ nie! jest wyjątkowy dla większości powłok podobnych do Bourne'a, ani w skryptach, istnieje wiele ścieżek, dzięki którym ludzie mogą w rozsądny sposób dowiedzieć się, które rozwiną, ale nie . Zapoznałem się z powłoką podobną do Bourne'a i moje pierwsze spotkanie z podstawieniem historii polegało na tym , że gryzłem ją, kiedy próbowałem zrobić szybką liniówkę w interaktywnej powłoce. Ludzie biegli w przenośnym i skryptowym korzystaniu z powłok podobnych do Bourne'a często gryzą go przynajmniej raz podczas używania . bash"$my_var some text!!"$my_var!!busybox ashbashbash
mtraceur
9

Zastąpienie historii jest przydatne. Weź na przykład

% make-me-a-sandwich
make-me-a-sandwich: Permission denied
% sudo !!
Ok.
Johan Myréen
źródło
2
Więc? Jeśli uznasz to za przydatne, możesz włączyć je w swoim .bashrc.
Barmar,
3
xkcd.com/149
Walter Tross,
3
@Barmar, a jeśli okaże się to nieprzydatne, możesz je wyłączyć. Zabawne, jak działa symetria.
hobbs
3
@ Hobbs Jeśli nie wiesz, że istnieje, skąd możesz to wyłączyć?
Barmar,
2
Ta odpowiedź dobrze wyjaśnia jeden z powodów, dla których funkcja jest przydatna. Myślę, że OP chce zrozumieć, dlaczego ta użyteczność jest wystarczająca, aby uzasadnić to zachowanie, mimo że OP (i inni, np. Ludzie zadający kilka powiązanych pytań na temat wymiany stosów) uważają to zachowanie za zaskakujące / nieoczekiwane.
mtraceur,
4

Bezwładność społeczna / kulturowa.

To pytanie znajduje się w przestrzeni problemowej dotyczącej działania ludzi, więc odpowiem pod tym kątem, nie wydając żadnej opinii na temat tego, czy funkcja powinna być domyślnie włączona.

Aby rozpocząć, aby upewnić się zrozumieć drugą stronę, uważają, że kłopot czujesz konieczności przechodzenia na swojej drodze, aby wyłączyć tę funkcję, jest kłopot, że będzie się czuł, gdyby musieli wychodzić na ich drodze, aby włączyć funkcja.

Połącz powyższe z faktem, że wystarczająca liczba bashużytkowników korzysta z tej funkcji, sugestie jej usunięcia lub domyślnego wyłączenia spotkały się z oporem ze strony osób, które już czują się komfortowo, gdy jest tam domyślnie.

Ponadto bashjest domyślną powłoką dla wielu osób (nie tylko w domyślnym sensie logowania lub powłoki systemowej, ale w sensie psychologicznym). Jeśli twoją ramką odniesienia dla cytowania powłoki jest bash, jeśli jest to powłoka, której nauczyłeś się najpierw, fakt, że !jest ona specjalną postacią powłoki, będzie dla ciebie naturalny i automatyczny (a przynajmniej, gdy się ją nauczysz, będzie to po prostu część sposób, w jaki jest to skorupa, tylko jedno dziwactwo do zaakceptowania wśród wielu).

A jeśli się nad tym zastanowić, wielu bashużytkowników prawdopodobnie napotyka składnię podstawiania historii w pozytywnym kontekście: czytają o tym lub ktoś im to pokazuje i widzą możliwą przydatność, gdy zaczynają się uczyć bash.

Pochodzi tylko z peryferyjnego świata innych powłok podobnych do Bourne'a, że ​​zostałbyś ugryziony przez !bycie wyjątkowym, a tym samym miałbyś skłonność do postrzegania go negatywnie: Ponieważ jeśli jesteś przyzwyczajony do pocisków, w których nigdy nie miałeś tej cechy, to twój pierwszy narażenie się na to nastąpi, gdy cię spieprzysz, gdy spróbujesz coś zrobić w pośpiechu.

TL; DR: Większość użytkowników prawdopodobnie nie dba o to, jaka jest wartość domyślna , niektórzy użytkownicy lubią tę funkcję i mają tę zaletę, że już taka jest, a nie było wystarczającej liczby osób aktywnie opowiadających się przeciwko tej funkcji, aby przezwyciężyć to.

mtraceur
źródło
2
Nie, nie pochodzi to tylko z innych pocisków. Znam tę funkcję od lat bashi wciąż gryzę się z zaskoczenia, ponieważ pojedyncze cytowanie nie zawsze działa z !powodu zepsutej bashimplementacji.
Philippos
@Filippos To przerażające (cóż, niezupełnie przerażające ... ale coś w rodzaju niepokojących negatywnych kwaliów). Dzięki za zwrócenie na to uwagi. Postaram się ponownie przeczytać tę odpowiedź później, aby opracować swój punkt widzenia w mojej odpowiedzi, gdy tylko wymyślę dobry sposób na jej zintegrowanie.
mtraceur
2

Dlaczego podstawianie historii bash jest nadal domyślnie włączone?

Ponieważ wiele osób go używa, a ludzie używający interaktywnej powłoki bash prawdopodobnie powinni znać zasady, aby uniknąć problemów i na ogół stwierdzą, że pomaga to bardziej niż boli.

Mój .bashrc zawiera set + H od wielu lat, ale niektórzy inni wciąż gryzą tę funkcję.

Jest to więc funkcja, której nie używasz, co nie znaczy, że większość użytkowników jej nie używa. Możesz złożyć wniosek o zmianę wartości domyślnej, ale musisz spojrzeć na A) część ludzi, którym zależy , i B) proporcję osób, które wolą to na swój sposób. Ludzie, którym zależy i których nie lubią, prawdopodobnie już mają to wyłączone. Zmiana tego pomogłaby, gdy założą konto na nowym komputerze. Osoby, którym to zależy i które to lubią, będą musiały aktualizować swoje ustawienia na każdym komputerze, którego używają i na każdym koncie, które otrzymają w przyszłości.

Biorąc pod uwagę, że prawie wszyscy używają terminali z funkcjami kopiuj-wklej

Moim zdaniem dziwniejsza opcja ...

czy naprawdę jest jakiś powód, aby w ogóle mieć tę funkcję? Żaden z istniejących skryptów nie zostałby uszkodzony, nawet jeśli byłby domyślnie wyłączony dla wszystkich powłok.

Tak, ludzie uważają to za przydatne. Jaki jest pożytek z posiadania pilota zdalnego sterowania, z którego mogłeś po prostu wstać i zmienić kanał?

(Oczywiście ta funkcja ma poważne problemy, jeśli jest domyślnie wyłączona dla wszystkich skryptów i istnieje funkcja umożliwiająca sprawdzenie wyników przed wykonaniem: shopt -s histverify.)

Historia naprawdę nie ma sensu w skryptach, ale co ważniejsze, może powodować problemy z bezpieczeństwem. W twoim przypadku możesz uniknąć problemu, używając pojedynczych cudzysłowów. Nie pamiętam, aby kiedykolwiek powodowało to dla mnie problem, więc nie wiem, jak można powiedzieć, że ma „poważne problemy”. Czy spowodowało to dla ciebie rzeczywisty problem, czy denerwowało Cię ustawienie domyślnych ustawień na nowym komputerze?

Nie rozumiem, jak to się różni od konieczności ucieczki lub użycia pojedynczych cudzysłowów, jeśli naprawdę chcesz dostać trochę pieniędzy:

$ echo "Give me $50 or the cat gets it"
Give me $0 or the cat gets it
Jason Goemaat
źródło
2
Zobacz powiązane pytania (prawa kolumna); większość pytań trafia do tej funkcji przez przypadek i zakłada, że ​​skorupa jest zepsuta. Dowiedziałem się o tej funkcji dawno temu, ponieważ przypadkowo użyłem sekwencji znaków, która spowodowała nieprawidłowe wyjście. Chciałbym zostały zapisane przez shopt -s histverifyale że nie było domyślnie. Ponadto samodzielne ustalenie przyczyny jest dość trudne, ponieważ komunikat o błędzie jest tajemniczy („nie znaleziono zdarzenia”), a sekwencja znaków, która go wyzwala, jest trudna do wyszukania w Google.
Mikko Rantalainen,
1
Ludzie naprawdę gryzą się tą funkcją, ponieważ „uniwersalne” funkcje składniowe powłoki, takie jak $bycie wyjątkowym w środku, "..."są jedną z pierwszych rzeczy, których ludzie dowiadują się o powłoce, podczas gdy fakt, że !jest ona wyjątkowa "..."(ale tylko w trybie interaktywnym) jest mniej znana, zazwyczaj nie uczy się tak od razu / w widocznym miejscu i jest bashspecyficzny. Ponadto powłoki podobne do Bourne'a w większości mają symetrię między tekstem w skrypcie i tekstem na interaktywnej powłoce, więc możesz ogólnie kopiować z jednego na drugi i mieć to samo - i ta funkcja tworzy jeden z wyjątków.
mtraceur
1
Nie rozumiem, jak to jest inaczej niż konieczność ucieczki lub użycia pojedynczych cudzysłowów Prawda zsh, gdy pojedyncze cytowanie !zawsze działa, ale nie w przypadku bash, gdy implementacja daje nieoczekiwane wyniki . Mówisz, że powinniśmy znać zasady , czy znasz tę powiązaną zasadę?
Philippos