버그 발생 조건
- BashOperator 의 bash_command 가
.sh
로 끝나면서 template_searchpath
지정하지 않았을 때 발생
원인
- Airflow Opeator는
template_ext
로 특정 파일 확장자를 가진 파일 내용을 Jinja 템플릿으로 렌더링 가능하게 설정.
- 확장자가 매칭될 경우 런타임에 동적으로 템플릿화하여 적용
- 내부적으로
endswith()
로 파일 확장자를 체크하는 방식
BashOperator
는 template_ext
로 .sh
, .bash
지정
- Jinja 템플릿 없이 실행하려면 공백을 추가하도록 가이드
- Jinja template 을 사용할 경우 공백 추가하지 않고
template_searchpath
을 명시할 것 (template 을 찾을 수 있도록)
- 공백이 없을 때 template 을 찾지 못하게 되면 스크립트를 템플릿화할 수 없어서 런타임에
TemplateNotFound
오류가 발생
class BashOperator(BaseOperator):
template_fields: Sequence[str] = ("bash_command", "env", "cwd")
template_fields_renderers = {"bash_command": "bash", "env": "json"}
template_ext: Sequence[str] = (".sh", ".bash")
...
.. note::
To simply execute a ``.sh`` or ``.bash`` script (without any Jinja template), add a space after the
script name ``bash_command`` argument -- for example ``bash_command="my_script.sh "``. This
is because Airflow tries to load this file and process it as a Jinja template when
it ends with ``.sh`` or ``.bash``.
If you have Jinja template in your script, do not put any blank space. And add the script's directory
in the DAG's ``template_searchpath``. If you specify a ``cwd``, Airflow must have write access to
this directory. The script will be rendered (Jinja template) into a new temporary file in this directory.
해결책
- jinja template 을 사용하지 않을 경우
- BashOperator 의
bash_command
가 .sh
, .bash
로 끝나지 않도록 한다. (endswith 우회)
- bash_command 뒤에 공백을 추가한다
- 스크립트 인자가 있을 경우엔 버그 발생 우회
- ex)
bash test.sh -i input.json -o output.json
reference