astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

働きたくないのでコードを自動生成してみたよ

こんにちは、開発部のNishikawaです。

今日はScala と Play frameworkを使ってコードの自動生成を行なった時の話をまとめたいと思います。

どうしてこの記事を書こうと思ったか

Webアプリケーションの開発をしていると、よく本質じゃないところに時間がかかることがままあります。

例えば、データアクセス部分とか、コントローラの実装部分です。プログラムとしての責務がちゃんと別れれば別れるほど刺身たんぽぽ感が出てくるので、心を無にしてひたすらコピペとクラス名やメソッド名などの修正を行う人が多いと思います。

しかし、心を無にして釈迦のような志のもと作業を行なっていても所詮は人間なのでミスは起こります。そうすると、釈迦のような志から一変、鬼の形相でひたすらバグを潰しさらに時間がなくなるという無駄が無駄を産む状況になりがちです。

そういうのは一人で仕事を進める上ではとても無駄だし、本当に避けたい状況です。そこで目をつけたのはコードの自動生成です。

実際どういう作戦で何をしたのか

一括りにコードの自動生成と言っても、使うにはやはり一定の条件があります。今回Webアプリケーションを作成するにあたり以下のような構成のプログラムの実装を行いました。

  • ビュー
実装はhtmlとjavascriptで行い、バックエンド側のAPIから情報を取得しレンダリングする。
  • コントローラ
REST APIの口を設けてView層からのリクエストを受け付ける
  • モデル
データへのアクセスはSlickを使用し、取得した値をプレゼンテーション層へ渡すためのモデルに移し替える

今回はコードを自動生成するにあたり以下のsbtプラグインとライブラリを使用しました。

  • sbt-swagger-codegen

https://github.com/unicredit/sbt-swagger-codegen

  • slick-codegen

http://slick.lightbend.com/doc/3.2.0/code-generation.html

  • flyway-play

https://github.com/flyway/flyway-play

sbt-swagger-codegen

これは、sbtのプラグインでswagger specからPlay framework のコントローラとroutesファイル、json返却用のモデルを生成してくれます。

slick-codegen

これはデータベースにある実際のテーブル構造からSlickのコードを自動生成してくれます。

flyway-play

これはflywayのPlay framework用ライブラリです。これを使ってSQLを管理しました。

コード生成

前提

実際にコード生成を行う前に前提として、今回コード生成に使用したプロジェクトのディレクトリ構成を記載します。

example-web      =============================================== > プロジェクトディレクトリ
├── app
│   ├── ErrorHandler.scala
│   ├── Module.scala
│   ├── com
│   │   └── astamuse
│   │       └── ・・・
│   └── infrastructure
│       └── models
│           └── postgresql
│               └── Tables.scala  ============================== > 今回自動生成したSlickコード。
├── build.sbt
├── conf
│   ├── application.conf
│   ├── db
│   │   └── migration
│   │       └── default
│   │           ├── V1.0.0__example_database_web_app.sql    == > flayway用のDDL その1。
│   │           └── V1.0.1__example_database_dummy_api.sql  == > flayway用のDDL その2。
│   ├── logback.xml
│   └── routes  ================================================ > 今回sbt-swagger-codegenで自動生成したroutesファイル。
├── docs
│   └── swagger
│       └── ExampleWebAPIController.yaml
├── project
│   ├── build.properties
│   ├── plugins.sbt
│   ├── project
│   │   └── target
│   └── target
├── target
│   ├── scala-2.12
│   │   ├── classes
│   │   ├── resolution-cache
│   │   ├── routes
│   │   ├── src_managed
│   │   │   └── main  ========================================== > 自動生成されたコードが本来格納されるディレクトリ。今回sbt-swagger-codegenで自動生成したコントローラやモデルなどのコードが格納される。
│   │   │       └── swagger
│   │   │           └── codegen
│   │   │               ├── Model.scala
│   │   │               ├── controller
│   │   │               │   └── ExampleWebAPIController.scala
│   │   │               └── json
│   │   │                   └── package.scala
│   │   └── test-classes
│   ├── streams
│   └── test-reports
└── test  ====================================================== > テストディレクトリ
    └── generator
        └── slick
            └── SlickCodeGenerator.scala  ====================== > 今回はテストコードでslickのコードを生成するためのプログラムを書きました。

