LINUX.ORG.RU
решено ФорумAdmin

Ansible. Замена строки, начинающейся со cпецсимвола $

 , , ,


0

1

Решил спросить у знающих людей, сам повозился, но как-то не получается. Пилю ansible playbook. Нужно в /usr/share/phppgadmin/conf/config.inc.php заменить $conf['servers'][0]['host'] = ''; на:

$conf['servers'][0]['host'] = 'localhost';

Для этого в playbook создаю task типа:

  - name: replace line
    lineinfile:
      path: /usr/share/phppgadmin/conf/config.inc.php
      regexp: ^$conf['servers'][0]['host'] ='';
      line: $conf['servers'][0]['host'] = 'localhost';

Затык в том, что строка начинается со спецсимвола $. Про экранирование в регекспах читал, но чета не получается как нужно.

Пробовал так:

^$\conf['servers'][0]['host'] ='';
^$\\conf['servers'][0]['host'] ='';
^\$conf['servers'][0]['host'] ='';

Вместо этого строка добавляется в конец файла:

 $conf['servers'][0]['host'] = 'localhost';

Разобрался.

Нужно ставить двойное экранирование перед каждым спецсимволом, в том числе и перед [, ] - это пропустил.

Вот так - работает:

  - name: replace a line
    lineinfile:
      path: /usr/share/phppgadmin/conf/config.inc.php
      regexp: "\\$conf\\['servers'\\]\\[0\\]\\['host'\\] = '';"
      line: "$conf['servers'][0]['host'] = 'localhost';"
dopedopedope ()
Последнее исправление: dopedopedope (всего исправлений: 1)
Ответ на: комментарий от dopedopedope

Ради одного слова целую строку менять?! Такое только на OTUSовских курсах для слаборазвитых видел, ну я, конечно, сам немножко странный, но обычно делаю так:


  - name:     add localhost to config file
    replace:
         path: test.txt
         backup: yes
         regexp: "^(.*)(=)*'';"
         replace:  '\1  "localhost";'
Bajenko ()
Ответ на: комментарий от Bajenko

Слаборазвитый тут походу только ты, ему надо конкретную строку находить и этой конкретной строке менять '' на localhost, а твоя регуляка подменит '' по шаблону blablablalba = '', т.е. любую '' которую найдет и которая удовлетворяет шаблону.

anonymous ()
Ответ на: комментарий от anonymous

понятия не имею что за otus, но этот мальчик мало того что говном полил этот otus, так еще и сделал не то что надо, а сколько апломба. Кстати файл test.txt опять же у мальчика, а не человека который ищет помощи.

anonymous ()
Ответ на: комментарий от anonymous

Это был сарказм.

Нет разницы, что в примере регэкспа написано - смотреть надо в модуль. Топикстартер пытается натянуть сову на глобус, используя lineinfile вместо replace.
https://docs.ansible.com/ansible/latest/modules/replace_module.html Отсюда и весь юмор в адрес отус весьма характерная ошибка из их видеокурса.

anonymous ()
Ответ на: комментарий от anonymous

рискуешь прослыть башмакакой с портянками

Только шеллскрипт с сотнями эскейпинга короче аналогичного yaml-смузи раза в два. И понятнее.

Алсо, я она и есть, в свободное время от кодинга, только я на конкретно баше не пишу, я осознанно читал ман от dash и регулярно пользуюсь аналогами.

нормальные пацаны на гребне волны

От таких пацанов я ржу, особенно когда очередное yaml-чудо, настроившее гитлаб по заветам такого же js-чуда и поставленное js-чудом в пример виндоадминам, перешедшим на коляску, пару дней не может сменить простую настройку. Во время чего js-чудо, получив вербозный выхлоп в качестве пруфа того, что факап случился на их стороне, не вникая в суть вопроса, пытается меня научить пользоваться ssh чуть ли не по видео, при том, что ssh я пользовался очень давно и часто.

anonymous ()
Ответ на: комментарий от anonymous

Ну братиш, dd-то в принципе вещь не совсем очевидная и правильная (хотя может подходить для разных вещей, в чём живёт суть Unix; но возможно стоило бы взять специальную команду-программу для буферизации stdin в памяти), а регулярку можно хоть на полнотекстовую замену поменять, хоть на

while read line; do [ "line" = "$toreplace" ] && echo "$replaced" || echo "$line"; done

в пайпе, тут чувство прекрасного особо включать не надо, учитывая то, что мы меняем дефолт, который если и поменяют, то только до того, что придётся менять всё заново.

На таких маленьких кусках скриптов думать не надо, любой путь сойдёт.

anonymous ()
Ответ на: комментарий от anonymous

Лень. Западло каждый раз убивать пол дня, чтобы раскатывать одно и то же добро с набором ништяков.

Как по мне - проще изобразить в ansible, чем перлом, шеллом и awk.

Перл - жив и молод, как Ленин.

dopedopedope ()
Последнее исправление: dopedopedope (всего исправлений: 1)
Ответ на: комментарий от anonymous

