Próbowałem utworzyć skrypt echo
, umieszczając zawartość w pliku, zamiast otwierać go za pomocą edytora
echo -e "#!/bin/bash \n /usr/bin/command args" > .scripts/command
Dane wyjściowe :
bash:! / bin / bash: nie znaleziono zdarzenia
Wyizolowałem to dziwne zachowanie z hukiem .
$ echo !
!
$ echo "!"
bash: !: event not found
$ echo \#!
#!
$ echo \#!/bin/bash
bash: !/bin/bash: event not found
- Dlaczego powoduje to huk?
- Do jakich „zdarzeń” odnosi się bash?
- Jak obejść ten problem i wydrukować „#! / Bin / bash” na ekranie lub w moim pliku?
command-line
bash
echo
Stefan
źródło
źródło
$''
. Na przykładecho $'1!\n2!\n3!\n'
drukuje każdą liczbę, po której następuje huk i nowa linia.echo '0123'"$var"'456'
zwróć uwagę na dwie pary pojedynczych cudzysłowów i jedną parę podwójnych cudzysłowów.Jak powiedział Richm , bash próbuje dopasować historię . Innym sposobem na uniknięcie tego jest po prostu ucieczka przed hukiem za pomocą
\
:Pamiętaj jednak, że wewnątrz podwójnych cudzysłowów
\
nie są one usuwane:źródło
"\!"
właściwie rozwija się\!
, a nie!
podobno dla zgodności z POSIX.!
podwójnych cudzysłowów bez magicznego zachowania? To szalone ...!
rozpoczyna podstawianie historii („zdarzenie” to wiersz w historii poleceń); na przykład!ls
rozwija się do ostatniego wiersza poleceń zawierającegols
i!?foo
rozwija się do ostatniego wiersza poleceń zawierającegofoo
. Możesz także wyodrębnić określone słowa (np.!!:1
Odnosi się do pierwszego słowa poprzedniego polecenia) i więcej; szczegóły w instrukcji obsługi.Ta funkcja została wymyślona, aby szybko przywoływać poprzednie polecenia w czasach, gdy edycja wiersza poleceń była prymitywna. Dzięki nowoczesnym powłokom (przynajmniej bash i zsh) oraz kopiowaniu i wklejaniu, ekspansja historii nie jest tak przydatna jak kiedyś - wciąż jest pomocna, ale możesz sobie bez niej poradzić.
Możesz zmienić, który znak wyzwala podstawienie historii, ustawiając
histchars
zmienną; jeśli rzadko korzystasz z podstawiania historii, możesz ustawić np.histchars='¡^'
tak, aby¡
zamiast historii uruchamiało się rozszerzanie historii!
. Możesz nawet całkowicie wyłączyć tę funkcję za pomocąset +o histexpand
.źródło
Aby wyłączyć rozszerzanie historii w określonym wierszu polecenia, możesz użyć
space
jako trzeciego znaku$histchars
:Następnie, jeśli wprowadzisz polecenie z wiodącym odstępem, ekspansja historii nie zostanie wykonana.
Zauważ jednak, że spacje wiodące są również używane, gdy
$HISTCONTROL
zawieraignorespace
jako sposób nabash
to, aby nie zapisywać wiersza poleceń w historii.Jeśli chcesz obu funkcji niezależnie, musisz wybrać inną postać jako 3. postać
$histchars
. Chcesz taki, który nie wpływa na sposób interpretacji twojego polecenia. Kilka opcji:\
):\echo foo
działa, ale efektem ubocznym jest wyłączenie aliasów lub słów kluczowych.jeśli nie przeszkadza pisanie dwóch przycisków, można wybrać dowolny znak, że zwykle nie pojawiają się w pierwszej pozycji (
%
,@
,?
, odbiór we własnym zakresie) i uczynić pustą alias dla niego:Następnie wpisz tę postać, spację i polecenie:
(nie będziesz w stanie nie zarejestrować polecenia, w którym zastąpiono zastępowanie historii. Pamiętaj też, że domyślnym trzecim znakiem
$histchars
jest#
to, że ekspansja historii nie jest wykonywana w komentarzach. Jeśli ją zmienisz i dodasz komentarze na monit, powinieneś zdawać sobie sprawę z tego, że sekwencje! mogą tam zostać rozwinięte).źródło
Proponowane rozwiązania nie działają, np. W następującym przykładzie:
W takim przypadku huk można wydrukować za pomocą ósemkowego kodu ASCII:
źródło
!
jest pomiędzy podwójnymi cudzysłowami, gdzie, jak inne odpowiedzi wskazują, zachowuje znaczenie ekspansji historii. Możesz użyćbash -c 'echo '\''hello World!'\'
lubbash -c "echo 'hello World"\!"'"
.Od czasu wersji Bash 4.3 możesz teraz używać podwójnych cudzysłowów, aby zacytować znak rozszerzenia historii:
źródło
!
następuje,"
że to już nie jest wyjątkowe.echo "foo!"
jest OK,echo "foo!bar"
nie jest