Slickコードの自動生成

ここからは、実際にSlickコードを自動生成する方法について述べます。

Slickのコード生成をするためにsbtに以下を書き込みライブラリを追加します。

libraryDependencies ++= Seq(
  "com.typesafe.slick" %% "slick-codegen" % "3.3.0"
  ,"org.flywaydb" %% "flyway-play" % "5.2.0"
)

追加したらプロジェクトディレクトリ配下の「conf/db/migration/default」にflywayのファイル命名規則に則りDDLを作成します。

作成したら以下のコードをテストディレクトリに作成します。

注意)今回は諸々省くためにテストコードに実装を行なっております。

package generator.slick

import org.flywaydb.core.Flyway
import org.scalatest.WordSpec
import play.api.Logger
import slick.jdbc.H2Profile.api._
import slick.codegen.SourceCodeGenerator

class SlickCodeGenerator extends WordSpec {

  private val logger: Logger = Logger("verification")

  "Generated code due to access to postgresql for slick." in {
    logger.debug("Start slick verification.")

    // Basic information
    val slickProfile = "slick.jdbc.PostgresProfile"
    val jdbcDriver = "org.postgresql.Driver"
    val url = "jdbc:postgresql://localhost:5432/example_db"
    val user = "admin"
    val password = ""
    val outputDirectory = "app"
    val pkg = "infrastructure.models.postgresql"

    // Execute migration for flyway
    val flyway: Flyway = Flyway.configure().dataSource(url , user, password).load()
    flyway.migrate()

    // Execute code generate for slick
    val args: Array[String] = Array( slickProfile, jdbcDriver, url, outputDirectory, pkg, user, password )
    SourceCodeGenerator.main(args)

    logger.debug("End slick verification.")

    true === true
  }
}

以上を記載したら、ローカル環境でPostgreSQLを起動し、コードに記載した内容でログインできることを確認したのちに実行します。

$ sbt "testOnly generator.slick.SlickCodeGenerator"

実行が完了したら、プロジェクトディレクトリの「app/infrastructure/models/postgresql」にコードが生成されていると思います。

Swagger Specからのroutesファイルおよびコントローラとモデルの自動生成

次はSwagger Specからroutesファイルとコントローラ、モデルを生成していきます。

sbtに以下のプラグインを追加します。

  • project/plugin.sbt
addSbtPlugin("eu.unicredit" % "sbt-swagger-codegen" % "0.0.11")

プラグインを追加したら、プロジェクトにプラグインを有効にし、 Play frameworkのディレクトリレイアウトのプラグインは無効にします。

  • build.sbt
lazy val `example-web` = (project in file("."))
  .enablePlugins(PlayScala)
  .disablePlugins(PlayLayoutPlugin)
  .enablePlugins(SwaggerCodegenPlugin)

・・・
(中略)
・・・

scalaSource in Compile := baseDirectory.value / "app"
resourceDirectory in Compile := baseDirectory.value / "conf"
scalaSource in Test := baseDirectory.value / "test"
resourceDirectory in Test := baseDirectory.value / "conf"

// Custom Settings
// For swagger
swaggerCodeProvidedPackage := "com.astamuse.example"
swaggerSourcesDir := file("docs/swagger")
swaggerGenerateServer := true

swaggerModelCodeTargetDir := file("target/scala-2.12/src_managed/main")
swaggerServerCodeTargetDir := file("target/scala-2.12/src_managed/main")

以下を記載したら、プロジェクトディレクトリ配下に「docs/swagger」ディレクトリを作成し、そこにSwagger Specを配置します。

諸々の配置が完了したら以下のコマンドを実行します。

$ sbt swaggerRoutesCodeGen
$ sbt compile

コマンドの実行が完了すると、「target/scala-2.12/src_managed/main」配下にコードが作成されそれを含めた状態でアプリケーションをコンパイルしてくれます。

