シェルスクリプトの本を読んでシェルを書いてみた
「シェルスクリプト 基本リファレンス」の本について
今回、読んでみた本は以下の「シェルスクリプト 基本リファレンス」だ。
[改訂新版] シェルスクリプト基本リファレンス ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)
- 作者: 山森丈範
- 出版社/メーカー: 技術評論社
- 発売日: 2011/04/27
- メディア: 単行本(ソフトカバー)
- 購入: 9人 クリック: 119回
- この商品を含むブログ (9件) を見る
総評
まず対象としてる読者は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 にあげたのでぜひ参考にしてほしい。
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';
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 で以下を実行。
- (new-object Net.WebClient).DownloadString('https://raw.githubusercontent.com/flofreud/posh-gvm/master/GetPoshGvm.ps1') | iex
- Import-Module posh-gvm
- gvm help
以下の画面が表示されればPosh-GVM のインストールは完了。
途中、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」を見てみると…
GGTS に含まれてるやないか!!Grails !!
せっかくインストールしたのに…!!
しかもバージョンが違ってる…
しょうがないのでPosh-GVM を使用してGrails をバージョンして入れ直し。
gvm install grails 2.4.4
Grails コマンドを使用して「Hello,World!」
せっかく入れたGrails だけをつかって「Hello,World!」アプリケーションを作る。
PowerShell で以下のコマンドを順に実行する。
- grails create-app HelloWorld
- cd .\HelloWorld
- grails create-controller HelloWorld
- エディタで .\grails-app\controllers\helloworld\HelloWorldController.groovy を開き、編集する
package helloworld class HelloWorldController { def index() { render "Hello,World!" } }
5. grails run-app
うん、なんか大丈夫そうだな。
アプリケーションが起動したというメッセージが出た。
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 をインストールして実行してみると成功した。
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*」と入力してみよう。アプリの詳細情報が表示される。
対象のアプリが分かったなら「Remove-AppxPackage 'PackageFullName'」コマンドだ。
これで不要アプリを削除できる。削除したアプリを復活させたい場合はWindowsストアから再度インストールすることで復活できる。
このようにひと手間加えなければアプリを削除できないのはMicrosoftさんに改善してほしいところである。
ついでにこれでも削除できないアプリ(「Edge」など)があるが、それについては今のところ削除する方法が分かっていないので、 知っている人がいれば教えてほしい。
Windows10にアップグレードしてみた① ~仮想デスクトップ~
初めての記事はWindows10へアップグレードした後に気づいた便利な点、不便な点をまとめてみたいと思う。
■便利①
まずは何と言っても仮想デスクトップであろう。この機能がWindowsにできたとMacユーザの同僚に話した時に「Macだとだいぶ前から標準搭載してますけど、やっとできたんですねw」と鼻で笑わられた…orz
仮想デスクトップはあたかもデスクトップが複数あるかのように振る舞う機能で、別々の作業をするときに便利な機能だ。基本的にショートカットキーしか使わないので、ショートカットキーの紹介だ。
まずは仮想デスクトップと起動アプリの一覧表示、Win + Tabだ。
選択は方向キーで移動可能。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