約束の地

キャロ組

Itamae でシェルのコマンドをそのまま実行する 3つ の方法

答え

ここにあります*1

3つの方法のそれぞれの具体例

1. run_commandメソッドを用いて引数にコマンドを書く

こんな感じです。

run_command('touch hello_itamae.txt')

戻り値に対して#stdout#exit_statusというメソッドを使うこともできます。

2. defineメソッドを用いてメソッドとして定義する

コマンド実行メソッドそれ自体を、別途メソッドとして定義します。定義されるコマンド実行メソッドは複数あっても構いません。以下のようにdefineで定義します。this_method_contains_run_commandsという命名でメソッドを定義しています。

define :this_method_contains_run_commands do
  run_command('touch good_morning.txt')
  run_command('touch good_evening.txt')
end

定義したメソッドを実行する際は引数が必須のようです(らしい。Chef-like ということだが、私は Chef を触ったことがないので分からない……)。具体的なドキュメントは以下にあります。

上で定義したthis_method_contains_run_commandsというメソッドを実行してみましょう。引数は適当なものでいいので*2、ここではnilとしました。

run_command_in_definition nil

以上で、touch good_morning.txttouch good_evening.txtが生成されたはずです。

3. executeメソッドを用いてコマンドを実行する

executeの引数にコマンドを与えればそれが実行されます。ここまでですとrun_commandメソッドと同じです*3

run_commandメソッドと異なるのは、executeメソッドはブロックを受け取ることができるという点です。このブロック内部にコマンド(など)を記述すると、最初の引数の実行コマンドに続けて、ブロック内部のコマンドを実行してくれます。

「2. defineメソッドを用いてメソッドとして定義する」の内容と同じことをexecuteメソッドを用いて実行する例を考えます。コードは以下のようになります。

execute 'touch good_morning.txt' do
  run_command('touch good_evening.txt')
end

run_commandメソッドをダラダラと連ねたくない場合に有効です(なんだと思います)。

注意

私は見習いの板前です。

*1:local_ruby_block についてはこの記事では省略

*2:メソッド内部で使用しないならば

*3:事実、受け取るブロックの中身が空っぽだったら挙動は同じです

Powered by はてなブログ