MyEnigma

とある自律移動システムエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

シェルスクリプト逆引きメモ


フルスクラッチから1日でCMSを作る シェルスクリプト高速開発手法入門 改訂2版

目次

はじめに

長めのシェルスクリプトを作るときに、

便利な逆引きメモです。

シェルスクリプトを安全に実行する

シェルスクリプトの冒頭に、

#!/bin/bash -euo pipefail

と書くと、各コマンドを表示してくれたり、

エラーが発生した場合や、

未定義の変数がある場合は、そこで止まってくれます。

 

スクリプトの中で、

set -euo pipefail

としてもOKです。

 

それぞれのオプションの意味は下記の通りです。

オプション 意味
-e (errexit) コマンド実行がエラー(exit statusが0以外)のときは、停止
-u 未定義の変数がある場合は終了
-o pipefail パイプの途中でエラーがあった時でも止める

デバッグモードを作成する

下記の記事の通りにシェルスクリプトを書くと、

$ TRACE=1 ./script.sh

とすることで、実行したコマンドを全部表示することができ、

シェルスクリプトをデバックしやすくなります。

sharats.me

 

helpを出すようにする

下記の記事の通りにシェルスクリプトを書くと、

--helpや-hで、任意の説明文を表示することができます。

sharats.me

 

error関数とabort関数を使う

下記の記事の通りです。

pyopyopyo.hatenablog.com

error関数とabort関数を使うと

$ command || error "Error"

でcommandが失敗したときに、エラーハンドリングできます。

 

コマンドが使えるか確認する

あるコマンドがシェルから実行できるかを確認するには、

下記のtypeコマンドを使うことができます。

 

下記はyumコマンドが使える場合は、

yumでvimをインストールし、

それ以外はaptでインストールする例です。

# yumコマンドがある場合は
if type yum > /dev/null 2>&1; then 
        sudo yum install vim
else # Ubuntu
        apt install vim
fi

 

複数のファイルを連結する

cat *.txt > all.txt

txt形式のログファイルを連結したりするのに便利です。

 

スクリプトの場所に移動してから、シェルスクリプトを実行する

スクリプトが実行される場所に関係ないシェルスクリプトを作るには、

下記のコマンドを最初に実行すれば、

スクリプトの場所に移動してから、シェルスクリプトを実行することができます

$ cd $(dirname $0) || exit 1

www.qoosky.io

 

二つのコマンドを一行で実行する

; (セミコロン)でつなぐと一行で書けます。

シェル・スクリプト・リファレンス - 【 複数のコマンドの実行「;」 】:ITpro

 

シェル変数のデフォルト値

下記のようにすると、

$1が設定されていない場合は、fooにhogeが入り、

$1が設定されている場合は、fooに$1の値が設定されます。

foo=${1:-hoge}

 

コマンドを実行して、その結果を変数に代入

ドルマークと丸括弧でコマンドを囲います。

$ hoge=$(command)

カレントディレクトリ以下の全ファイルからxxxという文字列を検索

find ./ -name '*'| xargs grep 'xxx'

.cppファイルのみから見つけたい時

find ./ -name '*.cpp' | xargs grep 'xxx'

 

シェルスクリプトのif文などで比較するときは、[[]]を使う。

fumiyas.github.io

文字列

シェルスクリプトで文字列を扱う方法です。

同じ文字列の比較

#!/bin/bash

VAR1="Linuxize"
VAR2="Linuxize"

if [ "$VAR1" = "$VAR2" ]; then
    echo "Strings are equal."
else
    echo "Strings are not equal."
fi

 

配列

シェルスクリプトで配列を扱う方法を説明します。

配列の初期化

一般的には、

$ declare -a my_array

でmy_arrayという配列を作ることができます。

他には、下記のように空の配列を作ったり、

$ my_array=()

初期値を入力して、初期化することもできます。

$ my_array=(foo hoge huga)

 

コマンドの出力を配列に入力する

bash v4.0から導入されたmapfileを使うと簡単に実現できます。

mapfile -t my_array < <( my_command )

linuxcommand.net

 

関数から配列を返す

そもそもシェルスクリプトでは、返り値を返すことそのものが難しいため、

あまり美しい方法はなさそうですが、一番良さそうな方法は、

返り値用の配列変数を、引数として渡してnamerefの機能を使って

その配列変数に代入することです。

create_array() {
    local -n arr=$1             # namerefを使って、参照とする
    arr=(one "two three" four)
}

main() {
    local my_array
    create_array my_array       # my_arrayを引数として渡す
    echo $my_array[@]
}

main

qiita.com

 

配列のスライス

一応、スライスも可能です。

stackoverflow.com

www.gnu.org

 

その他参考資料

linuxconfig.org

ループ関連

ダブルループから抜ける

breakの後に、ネスト数を入れる必要があります。

for i in something
   do
      while true
      do
         [ condition ] && break 2
      done
done

Bashの予約語

Bashにはいくつか予約語があります。

予約語 用途
$0 スクリプトの名前
$1 to $9 スクリプトの引数。$1は最初の引数で、残りも同様にアクセスできます。
$@ すべての引数
$# 引数の数
$? 一つ前のコマンドの終了コード
$$ このスクリプトの Process identification (PID) 番号。一時ファイルの名前にすると良い
!! 引数を含む最後のコマンド全体。よくある使い方は、コマンドを実行してもパーミッションが足りないために失敗したときに、sudo !! とすることです。
$_ 最後のコマンドの最後の引数。対話型シェルを使用している場合は、Escの後に.を入力することで、この値を取得することも可能

 

cutコマンドを使うと各列の一部のデータを取得できる。

ドット区切りで第二フィールドを取得する。

$ cut -d. -f2

 

数字列を取得する場合はegrepを使うと良い

0-9の数字が8個並ぶ所を取得する

$ egrep "[0-9]{8}"

awkの使い方

awkは位置指定付きのgrepとして使える

第5フィールドにsuを含む行を抽出

awk '$5=="su*"

awkでは文字列を”“で囲むと文字列扱い、囲まないと数値扱いになる

数値にすれば大小の比較条件などを使える。

sedの使い方

nanが混入してしまったデータを0に置き換える

別のファイルとして置き換えたい場合

$ cat hoge.txt | sed "s/nan/0/g" > hoge2.txt

同じファイルとして上書きしたい場合

$ sed -i "s/nan/0/g" hoge.txt

単語置換

$ #11行目~25行目までAAAをBBBに置換する

$ sed -e '11,25 s/AAA/BBB/g' source.txt

GitHubのリポジトリの最新tagのバージョンを取得する

下記のように、curlとsedを組み合わせることで、最新のバージョンを取得できます。

$ curl -s https://api.github.com/repos/AtsushiSakai/DiffSentinel/tags|grep -m1 '"name":'|sed 's/^.[^0-9]([0-9].[0-9].[0-9]).*$/\1/'

参考資料

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com


フルスクラッチから1日でCMSを作る シェルスクリプト高速開発手法入門 改訂2版

MyEnigma Supporters

もしこの記事が参考になり、

ブログをサポートしたいと思われた方は、

こちらからよろしくお願いします。

myenigma.hatenablog.com