Восклицательные знаки в аргументах команд bash [duplicate]

perl однострочный:

$ perl -ne 'if(/^HOST/){print "#$_"} else { print}' input.txt                                  
--------------------
NETWORKING=yes
#HOSTNAME=wls1.ebs-testsrvrs.com
# oracle-rdbms-server-12cR1-preinstall : Add NOZEROCONF=yes
NOZEROCONF=yes
--------------------

Этот простой однострочный алгоритм выполняет итерацию по всем строкам, проверяя, начинается ли строка с HOST и добавляя к нему # , в противном случае мы переходим к else , который просто печатает строку без изменений.

Версия для Python того же самого будет следующая:

python -c "import sys;print '\n'.join([ '#' + l.strip() if l.startswith('HOST') else l.strip()  for l in sys.stdin  ])" < input.txt

Однако это работает немного по-другому, путем создания списка (или массива) строк, условной вставки самой строки или строки с добавленным # . В конечном итоге массив объединяется в одну большую строку с элементами, разделенными новой строкой, и распечатывается.

1
04.04.2017, 12:53
3 ответа

В Linux Mint 18.1 на основе Ubuntu 16.04 с:

bash --version | head -1
 GNU bash, версия 4.3.46 (1) -release ( x86_64-pc-linux-gnu) 
 

Поведение выглядит следующим образом:

echo dog\!\!

приводит к:

 dog !! 
 
echo 'dog!!'

приводит к:

 dog! ! 
 
echo "dog!!"

неожиданно печатает dog , за которой следует последняя команда; например если вы выполнили ls раньше, он напечатает:

 echo "dogls" 
dogls 
 

На GNU / Linux Debian 9 Stretch там является немного более новой версией:

bash --version | head -1
 GNU bash, версия 4.4.11 (1) -release (x86_64-pc-linux-gnu) 
 

Поведение выглядит следующим образом:

echo dog\!\!

приводит к:

 dog !! 
 
echo 'dog!!'

приводит к:

 dog !! 
 
echo "dog!!"

неожиданно печатает dog , за которым следует последняя команда; например если вы сделали ls раньше, он напечатает:

 echo "dogls" 
dogls 
 

Мне это кажется последовательным.

Возможно, что в старых системах со старой версией bash он ведет себя немного иначе. Но в новых системах мы можем ожидать такого поведения.

1
27.01.2020, 23:12

Вам нужно либо убрать восклицательные знаки, либо использовать одинарные кавычки:

echo dog\!\!
echo 'dog!!'

(Это не объясняет, почему ваш echo "dog\!\!" не работает, но он должен работать, я не знаю, почему он не работает. Или, по крайней мере, он не должен действовать на историю; в Bash он выведет dog\!\! .)

5
27.01.2020, 23:12

В Bash, если вы хотите, чтобы восклицательные знаки всегда обрабатывались как обычные символы и не нуждались в расширении истории, вы можете отключить его для текущей оболочки с помощью

set +o histexpand

или добавить команду в обычную конфигурацию files, т.е. скорее всего .bashrc, чтобы отключить его для всех оболочек.

4
27.01.2020, 23:12

Теги

Похожие вопросы