まとめると・・・

いかがslick-codegenとsbt-swagger-codegenを利用するために使った設定ファイルの内容です。

  • project/plugin.sbt
logLevel := Level.Warn

resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.0")
addSbtPlugin("eu.unicredit" % "sbt-swagger-codegen" % "0.0.11")
  • build.sbt
//SwaggerCodegenPlyginのインポート
import eu.unicredit.swagger.SwaggerCodegenPlugin

name := "example-web"

version := "1.0.0"

lazy val `example-web` = (project in file("."))
  .enablePlugins(PlayScala)
  .disablePlugins(PlayLayoutPlugin)
  .enablePlugins(SwaggerCodegenPlugin)

resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"

resolvers += "Akka Snapshot Repository" at "http://repo.akka.io/snapshots/"

scalaVersion := "2.12.2"

libraryDependencies ++= Seq(
  ehcache
  ,ws
  ,guice
  ,"com.typesafe.play" %% "play-slick" % "4.0.0"
  ,"com.typesafe.slick" %% "slick-codegen" % "3.3.0"
  ,"org.flywaydb" %% "flyway-play" % "5.2.0"
  ,"org.postgresql" % "postgresql" % "42.2.5"
  ,"org.scalatestplus.play" %% "scalatestplus-play" % "4.0.0" % Test
  ,"com.h2database" % "h2" % "1.4.197" % Test
)

unmanagedResourceDirectories in Test +=  baseDirectory ( _ /"target/web/public/test" ).value

testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "exclude", "SLICK_CODE_GENERATE")

scalaSource in Compile := baseDirectory.value / "app"
resourceDirectory in Compile := baseDirectory.value / "conf"
scalaSource in Test := baseDirectory.value / "test"
resourceDirectory in Test := baseDirectory.value / "conf"

// Custom Settings
// For swagger
swaggerCodeProvidedPackage := "com.astamuse.example"
swaggerSourcesDir := file("docs/swagger")
swaggerGenerateServer := true

swaggerModelCodeTargetDir := file("target/scala-2.12/src_managed/main")
swaggerServerCodeTargetDir := file("target/scala-2.12/src_managed/main")

以下に躓きやすいところを記載しておきます。

なぜPlay frameworkのディレクトリレイアウトのプラグインを無効にするのか。

Play frameworkのディレクトリレイアウトを利用するとコントローラのパッケージが「app/controllers」配下に固定されるので、コード生成したコントーラを読み込んでくれないためです。(もしかしたら他にやり方があるかもしれない)

なぜPostgreSQLを使ってコード生成するのか

h2を使って生成を試みたが、なぜかうまくいかなかったので泣く泣くPostgreSQLを利用しました。今後はh2で生成できるようにするつもりです。

今後に向けての課題

今回はSwaggerでの生成部分については「target/scala-2.12/src_managed/main」にコードを吐き出しましたが、Slickについてはそれができませんでした。 理由はh2を利用してのコード生成ができなかったためです。

なぜ、h2が使えないと「target/scala-2.12/src_managed/main」にコードが吐けないかというと、このディレクトリは毎回コンパイルのたびにコードを生成するためのものを配置するようにできております。そのため、何度コンパイルしてもコード生成を成功させてコードを配置しなければならないのですが、flywayを使っている以上、重複してDDLを実行するとエラーになります。そのため今回のようにコードの生成を「app」配下にし固定することでこの問題を回避しました。

今後はここの技術課題を克服してDAO部分も完全にコード管理しないようにしていきたいと思います。

まとめ

今回はコード生成に向けて色々と作り込みを行いました。この方法はあくまで少人数・・・というか個人で何かものを短期間で作らないといけない場合に有効だと思っております。

ピーキーな実装が求められるところについてはあまりお勧めできませんが、人数に関係なくコード実装量を減らしてくれる上、コードの管理量も減るため、試しに採用してみてはいかがでしょうか。

以上

オフィス移転したので移転ポイント・反省をまとめてみた

f:id:astamuse:20190306203706j:plain

こんにちは、アスタミューゼでデザイナーをしている@YojiShirakiです。

