シェルスクリプトの本を読んでシェルを書いてみた

シェルスクリプト 基本リファレンス」の本について

今回、読んでみた本は以下の「シェルスクリプト 基本リファレンス」だ。

[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

総評

まず対象としてる読者はLinux で基本的なコマンド(ls, cp, mv など)を使うことができる人となっているが、 一から説明してるので初心者でも大丈夫だ。

内容としてはBシェル系、Cシェル系の違いや「#!/bin/sh」の説明など基本的なことから、 シェルの文法、シェルのコマンドなど基礎的な事柄をしっかり説明している。 ノウハウなど一部、実践的なことも書いてある。

総評としてはシェルを書き慣れていない人にはオススメの一冊である! 是非とも読んでみてほしい。

シェルスクリプト解説

#!/bin/sh, #!/bin/bash の意味

正直、シェルスクリプトの一行目に「#!/bin/sh」を書くのは慣例だと思っていた。 が、違った!ちゃんと意味があった。

単純に言えばシェルスクリプトに何を使うか、だ。

  #!/bin/sh

と書くと、Bourne Shell が使われる。 「#!/bin/bash」ならBourne-Again shell だ。bash のほうがsh より高機能。

では、ターミナルを開いたときにどのシェルと使ってるかは以下のコマンドで調べられる。

  echo $SHELL

パラメータ展開

パラメータは$をつけることで表される。 主なところはこんな感じだ。

書き方 説明
"{$HOME}" 変数の値を参照
"$1","$2",.. シェルスクリプト、シェル関数の引数を参照
$0 シェルスクリプト名を参照
"$@" シェルクリプト、シェル関数の引数全てを参照
$# シェルスクリプトの引数の個数
$? 直前のコマンドの終了ステータスを参照

ついでにダブルクォートで囲んでいるのは パラメータ展開をしたあとの文字列をパラメータ展開などを行わずに 文字列として展開することを示している。

例えば

  file=*
  echo $file
  # 現在のディレクトリの全ファイル、フォルダが表示
  echo "$file"
  # * が表示

のように、ダブルクォートで参照した文字列を再度、展開することを避けてくれる。

$#,$?などは数字の文字列が返ってきて、パラメータ展開などされる心配がないので、 ダブルクォートで囲んでいない。

シングルクォート、ダブルクォート、バックスラッシュ、バッククォートの違い

正直これはこの本を読むまで全く分からなかった。 これが分かっただけでもこの本を読む価値がある。

ここでは簡単なまとめを表にする。

パラメータ展開 コマンド置換 説明
シングルクォート × × 文字通りの意味として解釈される
ダブルクォート ○(``で囲む) $,`,\ の特殊文字が解釈される
バックスラッシュ - - 次の文字が特殊な意味を失う
バッククォート × 囲まれた部分がコマンドとして実行される
  echo '$HOME'
  # $HOME
  echo "$HOME"
  # /home/aha_oretama
  echo \$0
  # $0
  echo `expr 1 + 1`
  # 2

役立つテンプレート

他の人のシェルを見てると使い方、初期チェックなど お決まりの定型句があるように見えるが、 その定型句が人によってバラバラだったので全然覚えられなかった。

ここでは自分が一番良いと思った定型句を書く。

#!/bin/sh ← 何のシェルスクリプトを使うかを指定

# 使い方を指定
usage () {

cat <<EOT
Usage:
  "$0" [-o outputPath] targetFile
Description:
  Unzip file.
  File extension includes .tar .tar.gz .tar.Z .tar.bz2 .zip 
Options:
  -o  output-directory
EOT
## ヒアドキュメントで記載
## <<HOGEで始まり、次にHOGEが出るまでヒアドキュメントとなる

exit 1
}

# オプションの設定
# o: のようにコロンはオプションに引数があることを示す
while getopts ho: option
do 
  case $option in
    o)
      OUTPUT_PATH="$OPTARG"
      ;;
    h)
      usage
      ;;
    \?)
      usage
      ;;
  esac
done

# オプションを除く
shift `expr "$OPTIND" - 1`

# オプション以外の引数を確認
if [ $# -lt 1 ]; then
  usage
fi

最後に

この本はシェルスクリプトを学びたい人にとっては 基礎を固める最良の本となる。

この本を読んで作った簡単なUtil シェルを GitHub にあげたのでぜひ参考にしてほしい。

github.com

Oracle XE processes、SPFILE の設定

Oracleでは、けっこうprocesses数が問題になることが多いので、ここでやり方をまとめておきたい。

環境

  • Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

processes

ここではprocessesの変更を行うため、以下の権限を持ったユーザで実行する。

  • ALTER SYSTEM

確認

select * from  v$parameter where name = 'processes';

設定

ALTER SYSTEM SET PROCESSES=150 SCOPE=SPFILE; 



SCOPE 説明
MEMORY インスタンスのメモリ上に変更を加えるだけで再起動時には設定は破棄され前の状態に戻る。
PFILE サーバー・パラメータ・ファイル (SPFILE) に変更を加えるだけで現インスタンスには反映されない。再起動後に有効となる。
BOTH 現行インスタンス、および、サーバー・パラメータ・ファイル (SPFILE) に変更を加える。再起動時にも有効となる。




SPFILE の設定

案の定、上記を実行したときにエラーが発生した。
SPFILE でOracle XE を起動していなかったのだ…

ここではSPFILE の作成、設定も追記する。

SPFILEの作成のためにSYSDBA,SYSOPER のどちらかの権限のユーザで実行する。

SPFILE 確認

select * from  v$parameter where name = 'spfile';

Value に値があればSPFILE で起動している。逆にnull であればPFILE で起動していることになる。

SPFILE 作成

CREATE SPFILE [= filePath] FROM PFILE [= filePath];

もし必要であればfilePath を指定することで、SPFILE の格納場所、PFILE の参照先を指定できる。

Groovy on Grails をインストールして使ってみた

会社でGroovyを使っているので、勉強していたらGrailsというものがあり、
GrailsならWebアプリケーションを簡単に作れるっぽいのでインストールしてみた。

環境

インストール

Grails

Grailsは以下からインストールできる。
The Grails Framework

Posh-GVM (POwerSHell Groovy enVironment Manager) というGroovy の環境ツールがあるので、
せっかくなのでPosh-GVM を使ってインストールしてみた。

まずはPosh-GVM のインストール。
管理者権限のPowerShell で以下を実行。

  1. (new-object Net.WebClient).DownloadString('https://raw.githubusercontent.com/flofreud/posh-gvm/master/GetPoshGvm.ps1') | iex
  2. Import-Module posh-gvm
  3. gvm help

以下の画面が表示されればPosh-GVM のインストールは完了。
f:id:AHA_oretama:20151224195204j:plain

途中、PowerShell の実行ポリシーに引っかかった場合、以下をPowerShell 上で実行すれば解決した。

Set-ExecutionPolicy RemoteSigned


それではPosh-GVM を使用してGrails をインストールしてみよう。
といっても、以下コマンドをPowerShell で実行するだけだ。

gvm install grails

GGTS

Groovy/Grails Tool Suite というEclipse のGroovy/Grails 版があるのでインストールしてみた。
といっても、以下からダウンロードしてインストールするだけだ。
Groovy/Grails Tool Suite™ (GGTS)

インストールが終わってGGTS を開いてみるとなにかあやしい予感が…
おそるおそる「Preferences」→「Groovy」→「Grails」を見てみると…

f:id:AHA_oretama:20151224210304j:plain

GGTS に含まれてるやないか!!Grails !!
せっかくインストールしたのに…!!

しかもバージョンが違ってる…
しょうがないのでPosh-GVM を使用してGrails をバージョンして入れ直し。

gvm install grails 2.4.4

Grails コマンドを使用して「Hello,World!」

せっかく入れたGrails だけをつかって「Hello,World!」アプリケーションを作る。
PowerShell で以下のコマンドを順に実行する。

  1. grails create-app HelloWorld
  2. cd .\HelloWorld
  3. grails create-controller HelloWorld
  4. エディタで .\grails-app\controllers\helloworld\HelloWorldController.groovy を開き、編集する
package helloworld

class HelloWorldController {

    def index() {
        render "Hello,World!"
    }
}

  5. grails run-app

うん、なんか大丈夫そうだな。
アプリケーションが起動したというメッセージが出た。
f:id:AHA_oretama:20151224225808j:plain

GGTS を使用して「Hello,World!」

先ほど作ったプロジェクトを「Grails Project」としてインポートし、
あとはRUNするだけでOK!

これでうまくいくと思ったらエラーがバンバン出た…エラーが止まらない!

java.lang.reflect.InvocationTargetException
	at sun.reflect.GeneratedMethodAccessor58.invoke(Unknown Source)
…
Caused by: java.lang.IllegalArgumentException: Can not copy a non-root Method
	at java.lang.reflect.Method.copy(Method.java:151)
	... 390 more

さっそく調べてみると、ここに書いてあった。
Incompatible JVM in GGTS (Eclipse) and JAVA 1.8 - Stack Overflow

JDKのバージョンが対応していないとのこと。
JDK:1.8.0_60 をインストールして実行してみると成功した。

f:id:AHA_oretama:20151224225123j:plain

まとめ

Groovy on Grails の良さまでは今日はたどり着けなかった。
ただGrails の環境はこれでできたので、次からはGrails をいろいろ触ってみたい。

Java8から追加されたラムダ式についてまとめてみた。

Java8から追加されたラムダ式に触れる機会が増えてきたので、ここらへんで自分の知識をまとめておきたいと思う。

まずラムダ式とはなにか。関数型インターフェース(1つのインターフェースに実装が必要なメソッドを1つだけ持つインターフェース)に対して、以下のような形式で記述する文法である。

(引数) -> {処理};


では、実際にどのようになるか見てみよう。まずはjava.util.function.Functionインタフェースに対して、ラムダ式を使わずに匿名クラスで記述した場合。

	public void testMethod() {
		Function<Integer, Double> function = new Function<Integer, Double>() {
			@Override
			public Double apply(Integer t) {
				return (double) t / 2;
			}
		};
		System.out.println(function.apply(1));
	}


では、上記をラムダ式で記述するとどのようになるか。

	public void testMethod() {
		Function<Integer, Double> function = (Integer t) -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}

慣れないと分かりにくいが、匿名クラスの作成やメソッド部分が省略され、ずいぶん記述量が減った。


ここから若干、駆け足で説明したいと思おう。まずは引数の型は定義されているため、記述を省略できる。(ここではジェネリックス型なので左辺で定義されている。ジェネリックス型以外であればインタフェースに定義済みである。)

	public void testMethod() {
		Function<Integer, Double> function = (t) -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}


さらに引数が一つであれば括弧()が省略できる。

	public void testMethod() {
		Function<Integer, Double> function = t -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}


また戻り値が一つであれば return を省略できる。

	public void testMethod() {
		Function<Integer, Double> function = t -> (double) t / 2;
		System.out.println(function.apply(1));
	}

最初の匿名クラスの場合と比較してみてほしい。たった一行でインターフェースの実装が完了してしまった!!

これがラムダ式の力である。


もちろん慣れるまで意味を把握しにくいかもしれないが、この記述量の削減には素晴らしいものがある!
それにJava8から追加された「Stream API」ではラムダ式が多用されるため、
ぜひとも早く慣れて使いこなせるようになっておいたほうがいい。


最後にいくつか補足を付け加える。

まずは引数がない場合、どのようになるか。答えは ()-> {処理}; となる。
ここではjava.util.function.Supplierについて例を記載する。

	public void testMethod_Supplier() {
		Supplier<String> supplier = () -> "supplier";
                // supplierと表示。
		System.out.println(supplier.get());
	}

またメソッド参照ができるので、このような記載も可能。
ここではjava.util.function.Consumerについて例を記載する。

	public void testMethod() {
		Consumer<String> consumer = System.out::println;
                // consumerと表示。
		consumer.accept("consumer");
	}

Windows10にアップグレードしてみた② ~アプリ削除~

引き続きWindows10にアップグレードした後に気づいた便利な点、不便な点について触れたいと思う。2回目は不要なアプリの削除についてである。

 

■不便①

Windows10にアップグレードするとすぐに入れた覚えのないアプリがインストールされていることに気づく。WindowsのPCを買ったときと同じで、いらないアプリを削除するというお決まりの作業が発生するのである。ここら辺はMicrosoftさんに改善してほしい点だ。

基本はメニュー画面で右クリックからアンインストールができるが、いくつか削除できないアプリがあることに気づく。例えば「3D Builer」や「People」、「モバイルコンパニオン」などだ。

そのようなアプリを削除する場合はひと手間必要である。Windows PowerShellを管理者権限で開き、Window8から搭載された「Remove-AppxPackage」コマンドで削除する必要があるのだ。

それでは具体的な使い方だ。ここでは例として「People」を削除してみよう。

まずは対象アプリの具体的な名称の特定だ。Windows PowerShellに「Get-AppxPackage *people*」と入力してみよう。アプリの詳細情報が表示される。

f:id:AHA_oretama:20151011113503j:plain

対象のアプリが分かったなら「Remove-AppxPackage 'PackageFullName'」コマンドだ。

f:id:AHA_oretama:20151011114429j:plain

これで不要アプリを削除できる。削除したアプリを復活させたい場合はWindowsストアから再度インストールすることで復活できる。

このようにひと手間加えなければアプリを削除できないのはMicrosoftさんに改善してほしいところである。

ついでにこれでも削除できないアプリ(「Edge」など)があるが、それについては今のところ削除する方法が分かっていないので、 知っている人がいれば教えてほしい。

Windows10にアップグレードしてみた① ~仮想デスクトップ~

初めての記事はWindows10へアップグレードした後に気づいた便利な点、不便な点をまとめてみたいと思う。

 

■便利①

まずは何と言っても仮想デスクトップであろう。この機能がWindowsにできたとMacユーザの同僚に話した時に「Macだとだいぶ前から標準搭載してますけど、やっとできたんですねw」と鼻で笑わられた…orz

仮想デスクトップはあたかもデスクトップが複数あるかのように振る舞う機能で、別々の作業をするときに便利な機能だ。基本的にショートカットキーしか使わないので、ショートカットキーの紹介だ。

まずは仮想デスクトップと起動アプリの一覧表示、Win + Tabだ。

 

f:id:AHA_oretama:20151010222644j:plain

選択は方向キーで移動可能。Tabで仮想デスクトップ、アプリの選択を切り替えられる。

仮想デスクトップ間の移動はWin + Ctrl +方向キーだ。よく使う機能なので、覚えておいて損はない。

あと仮想デスクトップの追加はWin + Ctrl + D。仮想デスクトップの削除はWin + Ctrl + F4。

仮想デスクトップの機能は基本Win + Ctrlでできるので、Windows10ではこのキーたちを押しておけば間違いない。

ついでに何もアプリが起動していない仮想デスクトップでWinボタンを押してメニューを表示し、WinボタンまたはEscボタンを押してメニュー表示を閉じたときに、アプリが起動している仮想デスクトップに強制的に戻されるのはWindowsのバグだと思うが、仕様だと言い張るだろうw

・ショートカットキーまとめ
  • 仮想デスクトップの一覧表示 Win + Tab
  • 仮想デスクトップ間の移動 Win + Ctrl +方向キー
  • 仮想デスクトップの追加 Win + Ctrl + D
  • Win + Ctrl + F4