?

Log in

No account? Create an account

Previous Entry | Next Entry

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 этот факт описан. :)

Метки:

Comments

( 4 комментария — Оставить комментарий )
goodmesh
6 окт, 2011 10:59 (UTC)
внутри `foo` надо эскейпить бэкслеши бэкслешами)
Мне плюсик, да?
darkk
6 окт, 2011 11:07 (UTC)
Условно говоря, да.
drunkmaster
6 окт, 2011 14:24 (UTC)
Занятно, спасибо.
А я вообще как-то $() никогда не юзал. А документированные различия между ними есть?
darkk
6 окт, 2011 21:04 (UTC)
В man bash всё описано о различиях в секции Command Substitution.
( 4 комментария — Оставить комментарий )

Profile

darkk
Leonid Evdokimov
Website
Разработано LiveJournal.com
Designed by Tiffany Chow