Отрубание пальцев вместо стрижки ногтей так себе развлечение, но проблема с ногтями действительно решается.

string= $conf['servers'][0]['host'] = '';

#####
$ cat test.txt
$conf['servers'][0]['host'] = '';

#####
$ cat replace.yaml 
---
- hosts: localhost

  tasks:
  
  - name:          add localhost to config file
    replace:
         path:     test.txt
         backup:   yes
         regexp:   "(\\$conf\\['servers'\\]\\[0\\]\\['host'\\].*)(=)*'';"
         replace:  '\1 "localhost";'

#####
$ cat replace2.yaml 
---
- hosts: localhost

  tasks:


  - name:          replace a line
    lineinfile:
        path:      test.txt
        regexp:    "\\$conf\\['servers'\\]\\[0\\]\\['host'\\] = '';"
        line:      "$conf['servers'][0]['host'] = 'localhost';"
#####

$ time ansible-playbook replace.yaml 

PLAY [localhost] **********************************************************************

TASK [Gathering Facts] ****************************************************************
ok: [localhost]

TASK [add localhost to config file] ***************************************************
changed: [localhost]

PLAY RECAP ****************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


real	0m5.063s
user	0m4.208s
sys	0m0.805s


#####
$ time ansible-playbook replace2.yaml 

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [replace a line] **********************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


real	0m6.199s
user	0m4.830s
sys	0m0.869s

на одной строке!!! Карл

real 0m5.063s против real 0m6.199s

и это я не стал ещё регулярку править

Bajenko ()

Замена строки, начинающейся со cпецсимвола $

Этот символ в консоли не нужно заменять. Просто вводите свою команду в терминале. И не забывайте про sudo.

Владимир

anonymous ()
Ответ на: комментарий от dopedopedope

Западло каждый раз убивать пол дня, чтобы раскатывать одно и то же добро с набором ништяков.

Для этого существует source и функции.

Половину дня ты убиваешь потому, что у тебя мало опыта, о чём свидетельствует незнание регулярок и обращение на ЛОР за тем, что можно было почерпнуть из man regex за тридцать минут вдумчивого чтения, пятнадцать минут пролистывания и пяти минут поиска по словам (регуляркой, ага). По этой же причине ты выбрал готовый репозиторий с уже написанным кодом, т.е. твоя реальная стоимость как админа должна стремиться вниз, поскольку админ/девопс, который выполняет чужой код и не читает исходники кода и конфигов, имеет ненулевую вероятность нарваться на проблемы в виде забива на безопасность (привет майнерам, сливу данных с открытых баз, мяу-атаке, лол) и поднятия собственных лапок, когда дело доходит до нетривиальных случаев (один из примеров я описал выше).

Проще изобразить как раз на шелле, работая с шеллом, ты имеешь дело с REPL и более-менее языком программирования, пусть и игрушечным. Если в середине кода на шелле произошло что-то не так, ты в интерактивном режиме можешь прогнать код хоть по кускам, хоть целиком и понять, что делать; в случае каменной портянки такого уже не получится. Итеративное написание кода с такими каменными портянками без интерактивности превращается в пытку.

Перл - жив и молод, как Ленин.

9.5 из десяти задач этот инструмент возьмёт с лёгкостью. Не забывай, что это настоящий ЯП с явно не мёртвой системой пакетов. Для того, кто не поднимает лапки, полный скриптовый язык (не обязательно Perl) может и сгодиться, когда не хватает DSL для запуска программ и DSL для обработки текста. Но кто-то любит PCRE и пользуется перлом ещё и вместо AWK.

А так-то любой из сегодняшних скриптовых (да и не очень) языков - неграмотно составленный мусор для программистов малой степени грамотности, клюющих на любой хайп. Если период трэша м угара в Perl прошёл, то в случае Python, JS и Ruby всё только начинается или уже идёт. В этом ничего хорошего нет, говорю тебе как один раз клюнувший на пропаганду и посмотревший на (чуть) более грамотно сделанные языки.

anonymous ()
Ответ на: комментарий от Bajenko

Вы серьёзно?

$ cat > 1                                                             $conf['servers'][0]['host'] = '';                                     $ time (file=1; awk '/^\$conf\[.servers.\]\[0\]\[.host.\]/{sub("'"''"'", "'"'localhost'"'");}{print;}' $file >$file.new; cat $file.new >$file ; rm $file.new)

real    0m0.061s
user    0m0.036s
sys     0m0.016s
$ cat 1
$conf['servers'][0]['host'] = 'localhost';
$ uname  -m
aarch64
anonymous ()
Ответ на: комментарий от dopedopedope

Для экранирования строк, чтоб regexp распознавал их как «просто текст» в ansible есть фильтр regex_escape():

- name: replace a line
    lineinfile:
      path: /usr/share/phppgadmin/conf/config.inc.php
      regexp: '^{{ item.search | regex_escape() }}$'
      line: '{{ item.replace }}'
    with_items:
      - { search: "$conf['servers'][0]['host'] = '';", replace: "$conf['servers'][0]['host'] = 'localhost';" }
spirit ★★★★★ ()