Я попытался создать скрипт, echo
вставив содержимое в файл, а не открывая его в редакторе.
echo -e "#!/bin/bash \n /usr/bin/command args" > .scripts/command
Выход :
bash:! / bin / bash: событие не найдено
Я выделил это странное поведение на ура .
$ echo !
!
$ echo "!"
bash: !: event not found
$ echo \#!
#!
$ echo \#!/bin/bash
bash: !/bin/bash: event not found
- Почему взрыв вызывает это?
- К каким «событиям» относится bash?
- Как мне обойти эту проблему и вывести «#! / Bin / bash» на экран или в мой файл?
command-line
bash
echo
Стефан
источник
источник
$''
. Например,echo $'1!\n2!\n3!\n'
печатает каждый номер, за которым следует удар и символ новой строки.echo '0123'"$var"'456'
обратите внимание на две пары одинарных кавычек и одну пару двойных кавычек.Как сказал Ричм , bash пытается сделать исторический матч . Другой способ избежать этого - просто избежать взрыва с помощью
\
:Хотя имейте в виду, что внутри двойных кавычек
\
не удаляется:источник
"\!"
фактически расширяется\!
, а не!
, предположительно, для соответствия POSIX.!
в двойные кавычки без магического поведения? Это безумие ...!
запускает подстановку истории («событие» - это строка в истории команд); например,!ls
расширяется до последней содержащей командную строкуls
и!?foo
расширяется до последней содержащей командную строкуfoo
. Вы также можете извлечь конкретные слова (например,!!:1
относится к первому слову предыдущей команды) и многое другое; см. руководство для деталей.Эта функция была изобретена для быстрого вызова предыдущих команд в те времена, когда редакция командной строки была примитивной. С современными оболочками (по крайней мере, bash и zsh) и копированием и вставкой расширение истории не так полезно, как раньше - оно все еще полезно, но вы можете обойтись без него.
Вы можете изменить, какой символ запускает подстановку истории, установив
histchars
переменную; если вы редко используете подстановку истории, вы можете установить, например,histchars='¡^'
так, чтобы¡
запускать расширение истории вместо!
. Вы даже можете отключить эту функцию вместе сset +o histexpand
.источник
Чтобы иметь возможность отключить расширение истории в определенной командной строке, вы можете использовать
space
в качестве 3-го символа$histchars
:Затем, если вы введете команду с начальным пробелом, расширение истории не будет выполнено.
Тем не менее, обратите внимание, что начальные пробелы также используются, когда
$HISTCONTROL
содержатсяignorespace
как способ запретитьbash
запись командной строки в историю.Если вы хотите, чтобы обе функции были независимыми, вам нужно выбрать другой символ в качестве 3-го символа
$histchars
. Вы хотите тот, который не влияет на интерпретацию вашей команды. Несколько вариантов:\
):\echo foo
работает, но имеет побочный эффект отключения псевдонимов или ключевых слов.если вы не возражаете , набрав два ключа, вы можете выбрать любой символ , который обычно не появляется в первой позиции (
%
,@
,?
, выбрать свой собственный) и сделать пустой псевдоним для него:Затем введите этот символ, пробел и вашу команду:
(Вы не сможете не записать команду, в которой подстановка истории была отключена. Также обратите внимание, что третий символ по умолчанию используется для того
$histchars
,#
чтобы расширение истории не делалось в комментариях. Если вы измените его, и вы введете комментарии в подскажите, вы должны знать о том, что! последовательности могут быть расширены там).источник
Предлагаемые решения не работают, например, в следующем примере:
В этом случае взрыв может быть напечатан с использованием восьмеричного кода ASCII:
источник
!
находится между двойными кавычками, где, как указывают другие ответы, он сохраняет свое значение расширения истории. Вы можете использоватьbash -c 'echo '\''hello World!'\'
илиbash -c "echo 'hello World"\!"'"
.Начиная с Bash 4.3, теперь вы можете использовать двойные кавычки для цитирования символа расширения истории:
источник
!
за этим следует,"
что больше не является особенным.echo "foo!"
все в порядке,echo "foo!bar"
нет