実は弊社アスタミューゼは先の2月25日にオフィスを移転しまして、今回、移転担当をやらせて頂いたので記録と反省をまとめてみました。


目次

今回の引っ越しの規模感

弊社の基本的な規模感はだいたい以下です。移転直前で2.7坪/人になっているので、そこまで窮屈という程でもありません。しかし、昨今のIT企業だと坪/人が3坪以上というのもザラにあるので、もう少し空間的にゆとりを持たせたいなというレベル感です(フリースペースなど)。

項目
在籍員数 70人前後(出向、業務委託、派遣等含む)
移転前の坪数 190坪
一人あたり坪数 2.7坪
移転前の立地 築地(東銀座駅 徒歩1分)

ちなみに、築地に移転してきた直後の人数が50人弱でした。

移転のステップ

移転のステップは以下のような流れです。

  1. 不動産・仲介に連絡
  2. プランニング会社選定
  3. 内覧
  4. 物件決定(社内承認)
  5. 設計
  6. インフラ・ネットワーク手配
  7. 設計詰め
  8. 移転準備
  9. 移転
  10. 行政手続き(登記など)

今回はもっと良いオフィスにしたいという想いもありプランニング・プロマネ会社さんにご協力いただきました。

ちなみに、これまで弊社はプランニング・プロマネ会社を使わずに自力での移転をやってきましたが、もう無理です。

全体スケジュール

オフィス移転は半年かかると言われてます。専任者がいるならその見積もりで大丈夫だと思います。弊社の場合は専任者がいないためもう少し時間がかかりました。

やったこと
5月末 プランニング会社・不動産会社に声がけ
6月 方針策定、内覧、プランニング会社比較
7月 内覧、取締役会で大枠の方針合意(予算・規模など)
8月 候補絞って代表を伴って内覧、取締役会オフィス決議
9月 プランニング会社決定、レイアウト方針調整
10月 現行オフィスの満足度調査、ビル打ち合わせ
11月 レイアウト調整、ビル打ち合わせ、インフラ関係打ち合わせ
12月 レイアウト調整、インフラ・電話関係、既存什器整理、新規什器検討
1月 レイアウト調整、インフラ・電話関係、細かい詰め(壁塗装、造作物張り地など)
2月 インフラ・電話関係、細かい詰め(壁塗装、造作物張り地など)

意外に時間かかっのは非機能要件・感性要件でした。「○○っぽい感じにしたい」という社内の要望を意匠にどう落とし込むのか。言語化してプランニング会社さんと一緒に落とし込みするのは難しかったなぁ、と思います。

オフィス検討方法

オフィス選定は様々な要素が絡んできます。大前提「予算」というものがあり、その他の諸々ある要求の中から、今回は優先的な要求を3つに絞りました。

  • キャパシティ(人員数)
  • ブランディング(採用、PR)
  • 交通(日々の負荷)

弊社の全社戦略で2019年は採用優先順位が凄まじく高く、そこにどう資するかを検討した結果です。一つ一つ見ていきましょう。

キャパシティ

オフィスキャパシティは採用計画を踏まえ先2年を想定しました。ここは余裕持ったキャパシティを検討したいところです。が、あまりアッパーに想定すると月々のお家賃が大変なことになります。絶妙なバランスを読みたいポイントです。

また、ここでは賃貸借契約の最低契約期間に留意してください。キャパの限界が来るタイミングで最低契約期間終了が見えてないと次の移転を想定できなくなります。

ブランディング

ブランディングはオフィス物件のビル格であったり立地場所の格などです。今回は採用計画に資するようなオフィスを念頭にビル格・ビル品質感にやや重きを置きました。弊社のクライアント様が上級職の方たちばかりという背景もあります。

あとは単純に会社のメンバーもかっこいいオフィスの方が働く意欲も湧くだろう、と。

交通

交通については、全社員の居住エリアと路線を調査し通勤のしやすさを配慮します。地味に大変ですが内覧時に具体的な路線の良し悪しのイメージが湧くのは個人的には重要だったと感じました。

