シェルスクリプトの基礎①~シェルスクリプトってなに~

4 min読了の目安(約4400字IDEAアイデア記事

はじめに

くーばねてすをやっつけるためにLinuxさんと仲良くさせていただいているが、Linuxさんにはシェルのコマンドを格納しておくシェルスクリプトというファイルがあるらしいのでそれをまとめてみた。

概要

■シェルスクリプトとは
■なんのシェルを使うか
■シェルスクリプトを作る
■色んなシェルスクリプトの実行形式
■シェルスクリプトの配置

をまとめてみた^^

シェルスクリプトとは

シェルスクリプトたはシェルのコマンドを格納しておくファイルのことをいう。
たくさんのコマンドを組み合わせた処理が保存しておくことができるので多くの作業を素早く実行することができるらしい。('')
今まではコマンドラインで長いコマンドラインを入力していたが、実はコマンドラインをシェルスクリプトに組み込ませ実行することができた!(@
@)
シェルスクリプトはあらかじめコマンドラインを並べて保存しておくだけでなく、
また条件分岐や繰り返しなど複雑な構造を記述することができるそうだ。
シェルスクリプトを使うことによって
■一度作れば、後で同じ処理をしたい時にそのシェルスクリプトを再利用することができる。
■自分だけでなく他の人にも共有できる。
■コマンド打ち間違えの作業ミスが減る。
ことができるそうだ!

■なんのシェルを使うか

■なんのシェルのシェルスクリプトを書けばいいのか

前にbashでコマンドの設定をしたと思うが、シェルにはいくつか種類がある。
代表的なのが、
sh
bashだ。
なのでshかbashかという二択になる。

■shとは

長い歴史を持つ反面、設計が古く、低機能なシェルだ。しかしすべてのLinuxにはshが必ず入っているので、ほかの環境にシェルスクリプトを持って行って使う場合はshでシェルスクリプトをつくる。

■bashとは

shと比べbashの方が機能性が高いので移植性(ほかの環境にシェルスクリプトを持って行って使う可能性)がないのであれば、基本的にbashでシェルスクリプトを作成するのがおすすめ。
だそうだ。

■どっちでやるか

bash一択だ。
そもそもCentOsのRedHot系ディストリビューションはshをbashの別名として実装していたり、
Ubuntuではshがなく、shの代わりにdashという原始的なシェルで実装している。
なので、移植性に配慮してshでシェルスクリプトを作成しても互換性の問題は解決しなかったりする。

またshはすべてのLinuxに入っているが、bashもデフォルトでほぼ入っているのでbashの方が互換性、移植性が高いんじゃないかってことらしい。
またshは簡単な計算をするのにも外部コマンドを必要とし、動作も遅くなるが、bashは算術展開という機能が用意されており、外部コマンドなしに計算できるし、動作も高速だ。
shでわざわざ書きにくいプログラムを書くより、bashを使ったほうが生産性が高まるんじゃないか?
なので今回もbashでシェルスクリプトを作成しようと思う('◇')ゞ!

■シェルスクリプトを作る

シェルスクリプトは実行したいコマンドを記述したファイルなのでvimなどのテキストエディタで編集する。名前はなんでもいいそうだ。ファイル名を拡張子を.shにするのがシェルスクリプトの慣習だそうだが、拡張子を付けなくてもOK。.shと拡張子をつけておけばわかりやすいので今回はそうする。

$ vim command.sh
(シェルスクリプト内容↓)
#!/bin/bash     (←シェバン)
du -h ~ | tail -n 1  (←記述したいコマンド)

このように2行目からコマンドラインを記述していく。
まって!(@_@)シェバン!誰!

■シェバンって誰?

シェルスクリプトにコマンドを記述していくが、このコマンドがなにを使って動かすのかわからないとLinuxさんは困ってしまう。
なのでまず、なにを使ってコマンドを動かすのか、宣言してあげないといけない。
そこで宣言する役割を持つのが、シェバン(またはシバン)。
今回はbashでコマンドを動かすので、

↓ファイルの先頭が#!で実行するファイルを選択
#! /bin/bash
    ↑/bin/bashで実行せよ!

となる。そういう意味だったらしい。シェバン...('_')
もしシェバンで宣言しなかった場合、

$ /bin/bash ファイル名
または
$ bash ファイル名

というようにシェルと引数を指定しなければファイルは実行されない。
※...シェバンいたほうがいいね。('_')
コマンドを編集して保存したら、シェルスクリプトを実行できるように、chmodコマンドで実行権限を付与してからシェルスクリプトを実行する。
シェルスクリプトを実行するのには「./シェルスクリプトファイル名」でいい。
ファイル名の前に「./」を付けることを忘れない。

$ ls -l command.sh
-rw-r--r-- 1 root root 34 Jan  9 12:19 command.sh  (※実行権限がない)
$ chmod +x command.sh  (※実行権限付与)
$ ./command.sh
188K    /root

ファイル名を指定しただけでコマンドが実行された!
シェバン、やるな(>_<)

■色んなシェルスクリプトの実行形式

シェルスクリプトを実行するにはいろいろな方法がある。
↑シェバンで実行する方法、それと
sourceコマンドで実行する方法がある。
■sourceコマンドでの実行
sourceコマンドでは指定したファイルの内容をコマンドラインにそのまま入力したときと同じように実行する。
※ソースでそのまま流し込む!と覚えた!

$ cat test.sh
du -h ~ | tail -n 1
$ source ./test.sh
188K    /root

sourceコマンドを使う時は、シェバンは不要であり、仮にシェバンがいたとしても、#から始まる行はコメント行として扱われるため、無視される。
またsourceコマンドは対象ファイルを直接実行するわけではないので実行権限の設定は不要である。
またsourceコマンドは.と省略して記述することができる。

$ . ./test.sh
188K    /root

めっちゃ楽!!!('_') ソースも気に入ったよ!

■色んな実行方法があったね

色んな実行方法
①ファイル名のみ指定で実行する
$ ./command.sh
②シェルの引数として実行する
$ bash ./test.sh
③sourceコマンドで実行する
$ source ./test.sh
または
$ . ./test.sh

※※ただし、注意が!※※
ファイル名だけ指定で実行すると、子プロセス(現在のシェルから起動されるサブシェル)からファイルが実行されるので、例えば、カレントシェルでしか通用しないaliasなどの設定をしてしまうとファイルが実行されなくなってしまう。

$ alias lself='ls -alF'(※カレントシェルにaliasで設定)
$ cat test1.sh
#! /bin/bash
lself /
$ ./test1.sh
./test1.sh: line 2: lsalf: command not found

サブシェルは現在のシェルからaliasを引き継がれないので、コマンドが見つかりませんとなったのだ。
ファイル名だけでファイルを実行するときは注意が必要だ。

$ source ./test1.sh
total 20
dr-xr-xr-x  18 root root  257 Nov 20 03:25 ./
dr-xr-xr-x  18 root root  257 Nov 20 03:25 ../
-rw-r--r--   1 root root    0 Nov 20 03:25 .autorelabel
lrwxrwxrwx   1 root root    7 Nov 13 03:33 bin -> usr/bin/
略

sourceコマンドだとちゃんとでた!

■シェルスクリプトの配置

自分だけのシェルスクリプト置き場をつくり、サーチパスにファイルを参照するように設定する。と、lsやcatコマンドのように頭に./を付けなくてもコマンドを実行することができる。

設定しないと出来ない
$ test1.sh
-bash: test1.sh: command not found
※コマンドサーチをした結果、見つかりませんでした

■作ってみる
独自コマンドを作るには、~/binディレクトリがよく使われる。
なので~/binディレクトリを作成し、シェルスクリプトを移動させる。

自分だけの置き場をつくる
$ mkdir ~/bin
$ mv test1.sh ~/bin
$ ls ~/bin 
test1.sh

サーチパスに~/binを設定する

$ PATH="$PATH:~/bin"

PATHの環境変数が変わるのでこれで~/binからtest1.shを参照してもらえる。
有効化するには

$ source ~/.bash_profile

でsourceコマンドで~/.bash_profileを読み込むか、一度ログアウトする。

$ test1.sh 
total 20
dr-xr-xr-x 18 root root  257 Nov 20 03:25 ./
dr-xr-xr-x 18 root root  257 Nov 20 03:25 ../
-rw-r--r--  1 root root    0 Nov 20 03:25 .autorelabel

できた!

全てがめんどくさかったら

$. ./ファイル名

でいいんじゃない?って思った('_')

まとめ

今日は水道の試験があったんだけど、まじでやる気でなくてほとんど勉強しなくて、うっすらわかる問題ばかりで、ちょっと勉強したらわかったのになって思ったんだけど、最終的にまあやらなかったよね。