Copyright © Software Research Associates, Inc. All Rights Reserved
株式会社 SRA
阪井 誠
スクリプト言語入門
- シェル芸のすすめ -
第2回クラウド勉強会
Copyright © Software Research Associates, Inc. All Rights Reserved
クラウドでスクリプト言語
• クラウド環境ではインフラをソフトウェアから
簡単に扱え、多くの作業を自動化可能
( Infrastructure as Code )
• 最も簡単な自動化がシェルスクリプトの利用
• bashを中心にスクリプト処理の基本と開発の
方法を説明
• シェル芸のうち安全なシェルプログラミングの
方法を説明
• 普段の開発やAWSなどの作業にきっと役に立
つでしょう。
Copyright © Software Research Associates, Inc. All Rights Reserved 2
目次
• クラウドでスクリプト言語
• 目次
• シェル、引数、環境変数
• 標準入出力とパイプ
• 基本構造(実行ファイル、制御構造)
• 右辺値、左辺値
• 連想配列
• プロセス番号
• クォート、ワイルドカード
• head、tail、sort、uniq、more、less
• sed、awk
• JSON処理
• まとめ
Copyright © Software Research Associates, Inc. All Rights Reserved
3
シェル、引数、環境変数
• シェルとは
カ
ー
ネ
ル
コマンド
システム
コール
$ cat a.txt b.txt
argc: 3
argv[0]: cat
argv[1]: a.txt
argv[2]: b.txt
envp[0]: HOME=/home/sakai
envp[1]: HOSTTYPE=x86_64
envp[2]: LANG=en_US.UTF-8
:
C言語
Copyright © Software Research Associates, Inc. All Rights Reserved 4
シェル、引数、環境変数
• C言語のメイン関数
int main(int argc, char *argv[], char *envp[]){
• 入力した文字列をフィールドセパレータで分割し、
argc(数)とargv(配列のポインタ)で渡す
• 次ページの変数にbashが割り当ててくれる
• 環境変数のうち、exportで指定されたものを
envp(配列のポインタ)で渡す
• Bashの変数として参照可能
• 関連コマンド
• 代入:a=“b”
• export:export aあるいはexport a=“b”
• env:環境変数を設定/無効化してコマンドを実行する
Copyright © Software Research Associates, Inc. All Rights Reserved 5
シェル、引数、環境変数
• $# :引数の数
• $* :全引数 "$1 $2..."
• $@ :全引数 "$1" "$2" ...
• 位置パラメーターの一括展開 $* $@ "$*" "$@" の違いを知
れ!!
• https://fumiyas.github.io/2016/12/15/positional-
parameters.sh-advent-calendar.html
• $0 :コマンド名
• $1 - $n :引数の値。10番目以降は${10}
• shift:引数を先頭から一つ減らす
Copyright © Software Research Associates, Inc. All Rights Reserved 6
標準入出力とパイプ
• ファイルディスクリプタ(各プロセスが持つ)
• 0:標準入力
• 1:標準出力
• 2:標準エラー出力
• 3-:ファイルなど
• リダイレクトはファイルディスクリプタとタイル
をつなげる
• <:ファイルを標準入力に
• <<文字:文字までを入力に(ヒアドキュメント)
• >:標準出力をファイルに(>>で追加)
• 2>:エラー出力をファイルに(>>で追加)
• 2>&1:標準出力とエラー出力をまとめる
Copyright © Software Research Associates, Inc. All Rights Reserved 7
標準入出力とパイプ
• パイプは左のプロセスの標準出力を右のプロセス
の標準入力につなぐ
• コマンド 2>&1 | more
• エラー出力もまとめてページ表示
• ファイルに落としながらパイプするときはtee
• $ ls | tee la.txt
Copyright © Software Research Associates, Inc. All Rights Reserved 8
基本構造
• 実行ファイル
• ファイルの先頭に「#!/bin/bash」と書く
• 実行パーミッションを立てる(chmod +x ファイル名)
• 設定ファイル
• ~/.bash_profile:ログイン時の設定。~/.bashrcを
内部で実行
• ~/.bashrc:bash起動時の設定
Copyright © Software Research Associates, Inc. All Rights Reserved 9
基本構造
• 制御構造(主なもの)
• if 条件式
then
コマンド
elif 条件式
then
コマンド
else
コマンド
fi
• for ( ( i = 0 ; $i < 10 ; i++ ) )
do
コマンド
done
• for 変数 in a b c
do
コマンド
done
• while 条件式
do
コマンド
done
• case 変数 in
a)
コマンド
;;
b*)
コマンド
;;
* )
コマンド
;;
esac
Copyright © Software Research Associates, Inc. All Rights Reserved 10
基本構造
• 条件式とステータス
• #!/bin/bash
hoge="A“
fuga="A“
if [ $hoge = $fuga ]; then
echo "文字列は同じです“
else
echo "文字列は違います“
fi
• [はテストコマンドとしてステータスを返している
(引数との間にスペースが必要)
• $ [ "a" = "a" ]
• $ echo $?
0
• $ [ "a" = "b" ]
• $ echo $?
1
Copyright © Software Research Associates, Inc. All Rights Reserved 11
基本構造
• 比較
• if [ $var2 -gt $var1 ] ; then
• if [ $var1 -lt $var2 ] ; then
• if [ $var2 -ge $var1 ] ; then
• if [ $var2 -le $var1 ] ; then
• 存在チェック
• if [ -d ${DIR} ]; then
• if [ -f ${LOCK_FILE} ]; then
• ステータス
• if [ $? = 0 ]; then
• 論理式
• if [ ! $hoge ]; then
• if [ -f ${LOCK_FILE} -a -d ${DIR} ]; then
• if [ -f ${LOCK_FILE} ] && [ -d ${DIR} ]; then
• if [ -f ${LOCK_FILE} ] || [ -d ${DIR} ]; then
• その他は調べて使ってください
Copyright © Software Research Associates, Inc. All Rights Reserved 12
右辺値、左辺値
• 左辺値
• 代入文の左にあるときは変数名のみ
• 右辺値
• 変数の参照時は$を付ける
• 変数名を明確に定義するときは${変数名}とする
Copyright © Software Research Associates, Inc. All Rights Reserved 13
連想配列
• 連想配列
• 配列のインデックスに文字列を指定したものを連想配
列と呼ぶ(awkの方が使いやすい)
• いわゆるmapとかhash
• 計算量O(1)
• $ declare -A hash
• $ hash["a"]=“A“
• $ hash["a"]=“B”
• $ echo ${hash["a"]}
A
• $ echo ${!hash[@]}
a b
• $ echo ${!hash[@]}
A B
Copyright © Software Research Associates, Inc. All Rights Reserved 14
プロセス番号
• 一時ファイルの危険な例
• grep a file > tmp
grep b file >> tmp
• 安全な例
• ファイル名にプロセス番号を付けることで、同時実行
時の問題を回避できる
• grep a file > tmp.$$
grep b file >> tmp.$$
Copyright © Software Research Associates, Inc. All Rights Reserved 15
クォート、ワイルドカード
• クォート
• どんな文字も無効:’“はクォート’
• スペース・ワイルドカードを無効に、変数を展開:
”パス: $path”
• 実行結果を展開:`ls`
• ワイルドカード
• 一文字:?
• 複数文字:*
• いずれかの文字:[a-zA-Z]
• いずれかの文字でない:[^abc]
• ブレース展開:file{1,2,3}.txt
Copyright © Software Research Associates, Inc. All Rights Reserved 16
便利なコマンドたち
• head:先頭から指定行を取り出す
• tail:最後の指定行を取り出す
• sort:ソートする
• uniq:ソート済みデータの重複をなくす
• grep:指定文字列を含む行を取り出す
• more 、less :ページ参照
Copyright © Software Research Associates, Inc. All Rights Reserved 17
sed、awk
• sed
• 指定行や指定範囲を編集する
• macはバークレー版なのでc(行置換)が異なる
• -iオプションを使うと上書きできる
• Awk
• 前処理、パターンに一致した行の処理、後処理ができ
る
• フォーマットプリントや連想配列だけで使うことも
• sniproxyの最終設定行を取り出す。
• grep -n '}' /etc/sniproxy.conf| tail -1| awk -F ':' '{print
$1}'
Copyright © Software Research Associates, Inc. All Rights Reserved 18
JSON処理
• AWS CLIの入出力はjson(--output textでテキスト)
• ヒアドキュメント、シングルクォート、 jq
• $ cat <<END >test.json
{
"title": "Person",
"properties": {
"Name": “Sakai”
}
}
END
• Python(インストール不要な場合が多い)
• $ python -c "import json;
print(json.load(open('test.json','r')).get('properties').g
et(‘Name))“
Sakai
Copyright © Software Research Associates, Inc. All Rights Reserved 19
開発の進め方
• 部分的に動作を確認しながら拡張する
• 大きなスクリプトになってしまったら
• 途中でexitする
• /tmpにデバッグメッセージ
• 実行せずにechoする
• コメントアウト:#
• ーx、-v、:を使う(デバッグ、冗長、ヌルコマンド)
Copyright © Software Research Associates, Inc. All Rights Reserved
まとめ
• クラウドでの利用を想定して、bashの基本を
説明しました
• このほかにも正規表現によるパターンマッチや
シグナル、ヒストリー機能など多機能です
• 必要に応じてマニュアルを参照してください
• ただし、bashのマニュアルは読みにくいので
他の記事も参照してください

