🦧

systemで複数のコマンドを順に実行する

2023/03/19に公開

やりたいこと

  • コマンドラインで実行した一連のコマンドを Rake や Thor に取り込みたい
    • 同じコマンドを二度と入力したくない
    • 実行可能なドキュメントの意味もある
  • 逆にそのタスクから数行だけをターミナルにコピペで実行したい
    • そういうときもある
    • なのでコマンドラインで実行した通り一行ごとにコマンドが並んでいてほしい

方法1: シンプル

system <<~EOT
  echo A
  false
  echo B
EOT

これでもいいけど途中失敗しても処理が続行してたまにわけがわからなくなることがある

方法2: exception: true

system <<~EOT, exception: true
  echo A
  false
  echo B
EOT

それっぽいオプションをつけてみるが最後のコマンドにしか反応してくれない

方法3: 繋ぎまくる

system <<~EOT, exception: true
  echo A && false && echo B
EOT

一行になってしまったらうまくコピペができないしpackage.json の scripts みたいになって目を伏せたくなる

方法4: 複数行化

system <<~EOT, exception: true
true &&
  echo A &&
  false &&
  echo B &&
  true
EOT

コピペしたとき && のせいですぐに実行できないのが困る
先頭の true && はエディタに次の行のインデントを揃えさせるため

方法5: 利用者が本当に必要だったもの

system "sh", "-vec", <<~EOT, exception: true
  echo A
  false
  echo B
EOT

ついでに -v で実行するコマンドを表示するようにしたらより便利になった

方法6: 邪道

def system!(command)
  command.each_line(chomp: true) do |command|
    puts command
    system command, exception: true
  end
end

system! <<~EOT
  echo A
  false
  echo B
EOT

sh -vec 風の system を別途作るのは反則

Discussion