次いで来客しやすさ・外出しやすさを加味します。つまりJRや主要メトロ路線との距離などです。弊社は全体の約1/3が営業職、コンサル職など外勤職であり彼らの足回りへの影響はだいぶ意識しました。

その他 オフィスチェックポイント

その他、細かい要因も上げておきます。上から順に意識した順です。

項目 コメント
フリーレント期間 契約段階でオーナー様とご相談
空調 個別 or セントラル。セントラルで温度調整効かないと社員の生産性が著しく落ちます(調査済)
時間外空調費用 古いビルの場合、この金額が意外に大きい
周辺飲食環境 ランチ平均金額、店舗数など。入居後に評価されるポイントです
喫煙所 いくつかの物件では喫煙所が無いところもありましたので念の為
トイレ個室数 古い物件だと人数に対して個室の数が少ないケースがあります
天井高 高いほうがおしゃれ(天井抜けばいいですが施工が大変です)
避難経路 人命に関わるところなので

飲食事情については日々の潤いですから、極力配慮してあげたいところでした。

で、どんな感じなったの?

色々書きましたが、結局こちらに移転しました。

BIZCORE神保町 www.bizcore-office.com

ほぼ新築の中規模オフィスビルブランドです。屋上がテラスになっており、平日に食事すると気分のいい共有部分が魅力的な建物です。

実際、BEFORE/AFTERでどんな印象変化があったのか比較してみましょう。

BEFORE

(あんまりいい写真がなかったので移転作業時の写真です)

f:id:astamuse:20190306202200j:plain
すでに段ボールが積まれてますが、大体の印象はこんな感じでした。

f:id:astamuse:20190306202324j:plain

AFTER

f:id:astamuse:20190306203129j:plain
エントランス。ロゴと受付端末だけのシンプルな構成です。

f:id:astamuse:20190306203238j:plain
たくさんのお花いただきました。ありがとうございます!

f:id:astamuse:20190306203327j:plain
会議スペースの廊下。フレームとガラスで透明感とシャープ感があります。

f:id:astamuse:20190306203449j:plain
会議室。壁の色はそれぞれ違う色にしています。

f:id:astamuse:20190306203706j:plain
各会議室には大型のディスプレイ設置しています。Windowsは無線で画面を映せます。

f:id:astamuse:20190306203904j:plain
ファミレスのボックス席のような席もあり、社内向けMTGで気軽に利用できます。

f:id:astamuse:20190306204145j:plain
こちら移転前日の状態。すっきりしてます。

f:id:astamuse:20190306204306j:plain
全社MTGするときに使われる雛壇。

f:id:astamuse:20190306204940j:plain
雛壇の裏側はソファになっていてカフェテーブルが置いてあります(電源もある)。

f:id:astamuse:20190306204433j:plain
実はこの雛壇動かせます。便利です。

f:id:astamuse:20190306204540j:plain
雛壇の対面は大きなスクリーンになっていて・・

f:id:astamuse:20190306204808j:plain
さらにスクリーンの裏側がカフェカウンターになっています。

f:id:astamuse:20190306205326j:plain
執務スペースは一部だけ・・。

だいたい雰囲気はこのような感じになりました。

反省

最後にいくつか反省ポイントをあげます。

細かいものも含めて本当はもの凄いあるのですが大きいものをいくつか。

1. 移転に伴う整理・断捨離を全社に2ヶ月くらい前から呼びかけるべきだった

引っ越しの立会時に痛烈に感じたのが「なんて物が多いんだ!!!」ということ。もっと事前に断捨離すべきでした。断捨離しておけばタスクの量が減りますし(既存什器の移設場所検討やオフィスキャパシティの検討など)、引っ越し当日にかかる時間を削減することができます。

引っ越し当時は長丁場ですし、予期せぬ出来事が起こるので、圧縮できる時間は事前にできるだけ圧縮するに越したことはありません。

事前の断捨離は絶対にやったほうがいいです

2. インフラ関係が後手に回り過ぎた

オフィスの物理設計の方に時間をとられてしまって、その後に控えているネットワーク・電話などの手配が完全に後手に回っていました。これは痛烈なミスでした。

