Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

0

Share

Download to read offline

Ruby での外部コマンドの実行について

Download to read offline

大手町.rb #16発表資料

Related Books

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Ruby での外部コマンドの実行について

  1. 1. Ruby での 外部コマンドの実行について 2019/04/10 大手町.rb #16
  2. 2. 大手町.rb #16 「Ruby での外部コマンドの実行について」 1自己紹介 Tomoya Kawanishi a.k.a. @cuzic エネチェンジ株式会社 チーフエンジニア 電力会社、ガス会社を切り替えるなら、エネチェンジ経由で! 一般家庭も!法人も! Ruby関西の中の人 2019年5月11日 第86回Ruby関西勉強会 2019年7月13日 第87回Ruby関西勉強会 発表者として登壇くださる方、あとで声かけください。 大手町.rb の中の人 毎月 大手町.rb の開催を予定 東京駅、各線大手町駅から直結! Ruby の初級者がメインターゲット
  3. 3. 大手町.rb #16 「Ruby での外部コマンドの実行について」 今日のテーマ Ruby での外部コマンドの実行について 外部コマンド ruby では system コマンド echo 、time、ruby などすべて外部コマンド Ruby はグルー言語としてとても優秀 グルー = のり(糊) いろんな処理をくっつけて、新しい処理を組み立てるときに 使う言語を グルー言語 と呼ぶ すでにいろんなベンリな機能がたくさんあるわけだし、 グルー言語として、実現する方がカンタンかつ速い! 2
  4. 4. 大手町.rb #16 「Ruby での外部コマンドの実行について」 ` ` (backtick)、 %x()、%X() `` 、%x で簡単に外部コマンドの実行結果が取得可能 3 `aws configure get aws_access_key_id`.chomp #=> "AKIA...........A" `git config user.name`.chomp #=> "cuzic" # `` と %x は式展開する field = "user.name" `echo #{field}"`.chomp #=> "user.name" %x(echo #{field}").chomp #=> "user.name" # %X だと式展開しない %X(echo #{field}").chomp #=> "#{field}"
  5. 5. 大手町.rb #16 「Ruby での外部コマンドの実行について」 Kernel.system 外部コマンドを実行し、成功したときに真が返る 4 system("echo Hello, World!") # PATH で見つかる echo を呼ぶ system("echo /dev/z*") # ワイルドカードも書ける。シェル経由で実行される。 system('echo –n a¥nb') # /bin/echo は bash の echo と挙動が異なる。 # 成功するときは、true が返る system("true") #=> true # 失敗するときは false が返る system("false") #=> false # ; 区切りで複数コマンド実行できる system("echo 1 ; echo 2") # 改行区切りでも複数コマンド実行できる system("echo 1 ¥n echo 2") # 該当のコマンドが実行できないときは nil が返る system("sad") #=> nil
  6. 6. 大手町.rb #16 「Ruby での外部コマンドの実行について」 system の高度な利用 5 # 配列で引数を渡すこともできる system("ssh", hostname, "bash –l –c 'cd repo; bin/rails c'") # exception: true を指定すると、 nil が返るのではなく例外を raiseする system("sad", exception: true) #=> Errno::ENOENT (No such file or directory - sad) # unsetenv_others: true を指定すると、環境変数をクリアする system("echo $HOME") # "/home/cuzic" などが表示される system("echo $HOME", unsetenv_others: true) # 何も表示されない # bundle exec の中で ruby コマンドを実行するときとか便利 # 第1引数で環境変数を指定できる system({"FOO"=>"BAR"}, "echo $FOO") # chdir オプションで子プロセスのカレントディレクトリを変更できる # "cd /tmp; pwd" とすると、シェル経由で実行されるが、 # 下記はシェルを経由せず、実行される system("pwd", chdir: "/tmp")
  7. 7. 大手町.rb #16 「Ruby での外部コマンドの実行について」 Kernel.exec exec で実行すると ruby インタプリタを置き換える ruby で ssh を wrap したい時とかベンリ 6 STDIN.close STDOUT.close system("ssh production-server") # `system': closed stream (IOError) STDIN.close STDOUT.close exec("ssh production-server") # ふつうに ssh できる! system("ssh production-server") puts "ssh finished" # ssh 終了後、実行、表示される exec("ssh production-server") puts "ssh finished" # ssh 終了してもこの行は決して実行されない
  8. 8. 大手町.rb #16 「Ruby での外部コマンドの実行について」 shellwords Array#shelljoin 、String#shellescape がベンリ 7 # system メソッドに配列で引数を渡す system("ssh", hostname, "bash –l –c 'cd repo; bin/rails version'") # String#shellescape rails_version = "bash –l –c 'cd repo; bin/rails version'" require 'shellwords' rails_version.shellescape #=> "bash¥¥ ¥¥–l¥¥ ¥¥–c¥¥ ¥¥'cd¥¥ repo¥¥;¥¥ bin/rails¥¥ version¥¥'" # Array#shelljoin cmdline = ["ssh", hostname, rails_version].shelljoin #=> "ssh production-server bash¥¥ ¥¥–l¥¥ ¥¥–c¥¥ ¥¥'cd¥¥ repo¥¥;¥¥ bin/rails¥¥ version¥¥'" # system メソッドに文字列で渡す `#{cmdline}` #=> "Rails 5.0.7¥n"
  9. 9. 大手町.rb #16 「Ruby での外部コマンドの実行について」 IO.popen IO.popen で、標準入力からの値の取得ができる エンコーディングの指定もできる 標準エラー出力も受け取れる 8 env = {"PGUSER"=>"scott", "PGPASSWORD"=>"tiger"} body = IO.popen(env, "psql template1", "r+") do |io| io.puts '¥dS+' io.close_write io.read end puts body IO.popen("nkf –s README.md", external_encoding: "CP932", &:read) IO.popen("ls /nothing", err: %i(child out), &:read) #=> "ls: /nothing にアクセスできません: そのようなファイルやディレクトリはあり ません¥n"
  10. 10. 大手町.rb #16 「Ruby での外部コマンドの実行について」 Open3.capture3 標準入力への入力、標準出力、標準エラー出力の取得が 一度にできてとてもベンリ! 環境変数の設定などもできる 9 require 'open3' env = {"PGUSER"=>"scott", "PGPASSWORD"=>"tiger"} sql = <<'EOD' ¥d selct 1 + 1; EOD options = {stdin_data: sql} o, e, s = Open3.capture3(env, "psql", "template1", options) p o #=> "リレーションがありません。¥n" p e #=> "ERROR: ¥"selct¥"またはその近辺で構文エラー¥n行 1:" p s #=> #<Process::Status: pid 21358 exit 0> select を typo してる!
  11. 11. 大手町.rb #16 「Ruby での外部コマンドの実行について」 expect PTY と expect でインタラクティブ操作も自動化できる 非常に多数の L2SW やルータを自動制御したいときとか便利 10 require 'pty' require 'expect' username, password, database = "scott", "tiger", "template1" PTY.getpty("psql –U #{username} #{database}") do |i, o| o.sync = true i.expect(/パスワード:/) do o.puts password i.expect(/#{database}/) do o.puts "¥¥d" i.expect(/#{database}/) do |result| puts result end end end end
  12. 12. 大手町.rb #16 「Ruby での外部コマンドの実行について」 まとめ Ruby での外部コマンドの実行方法についていろいろ紹介 しました 開発生産性を改善するには ・あるものは使う。つなぐ というのが大切です Rubyはいろんなライブラリが用意されているので どんな状況でもたいてい自動化することができます 今日の説明が今後の開発にお役立ちできるとうれしいです 11
  13. 13. ご清聴ありがとう ございました

大手町.rb #16発表資料

Views

Total views

5,261

On Slideshare

0

From embeds

0

Number of embeds

72

Actions

Downloads

4

Shares

0

Comments

0

Likes

0

×