Leonid Evdokimov (darkk) wrote,
Leonid Evdokimov
darkk

bash-WTF: `foo` != $(foo)

А я тут замечательный WTF в sh встретил.

Есть строчка /var/log/daemon/api/*.log и нужно получить из неё регулярку для sed - т.е. поэскейпить звёздочку и точку.
Очевидное решение:
$ log="/var/log/daemon/api/*.log"
$ echo "$log" | sed 's/[\.\*]/\\&/g'
/var/log/daemon/api/\*\.log


Но есть пара неочевидных тонкостей:
$ log="/var/log/daemon/api/*.log"
$ echo "$log" | sed 's/[\.\*]/\\&/g'
/var/log/daemon/api/\*\.log
$ relog=`echo "$log" | sed 's/[\.\*]/\\&/g'`; echo $relog
/var/log/daemon/api/&&log
$ relog=$(echo "$log" | sed 's/[\.\*]/\\&/g'); echo $relog
/var/log/daemon/api/\*\.log
$ relog=`echo "$log" | sed 's/[\.\*]/\\\\&/g'`; echo $relog
/var/log/daemon/api/\*\.log


Отсюда важный вывод, о котором стоит помнить - escaping внутри `foo` и $(foo) работает по-разному.
Проверено на sh из FreeBSD-8.2, bash-4.1.10, bash-4.2.8, dash-0.5.5.1-7.2ubuntu1.

UPD: Впрочем, в man bash этот факт описан. :)
Tags: **it, bash, dash, freebsd, linux, sh
Subscribe

  • Мой ежедневный Android-софт

    aLogcat — иногда отправляю отчёты разработчикам, логи при этом довольно полезны ASTRO — неплохой файл-менеджер, особенно полезен из-за…

  • Nokia E61 & google sync: потери в vCard

    Просто чтоб не забыть. Нормально не синхронизируются у Nokia E61 и google contacts через SyncML следующие поля: Прозвище (вместо него можно…

  • GSM-модем Huawei E171 в Linux

    Модем вышел на рынок довольно давно и поддерживается usb_modeswitch. По-умолчанию он у меня представлялся как 12d1:1446, после переключения…

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 4 comments