W duchu .ONESHELL możliwe jest zbliżenie się do trudnych środowisk .ONESHELL:
define _oneshell_newline_
endef
define oneshell
@eval "$$(printf '%s\n' '$(strip \
$(subst $(_oneshell_newline_),\n, \
$(subst \,\/, \
$(subst /,//, \
$(subst ','"'"',$(1))))))' | \
sed -e 's,\\n,\n,g' -e 's,\\/,\\,g' -e 's,//,/,g')"
endef
Przykład użycia mógłby wyglądać następująco:
define TEST
printf '>\n%s\n' "Hello
World\n/$$$$/"
endef
all:
$(call oneshell,$(TEST))
To pokazuje wynik (zakładając pid 27801):
>
Hello
World\n/27801/
Takie podejście pozwala na dodatkowe funkcje:
define oneshell
@eval "set -eux ; $$(printf '%s\n' '$(strip \
$(subst $(_oneshell_newline_),\n, \
$(subst \,\/, \
$(subst /,//, \
$(subst ','"'"',$(1))))))' | \
sed -e 's,\\n,\n,g' -e 's,\\/,\\,g' -e 's,//,/,g')"
endef
Te opcje powłoki:
- Wydrukuj każde polecenie w trakcie jego wykonywania
- Zakończ przy pierwszym nieudanym poleceniu
- Traktuj użycie niezdefiniowanych zmiennych powłoki jako błąd
Prawdopodobnie nasuną się inne interesujące możliwości.
export ANNOUNCE_BODY
ustawia zmienną tylko w regułach - nie pozwala na odwoływanie się do $$ ANNOUNCE_BODY w celu zdefiniowania innych zmiennych.