「入門UNIXシェルプログラミング」を読んだ
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
- 作者:ブルース・ブリン,Bruce Blinn
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2003/02
- メディア: 単行本
目的、モチベーション
今まではググりながら雰囲気でシェルスクリプトを書いていて、最近業務で使うことが増えてきて、シェル使いになりたいと思ったから。
全体の感想
一通りの文法がまとまっていたので、この1冊を理解すれば、ソースコードもガンガン読んでいけるレベルにはなると思う。
リダイレクトとかは特に雰囲気で使っていたレベルだったので、ちゃんと理解できてよかった。
たまに見る、 /dev/null
の意味もわかったので、これからはガンガン使おうと思う。
目次
- 目的、モチベーション
- 全体の感想
- 目次
- 概要
概要
第1章 書き方にかかわる基本的な説明
1.4 ファイル名称の補完
ワイルドカード | 説明 |
---|---|
* | 文字列全部 |
? | 1文字 |
[...] | の中に含まれている文字のどれか一つ |
[!...] | の中に含まれてない文字 |
1.5 引用符の使い方
シングルクォートの中で変数を展開したい場合
'Part1'"$VAR"'Part2'
1.9 コマンドのグルーピング
()
によるグルーピング: サブシェルで実行する。現在の環境を変えずに実行したい場合などに便利。{}
によるグルーピング: 現在のシェルで実行する。コマンドの結果をひとまとめにしたい場合などに便利。
1.10 制御文
testコマンドは []
と同じ。
第2章 シェル変数
変数を明示的に使うには、{}
で囲む。
$ FOO=abc $ echo ${FOO}abc
2.5 位置パラメータ, 2.6 特殊な変数
変数 | 説明 |
---|---|
$# | 引数の数 |
$* | 引数全体。ダブルクォートで括ると、一つの文字列として扱われる。 |
$@ | 引数全体。ダブルクォートで括ると、それぞれが文字列として扱われる。 |
$? | コマンド実行時の終了ステータス |
$$ | プロセスID |
$! | & でバックグラウンド実行させたときのプロセスID |
$- | 実行中のシェルのフラグの一覧 |
第3章 シェル関数、組み込みコマンド
3.1 シェル関数
3.1.4 関数をカレントシェルで利用すること
通常、シェルスクリプトに含まれるコマンドはそのシェルスクリプト内で動作し、起動したシェル上で動くわけではない。
カレントシェルで実行させるには .
という組み込み関数を使用する。
$ . script_file
3.2 組み込みコマンド
3.2.1 ヌルコマンド(:)
何もしないが、いつも成功を返すコマンド。
# 無限ループ while : do if ..... then break fi done # 空ファイルの作成 $ : > file
3.2.7 evalコマンド
複数の変換処理を一度に実行。
$ VAR1=val $ VAR2=$"$VAR1" $ echo $VAR2 $val $ eval echo $"$VAR2" val
3.2.10 exportコマンド
引数に指定した変数を、他のコマンドやシェルからも利用できるようにする。
3.2.12 readコマンド
キーボードからの入力を変数にセットする。
#!/bin/sh echo -n "enter yes or no -->" read ANSWER
3.2.13 readonlyコマンド
変数を書き換え不可にする。
3.2.19 typeコマンド
コマンドの取り扱いを表示。
$ type echo cd echo is a shell builtin echo is /bin/echo cd is an alias for nocorrect cd cd is a shell builtin cd is /usr/bin/cd
3.2.20 umaskコマンド
ファイル生成時にどういうモードで作るかを決めれる。
ファイルの場合は666からumaskで指定した数字を指定したものができる。
デフォルト値は022なので、644のファイルができる。
$ umask 022 $ touch hoge $ ls -l hoge -rw-r--r-- 1 user1 staff 0 2 10 10:34 hoge $ umask 002 $ touch foo $ ls -l foo -rw-rw-r-- 1 user1 staff 0 2 10 10:34 foo
3.2.21 unsetコマンド
変数や関数を消去する
3.2.22 waitコマンド
引数に渡したプロセスIDのプロセスが終了するまで待つ。
第4章 リダイレクションによるファイル操作
4.1 ファイルディスクリプタ
- 0: 標準入力
- 1: 標準出力
- 2: 標準エラー
4.2 リダイレクト
リダイレクトとは、通常はキーボードからの入力を端末に出力するが、その入力元や出力先を変えること。
# 標準出力と標準エラーの両方をリダイレクト $ cat abc def > nnn 2>&1
記法 | 説明 |
---|---|
>file | 標準出力をfileというファイルに書く |
>file | 標準出力をfileというファイルに追加書きする |
>&m | 標準出力をm番のファイルディスクリプタに書く |
>&- | 標準出力をクローズする |
<file | 標準入力をfileというファイルから読み込む |
<&m | 標準入力をm番のファイルディスクリプタから読み込む |
<&- | 標準入力をクローズする |
<<word | 標準入力をヒアドキュメントから読み込む |
4.6 execコマンドとリダイレクション
execコマンドは、現在のシェルのプロセスをそのまま置き換えて新しいコマンドを実行させる。
# 標準出力を非表示に exec > /dev/null # 標準出力と標準エラーを非表示に exec > /dev/null 2>&1 # fileから入力する exec < file # n番目のファイルディスクリプタを使ってファイルをオープン exec n> file
4.7 ファイルからの読み込み
# fileから一行ずつ読み込んで処理 while read LINE do ..... done < file
4.10 ヒアドキュメント
# $VARは展開される command << END hoge is $VAR END # $VARは展開されない command << \END hoge is $VAR END # $VARは展開されない command << 'END' hoge is $VAR END # -をつけると行頭のtabが無視される command <<- END <tab>hoge is $VAR END # パイプにわたす command << END | command hoge is $VAR END
第5章 環境
5.3 ユーザ情報、マシン情報
5.3.1 ユーザ名の取得
USERやLOGNAMEという環境変数でも取得できるが、書き換えられるので信用はできない。
$ whoami hoge_foo $ logname hoge_foo $ sudo su - # whoami root # 切り替わる # logname hoge_foo # もとのまま
スーパーユーザのみで実行させたい場合は、ユーザidで判断する。
if id | grep "^uid=0(" > /dev/null 2>&1 then echo "Is superuser" else echo "Is not superuser" fi
5.4 シグナルの処理
プロセスはシグナルを受け取ると実行を中止する。ハンドリングするためには trap
コマンドを使う。
trap command-list signal_number # シグナルを受け取って処理する trap '' signal_number # シグナルを無視する trap signal_number # シグナルをリセットする # シングルクォートで渡して、後ほど展開させる trap 'rm -f /tmp/*.$$; exit 1' 1 2 3 15
数字 | 種類 | 説明 |
---|---|---|
1 | ハングアップ(SIGHUP) | |
2 | 割り込み(SIGINT) | キーボードからの割り込みで中断させるためのキー。Ctrl-C |
3 | クイット(SIGQUIT) | |
9 | キル(SIGKILL) | プロセスを強制終了させる。trap等でも捕まえることはできない。 |
15 | 終了(SIGTERM) | アプリケーションを終了させるときに用いられる。 |
第6章 コマンド行の解析、処理
6.2 コマンド行の書き方
引数が -
でスタートするとオプションとして認識されてしまうため、 --
を前につける。
$ mkdir -- -p
6.3 シェルスクリプトでのオプション処理
getopts
コマンドを使う
FLAG=FALSE VALUE= OPT= while getopts fv: OPT do case $OPT in f) FLAG=TRUE ;; v) VALUE=$OPTARG ;; \?) echo "Usage: $0 [-f] [-v value]" 1>&2 exit 1 ;; esac done shift `expr $OPTIND - 1`
第7章 フィルタの使用法
7.2 sedコマンド
# 以下は同じ cat file | sed -e 's/abc/ABC/' sed -e 's/abc/ABC/' < file # 慣習として使われてるだけで `/`のデリミータは任意の文字列でも大丈夫。 sed -e 's%abc%ABC%' file
7.3 sed を使っての編集
# 先頭に文字列追加 sed -e "s/^/top/" # 末尾に文字列追加 sed -e "s/\$/top/" # Pattern1とPattern2に囲まれてる部分の削除 sed -e "s/Pattern1*.Pattern2//" # 大文字小文字の変換 cat file | tr '[a-z]' '[A-Z]' > upperfile # タブをスペースに置換 sed -e "s/<tab>/<space>/" # ホワイトスペースをスペースに置換 sed -e "s/[<tab><space>][<tab><space>]*/<space>/g" # 空白行の削除 sed -e '/^[<tab><space>]*$/d' # 行の指定 sed -e '5,$s/<tab>/<space>/g' # 行の削除 sed -e '5,$d' # 1行目からn行目まで表示 sed -n '1,np' # BeginからEndの行を削除 sed -e '/Begin/,/End/d' # ファイルを後ろから表示 grep -n '.*' | sort -n -r | sed 's/^[0-9]*://'
第8章 シェルのいろいろな機能
8.6 ファイルとディレクトリ
# ファイル名やディレクトリ名の単体での取得 basename `pwd` # ディレクトリ名の取得 dirname `pwd` # dir以下のファイルとディレクトリをすべて表示 find dir -print # カレントディレクトリ以下のディレクトリのみすべて表示 find . -type d -print # カレントディレクトリ以下のファイルのみすべて表示 find . -type f -print # カレントディレクトリ以下の.swiftファイルのみすべて表示 find . -type f -name '*.swift' -print
第11章 デバッグの手順、手法
11.2 デバッグオプション
- -vオプション: 何を実行しようとしているのかが表示される
- -xオプション: 実行している途中経過が出色される
$ cat shscript #!/bin/sh ABC=0 for i in 1 2 3 do ABC=`expr $ABC + $i` done echo $ABC $ sh -v shscript #!/bin/sh ABC=0 for i in 1 2 3 do ABC=`expr $ABC + $i` done expr $ABC + $i expr $ABC + $i expr $ABC + $i echo $ABC 6 $ sh -x shscript + ABC=0 + for i in 1 2 3 ++ expr 0 + 1 + ABC=1 + for i in 1 2 3 ++ expr 1 + 2 + ABC=3 + for i in 1 2 3 ++ expr 3 + 3 + ABC=6 + echo 6 6
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
- 作者:ブルース・ブリン,Bruce Blinn
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2003/02
- メディア: 単行本