特に、想定していた回線移設工事が
近隣の地下工事の影響ですぐにはできないことが発覚するなど、トラブルの発生を想定できておらずかなり肝を冷やしました(代替回線の手配で凌げましたが・・)。

電話関係についてもクラウドPBXを新規に導入するにあたって事前の動作検証を行っておけばよかったと思うことも多く、全体スケジュールの後工程になるネットワーク全般に反省の多かった移転となりました。担当のメンバーに大変ご迷惑おかけしました・・。

3. 他のプロジェクトの影響を適切に見積もれずタスク分散が遅れた

また、移転の時期に他の重要案件が重なってきてしまい時間捻出が難しくなってきたことも大きかったです。後半の作業が遅滞気味になる要因となりました。

この案件はコントローラブルとは言い難い性質であったため、早い段階でリスクとみなして作業を分散するなどのヘッジをすべきだったと思います。基本、皆、本業務があるので作業を渡しにくいところもあるのですが、早くから担当を決めてタスク分散の根回しをしておくことで突発的な遅延要因にも耐え得たなぁ、としみじみ思います。

最後に

実は移転するのこれで5回目なのですが、何回やっても大変だなぁ、としみじみ思います。

本稿が同じような想いを抱いている方の役に立つ投稿であれば嬉しいです。もし本稿について何かご質問があれば@YojiShirakiにDMお送りください。

例によって当社では一緒にサービス開発してくれるエンジニア・デザイナー・ディレクターを超絶賛募集しております。

せっかくオフィスも新しくなりましたし、遊びに来がてらお話聞きたいという方は、このブログのサイドバー下にあるアドレスか@YojiShirakiにDMいただければと思います。いつでもウェルカムですし、結構面白いお話を差し上げられると思います!採用サイトもありますので下の水色のバナーから是非どうぞ!

ではまた:- )

@YojiShirakiの過去記事)

ターミナルなんて怖くない

ご挨拶

どうもお久しぶりです、元バンドマンの新米エンジニアgucciです。
未経験からエンジニアに転職して早1年が経ちました。
「まだ1年目なもんで、てへ」というのが通用しないと思うと、気を引き締めていかないとなと思う今日この頃です。
あっという間の1年であり、忘れられない1年となりました。
2年目はエンジニアとしても人間としても、もっともっと成長していきたく思います。

ターゲット

さて、綺麗事はさておき今回のブログのターゲットは、
まだプログラミングを初めて日が浅い新米エンジニアの方
や、
これからエンジニアを目指そうという未来のエンジニアの方
でございます。
もう熟練のエンジニアの皆さんからすると物足りなかったり、もっといいのがあるよ!といった内容があるかもしれませんがご容赦くださいませ。

今回のブログの内容はタイトルにもありますように「ターミナルなんて怖くない」です。
なぜこのような内容にしたのかというのも、
私がプログラミングスクールでWebアプリケーション開発の基礎を学び、未経験エンジニアとしてこの業界に入って一番感じたことは、 ターミナルめっちゃ触る。ということです。 (windowsでいうコマンドプロンプト)

f:id:astamuse:20190213143117j:plain アプリケーションを開発するのに、Java、Scala、Ruby、PHP、Goなどなど…数々のプログラミング言語がありますが、共通して言えることはコンピュータを操作するのにターミナルでのコマンド操作が必要不可欠だということです。(もちろん、働いている環境により様々なやり方があると思いますので、あまり使わない方もいるかと思います)

「ターミナルで何ができるの?」というと、

  • ファイル・ディレクトリ(いわゆるフォルダ)を作る
  • ファイルの中を編集する
  • コピー・削除する
  • ログファイルから欲しい言葉を検索する

などなど、パソコンに対する命令はほとんどターミナルでできるのです。

「ターミナルなんか使わなくてもFinder(エクスプローラ)でいいじゃない」という意見もわかります。
わかりますが、

  • ターミナルでしか行えない操作がある
  • ターミナルの方が圧倒的に速い(場合がある)
  • FinderやエクスプローラといったGUIがない環境がある

