kaakaa Blog

この世は極楽 空にはとんぼ

commandモジュールがパイプを使えないことを経験した

という話。

LibreOfficeインストール用のPlaybookを書いてる時に、複数rpmファイルをlocalinstallする必要があったので、こんなタスクを書いた。

    - command: find LibreOffice_{{ detail_version }}_Linux_x86-64_rpm/RPMS/ -name *.rpm | xargs yum -y localinstall

エラーになった。

TASK [command] ******************************************************************
fatal: [192.168.33.14]: FAILED! => {"changed": true, "end": "2015-06-08 09:53:27.678648", "stdout": "", "cmd": ["find", "LibreOffice_4.4.3.2_Linux_x86-64_rpm/RPMS/", "-name", "*.rpm", "|", "xargs", "yum", "-y", "localinstall"], "start": "2015-06-08 09:53:27.662475", "delta": "0:00:00.016173", "stderr": "find: paths must precede expression: |\nUsage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]", "rc": 1, "invocation": {"module_name": "command", "module_args": {"_raw_params": "find LibreOffice_4.4.3.2_Linux_x86-64_rpm/RPMS/ -name *.rpm | xargs yum -y localinstall"}}, "stdout_lines": [], "warnings": []}

findの-nameオプションの引数 *.rpm をダブルクオートで囲ってないのが原因だと思って調べまくってたけど解決できず、ようやくcommandモジュールにパイプやリダイレクト等を使用できないことを知る。

ansibleでshellやcommandを使う時の注意点 - Qiita

commandモジュールじゃなくてshellモジュールを使えばいいだけだった。

    - shell: find LibreOffice_{{ detail_version }}_Linux_x86-64_rpm/RPMS/ -name *.rpm | xargs yum -y localinstall

shellモジュールの方が出来ること多いから、commandモジュールいらなくね?って疑問に言及しているエントリを見つけた。

Ansibleのshellモジュールとcommandモジュールの使い分け | bacchi.me

shellモジュールは記述されたコマンドを/bin/shで実行するけど、commandは違うよという話。 ほんまかいな。

まぁ、使えるコマンド制限されてたほうがセキュリティ的に頑丈だよねってことだろうか。


shellモジュールとcommandモジュールの違いが気になってきたのでソースを見てみた。 (結果は、よくわかりませんでした)

ansible/mod_args.py at 5622fc23bc51eebde538b582b5e020c885511f31 · ansible/ansible

shellモジュールが使われてる場合は '_uses_shell' フラグを True にして、アクション名をcommandに書き換えている。 ということは、shellもcommandも同じ動きをする?

'_uses_shell' が使われている箇所を調べるためにansible-playbook実行した時のトレースを見てみる。 Python スクリプトの動作をトレースする - とあるSIerの憂鬱

[vagrant@localhost ~]$ python -m trace --trace /usr/local/src/ansible/bin/ansible-playbook -i hosts  pptgallery-playbook.yml --ask-pass | grep '_uses_shell'
SSH password:
mod_args.py(125):             args['_uses_shell'] = True

設定されてるだけで使われてなかった。。。

とりあえずここまで。


蛇足

来日行こうか迷う。


Pallbearer - Saint Vitus 2014 - YouTube