スクリプト言語入門 - シェル芸のすすめ - 第2回クラウド勉強会

  • 1.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 株式会社 SRA 阪井 誠 スクリプト言語入門 - シェル芸のすすめ - 第2回クラウド勉強会
  • 2.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved クラウドでスクリプト言語 • クラウド環境ではインフラをソフトウェアから 簡単に扱え、多くの作業を自動化可能 ( Infrastructure as Code ) • 最も簡単な自動化がシェルスクリプトの利用 • bashを中心にスクリプト処理の基本と開発の 方法を説明 • シェル芸のうち安全なシェルプログラミングの 方法を説明 • 普段の開発やAWSなどの作業にきっと役に立 つでしょう。
  • 3.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 2 目次 • クラウドでスクリプト言語 • 目次 • シェル、引数、環境変数 • 標準入出力とパイプ • 基本構造(実行ファイル、制御構造) • 右辺値、左辺値 • 連想配列 • プロセス番号 • クォート、ワイルドカード • head、tail、sort、uniq、more、less • sed、awk • JSON処理 • まとめ
  • 4.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 3 シェル、引数、環境変数 • シェルとは カ ー ネ ル コマンド システム コール $ cat a.txt b.txt argc: 3 argv[0]: cat argv[1]: a.txt argv[2]: b.txt envp[0]: HOME=/home/sakai envp[1]: HOSTTYPE=x86_64 envp[2]: LANG=en_US.UTF-8 : C言語
  • 5.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 4 シェル、引数、環境変数 • C言語のメイン関数 int main(int argc, char *argv[], char *envp[]){ • 入力した文字列をフィールドセパレータで分割し、 argc(数)とargv(配列のポインタ)で渡す • 次ページの変数にbashが割り当ててくれる • 環境変数のうち、exportで指定されたものを envp(配列のポインタ)で渡す • Bashの変数として参照可能 • 関連コマンド • 代入:a=“b” • export:export aあるいはexport a=“b” • env:環境変数を設定/無効化してコマンドを実行する
  • 6.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 5 シェル、引数、環境変数 • $# :引数の数 • $* :全引数 "$1 $2..." • $@ :全引数 "$1" "$2" ... • 位置パラメーターの一括展開 $* $@ "$*" "$@" の違いを知 れ!! • https://fumiyas.github.io/2016/12/15/positional- parameters.sh-advent-calendar.html • $0 :コマンド名 • $1 - $n :引数の値。10番目以降は${10} • shift:引数を先頭から一つ減らす
  • 7.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 6 標準入出力とパイプ • ファイルディスクリプタ(各プロセスが持つ) • 0:標準入力 • 1:標準出力 • 2:標準エラー出力 • 3-:ファイルなど • リダイレクトはファイルディスクリプタとタイル をつなげる • <:ファイルを標準入力に • <<文字:文字までを入力に(ヒアドキュメント) • >:標準出力をファイルに(>>で追加) • 2>:エラー出力をファイルに(>>で追加) • 2>&1:標準出力とエラー出力をまとめる
  • 8.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 7 標準入出力とパイプ • パイプは左のプロセスの標準出力を右のプロセス の標準入力につなぐ • コマンド 2>&1 | more • エラー出力もまとめてページ表示 • ファイルに落としながらパイプするときはtee • $ ls | tee la.txt
  • 9.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 8 基本構造 • 実行ファイル • ファイルの先頭に「#!/bin/bash」と書く • 実行パーミッションを立てる(chmod +x ファイル名) • 設定ファイル • ~/.bash_profile:ログイン時の設定。~/.bashrcを 内部で実行 • ~/.bashrc:bash起動時の設定
  • 10.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 9 基本構造 • 制御構造(主なもの) • if 条件式 then コマンド elif 条件式 then コマンド else コマンド fi • for ( ( i = 0 ; $i < 10 ; i++ ) ) do コマンド done • for 変数 in a b c do コマンド done • while 条件式 do コマンド done • case 変数 in a) コマンド ;; b*) コマンド ;; * ) コマンド ;; esac
  • 11.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 10 基本構造 • 条件式とステータス • #!/bin/bash hoge="A“ fuga="A“ if [ $hoge = $fuga ]; then echo "文字列は同じです“ else echo "文字列は違います“ fi • [はテストコマンドとしてステータスを返している (引数との間にスペースが必要) • $ [ "a" = "a" ] • $ echo $? 0 • $ [ "a" = "b" ] • $ echo $? 1
  • 12.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 11 基本構造 • 比較 • if [ $var2 -gt $var1 ] ; then • if [ $var1 -lt $var2 ] ; then • if [ $var2 -ge $var1 ] ; then • if [ $var2 -le $var1 ] ; then • 存在チェック • if [ -d ${DIR} ]; then • if [ -f ${LOCK_FILE} ]; then • ステータス • if [ $? = 0 ]; then • 論理式 • if [ ! $hoge ]; then • if [ -f ${LOCK_FILE} -a -d ${DIR} ]; then • if [ -f ${LOCK_FILE} ] && [ -d ${DIR} ]; then • if [ -f ${LOCK_FILE} ] || [ -d ${DIR} ]; then • その他は調べて使ってください
  • 13.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 12 右辺値、左辺値 • 左辺値 • 代入文の左にあるときは変数名のみ • 右辺値 • 変数の参照時は$を付ける • 変数名を明確に定義するときは${変数名}とする
  • 14.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 13 連想配列 • 連想配列 • 配列のインデックスに文字列を指定したものを連想配 列と呼ぶ(awkの方が使いやすい) • いわゆるmapとかhash • 計算量O(1) • $ declare -A hash • $ hash["a"]=“A“ • $ hash["a"]=“B” • $ echo ${hash["a"]} A • $ echo ${!hash[@]} a b • $ echo ${!hash[@]} A B
  • 15.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 14 プロセス番号 • 一時ファイルの危険な例 • grep a file > tmp grep b file >> tmp • 安全な例 • ファイル名にプロセス番号を付けることで、同時実行 時の問題を回避できる • grep a file > tmp.$$ grep b file >> tmp.$$
  • 16.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 15 クォート、ワイルドカード • クォート • どんな文字も無効:’“はクォート’ • スペース・ワイルドカードを無効に、変数を展開: ”パス: $path” • 実行結果を展開:`ls` • ワイルドカード • 一文字:? • 複数文字:* • いずれかの文字:[a-zA-Z] • いずれかの文字でない:[^abc] • ブレース展開:file{1,2,3}.txt
  • 17.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 16 便利なコマンドたち • head:先頭から指定行を取り出す • tail:最後の指定行を取り出す • sort:ソートする • uniq:ソート済みデータの重複をなくす • grep:指定文字列を含む行を取り出す • more 、less :ページ参照
  • 18.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 17 sed、awk • sed • 指定行や指定範囲を編集する • macはバークレー版なのでc(行置換)が異なる • -iオプションを使うと上書きできる • Awk • 前処理、パターンに一致した行の処理、後処理ができ る • フォーマットプリントや連想配列だけで使うことも • sniproxyの最終設定行を取り出す。 • grep -n '}' /etc/sniproxy.conf| tail -1| awk -F ':' '{print $1}'
  • 19.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 18 JSON処理 • AWS CLIの入出力はjson(--output textでテキスト) • ヒアドキュメント、シングルクォート、 jq • $ cat <<END >test.json { "title": "Person", "properties": { "Name": “Sakai” } } END • Python(インストール不要な場合が多い) • $ python -c "import json; print(json.load(open('test.json','r')).get('properties').g et(‘Name))“ Sakai
  • 20.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved 19 開発の進め方 • 部分的に動作を確認しながら拡張する • 大きなスクリプトになってしまったら • 途中でexitする • /tmpにデバッグメッセージ • 実行せずにechoする • コメントアウト:# • ーx、-v、:を使う(デバッグ、冗長、ヌルコマンド)
  • 21.
    Copyright © SoftwareResearch Associates, Inc. All Rights Reserved まとめ • クラウドでの利用を想定して、bashの基本を 説明しました • このほかにも正規表現によるパターンマッチや シグナル、ヒストリー機能など多機能です • 必要に応じてマニュアルを参照してください • ただし、bashのマニュアルは読みにくいので 他の記事も参照してください