などなど、ターミナルとは必ず向き合わないと行けない日がきます。
その反面、まだプログラミングの経験が浅い段階だとターミナルの使い方がわからなかったり、うまく使えないでイライラしてしまい「ターミナルなんて嫌い!」と感じる方もいるかもしれません。
私も最初の頃はターミナル操作が全然わからず苦手でしたが、今ではドヤ顔でコマンドを叩いております。(大したことはしていませんが)
なのでまずは少しずつコマンドを叩いてみて、コンピュータに命令を出してみましょう。
ターミナルなんて怖くないんだ、ということをまずは知っていきましょう。

今回は、
「知っていて当たり前!これだけは抑えておこうターミナルコマンド!」をご紹介します。
コマンドと合わせて、そのコマンドがどういった意味を持つのか補足をします。
英語の意味と合わせて覚えるだけで、訳の分からないコマンドがグッと身近になります。
さらに、知っておくと便利なオプションや使い方もプラスαでご紹介します。

それでは参りましょう。

よく使うコマンドたち編

cd

cd 移動先のパス

ディレクトリ間を移動する。「Change Directory」の略。

cd ..
 一つ上のディレクトリに移動。
cd -
 一つ前にいたディレクトリに移動。

ls

ls

ファイルやディレクトリを表示する。「LiSt」の略。

ls -a
 隠しファイルも含めすべて表示。「all」の略。
ls -l
 ファイルの詳細も表示。「long」の略。
ls -1
 縦一列に表示。「1列」の1が覚えやすい。

pwd

pwd

現在の作業ディレクトリのパスを表示。「Print Working Directory」の略。

cp / mv / rm / mkdir

cp コピーする元 コピーする先

ファイルやディレクトリをコピーする。「CoPy」の略。

cp -r コピー元ディレクトリ コピー先ディレクトリ
 ディレクトリごとコピーする。「recursive(再帰的)」の略。←他のコマンドでもよく使うオプション。

mv 移動する元(移動するファイル名) 移動する先
mv 変更前の名前 変更後の名前

ファイルやディレクトリを移動する。また、名前を変更するのにも使う。 「MoVe」の略。

mv -v 移動する元(移動するファイル名) 移動する先
 移動の詳細を表示。「verbose」の略。←他のコマンドでもよく使うオプション。

rm ファイル名

ファイルやディレクトリを削除する。「ReMove」の略。

rm *
 全てのファイルを削除する。*はワイルドカードで、色々な場面で使う。
rm -f
 警告メッセージを表示せずに削除する。「force(強制する)」の略。フォースの力。

mkdir

ディレクトリを作成する。「MaKe DIRectory」の略。
rmdirというディレクトリを削除するコマンドもある。

less/cat

less ファイル名

ファイルの内容を一画面ずつ表示する。moreの対義語。(moreというコマンドが存在するがあまり使わない)
lessでファイルの内容を表示後
 「/」キーワード前方検索。
 「?」キーワード後方検索。
 「q」を入力して終了。

cat ファイル名

ファイルの内容を最後まで続けて表示。「conCATenate(連結する)」 の略。

cat -n
 行番号をつけて表示。「number」の略。

tail ファイル名

最終行から数行を表示する。標準では10行。そのまま「尾」という意味。

tail -f ファイル名
 ファイルの追記を監視し、追記分を表示する。「follow」の略。
 ログの監視をしている際などによく使用する。

diff

diff ファイルA ファイルB

ファイル同士の差分を表示する。「difference」の略。

diff -y ファイルA ファイルB
 比較した結果を横並びで表示。「side-by-side形式」の略。
 「横(yoko)」の「y」が覚えやすい。

grep

grep 検索正規表現 ファイル名

ファイル中の文字列に対して正規表現を使って検索して表示する。「Global Regular Expression Print」の略。

grep -i 検索正規表現 ファイル名
 大文字と小文字を区別せず検索する。「ignore-case」の略。

コマンドの標準出力 | grep 検索正規表現
 このように「|(パイプ)」でつないで、コマンドの実行結果に対して検索をかけて抽出する使い方がとても便利。

scp

scp コピーするファイル名 コピー先のリモートのホスト:パス名
scp コピーするリモートのホスト:パス名/ファイル名 コピー先のローカルパス名

ローカルとリモートサーバ間でファイルの転送を行う。「Secure CoPy」の略。

scp -r コピー元 コピー先
 ディレクトリごとコピーする。「recursive(再帰的)」の略。(再登場)

サーバでよく使う編

du / df

du

ファイルのディスク使用量を推定する。「Disk Usage」の略。

df

ファイルシステムのディスク容量の使用状況を表示する。「Disk Free」の略。

-hオプション
 単位を見やすい形にして表示してくれる。「human-readable」の略。

ps

ps

現在動作しているプロセスを表示する。「Process Status」の略。

ps aux
 よく使うauxオプションは、aとuとxの合わせ技。
 a 端末を持つ全てのプロセスを表示
 u ユーザー名を表示
 x 端末を持たない全てのプロセスを表示

free

free

macにはないLinuxコマンド。現在のメモリ使用量を確認。Swapの使用状況などを確認することができる。

free -m
 メガバイト単位で表示。

top

top

現在のシステム全体の負荷情報を表示する。
LinuxだとCPU使用率順で出るが、macだと表示の仕方が異なる。

vmstat

vmstat

macにはないLinuxコマンド。メモリやCPUの情報だけでなく、スワップやディスクI/Oの情報を表示する。 「Virtual Memory STATistics」の略。

vmstat 1
 1秒ごとに更新して表示。

ちょっとしたお助けコマンド編

man

man コマンド名

マニュアルを表示する。「MANual」の略。
ここまで色々と書いてきましたが、manコマンドで叩けば全て乗っている。 コマンドの使い方やオプションについて調べたい時に便利。

which

which コマンド名

コマンドを探し出し、フルパスで表示する。
使いたいコマンドがマシンに入っているか調べたい時に便利。

ちょい足しプラスα編

タブ補完

とにかく便利なタブ補完。
ファイル名やディレクトリ名を途中まで打って、キーボードの「Tab」キーを押すと、該当する名前を自動で入力補完してくれる。超絶便利。 同じようなファイル名のものが複数あった場合は、名称が同じ部分まで補完。

ログアウト

ctrl + d

サーバに入っている時などにlogoutexitと叩くとサーバから出ることができるが、このショートカットキーを叩くと同様の操作が行える。

強制終了

ctrl + c

なにかプログラムやコマンドを実行している時に、強制的に終了してくれるのがこのショートカットキー。

クリア

ctrl + l

clearコマンドという画面をクリアしてくれるコマンドがあるが、このショートカットキーでもクリアしてくれる。何かと画面に色々出力していて、見にくくなってしまっても一発で綺麗に。

過去検索

ctrl + r

過去に叩いたコマンドを探したくなることがよくある。
historyというコマンドで履歴を表示することもできるが、もっとお便利なのがこのコマンド。
ctrl + rを叩くと表示が「(reverse-i-search)...」と変わる。
ここで文字を入力していくと、入力された文字を含む過去に叩いたコマンドが右側に出てくる。
表示されるものが欲しいものと違ったら、再びctrl + rを叩けばどんどん遡ってくれる。

最後に

以上で今回のご紹介はおしまいです。
コマンドにはたくさんのオプションがあって、色々な組み合わせ方ができるとても便利なものです。
少しずつ慣れていくことで、少しずつターミナルと仲良くなっていきましょう。
他にもたくさんのまとめブログや記事があると思いますので、色々と見てみることをおすすめします。
このブログを読んでいただいて、
「このコマンドはこんな意味だったのか〜」「こんなお便利なものがあったのね」
となり、ターミナルと仲良くなる入り口になれたなら幸いです。

アスタミューゼでは、エンジニア・デザイナーを募集中です。
ご興味のある方は下記バナーからチェックして頂き、ぜひぜひご応募ください!お待ちしています。
ではまた。

Copyright © astamuse company, ltd. all rights reserved.