Masayan tech blog.

  1. ブログ記事一覧>
  2. エンジニアなら最低限押さえておきたいシェルスクリプト

エンジニアなら最低限押さえておきたいシェルスクリプト

公開日

趣旨

シェルスクリプトは、UNIX系OSにおけるスクリプト言語の一種であり、コマンドラインから連続的な操作を自動化するための重要なツールである。そこで本稿では、エンジニアなら押さえておきたいシェルスクリプトの基本となる、いくつかの主要なコマンドについて解説する。

変数

代入

他の多くの言語と同じように=で代入。定義した変数は$をつけることで参照できる

replacement="hoge"

echo $replacement # hoge

${value}といった形で{}で囲んで文字列と区別させることが可能

replacement="hoge"

echo "置換文字列は:${replacement}です" # 置換文字列は:hogeです

変数の代入の際、=の前後に空白が入っているとエラーになるので注意

replacement = "hoge" # main.bash: line 1: replacement: command not found

変数展開

ダブルクォーテーションで囲むと変数が展開され、シングルクォーテーションだと展開されない

first="シスイ"
last="うちは"

echo "$first" # シスイ
echo '$last' # $last

文字列結合

単純に繋げて記述するだけでOK

first="シスイ"
last="うちは"

echo "$last$first" # うちはシスイ

配列

定義

array=("element1" "element2" "element3")

要素へのアクセス

echo ${array[0]}  # element1
echo ${array[1]}  # element2
echo ${array[2]}  # element3

配列の長さを取得

echo ${#array[@]}  # 3

配列の全要素に対するループ

  • breakで終了
  • continueで現在のループから抜ける

for

$iが5と等しい場合、break

for i in {1..10}
do
   echo "Number: $i"
   if [ $i -eq 5 ]; then
       break
   fi
done

$iが5と等しい場合、continueし、echoしない

for i in {1..10}
do
   if [ $i -eq 5 ]; then
       continue
   fi
   echo "Number: $i"
done

while

$iが5と等しい場合、break

count=0
while true
do
    count=$((count+1))
    echo "Loop count: $count"
    if [ $count -eq 5 ]; then
        break
    fi
done

$iが5と等しい場合にcontinue

i=0
while [ $i -lt 10 ]
do
  i=$(( $i + 1 ))
  if [ $i -eq 5 ]
  then
    continue
  fi
  echo $i
done

条件分岐

  • 条件分岐は、特定の条件が満たされた場合にだけ、特定のコマンドを実行させる。次の例は、変数 NUM の値が 100 以上なら "OK" と表示する。
  • if [ 条件 ] then コマンド fiの形式で記述する
if [ $NUM -ge 100 ];
then
   echo "OK"
fi

コマンド

echo

echo コマンドは、文字列や変数の内容を画面に表示させるために使用する。以下のような形式で使用する。

echo "Hello World"

特殊文字を含む場合

\nが含まれる文字列をechoで改行コードとして出力したい場合はハイフンeオプションをつける

x="hoge\nfoo"
echo -e "$x"

hoge
foo

リダイレクト

コマンドの実行結果をファイルへ出力することが可能。> は上書き

echo "foo" > file.txt

追記する場合

echo "foo" >> file.txt

echoした結果をechoする

``でコマンド結果を使用することが可能

echo `echo 'foo'` # foo

sed

sed コマンドは、テキストファイルの内容を検索、置換、追加、削除するなど、様々な操作を行うことができる。以下の例では、"Hello"という文字列を"Hi"に置換している。ファイルなどに対して上書き保存する場合は-iオプションを指定してないと上書き保存されないので注意

echo "Hello World" | sed 's/Hello/Hi/g'

変数を使用する場合の注意点

ダブルコーテーションで囲う必要がある。ダブルコーテーションで囲うとエスケープ処理も行われる

replacement="hoge"

echo "foo bar" | sed -e "s/bar/$replacement/g" #foo hoge

シングルコーテーションだと変数名のまま置換されてしまう。エスケープ処理も行われない

replacement="hoge"

echo "foo bar" | sed -e 's/bar/$replacement/g' #foo $replacement

変換したい文字列に"/"が含まれている場合は区切り文字もスラッシュだとかなり視認性が悪くなるので区切り文字を変える方が見やすくておすすめ。また、-eオプションは標準出力に表示するのに対し、-iにすると直接ファイルを編集

replacement="hoge"

sed -i "s|foo/bar/hoge|'$replacement'|g" key.txt

export

export コマンドは、環境変数を設定するためのコマンドで、子プロセスに変数を引き継ぐことができる。次のようにして使用する。

export PRIVATE_KEY="private key"
echo $PRIVATE_KEY

コマンド置換

コマンド置換は、$() の形式で、コマンドの出力結果を取り込むために使用する。

echo "$(echo 'hoge')" # hoge

バッククォートで囲む記述方法でも同じ

echo `echo 'hoge'` # hoge

pwd

カレントディレクトリの取得

cd /Users/username
pwd # /Users/username

cd

カレントディレクトリを切り替える

cd /Users/username/Desktop

ls

ls -lで、特定のディレクトリの内容を詳細なリスト形式で表示できる。各ファイルやディレクトリについて、パーミッション、所有者、グループ、サイズ、最終更新日時、名前が表示される。.から始まる隠しファイルも表示する場合はls -la

ls -la

drwxr-xr-x  7 user  group  224 Sep  1 12:34 .
drwxr-xr-x  5 root  admin  160 Aug 31 09:45 ..
-rw-r--r--  1 user  group  6148 Sep  1 12:34 .DS_Store
drwxr-xr-x  3 user  group   96 Sep  1 12:34 .config
-rw-r--r--  1 user  group    0 Sep  1 12:34 file1.txt
-rw-r--r--  1 user  group    0 Sep  1 12:34 file2.txt
drwxr-xr-x  4 user  group  128 Sep  1 12:34 folder
  1. ファイルタイプとパーミッション:dはディレクトリを示し、-は通常のファイルを示す。その後のrwxr-xr-xはファイルのパーミッションを示す。それぞれ所有者、グループ、その他のユーザーに対するパーミッション。
  2. ハードリンクの数:ファイルやディレクトリへのハードリンクの数
  3. 所有者:ファイルの所有者のユーザー名。
  4. グループ:ファイルの所有者のグループ名。
  5. サイズ:ファイルのサイズ(バイト単位)。
  6. 最終更新日時:ファイルが最後に変更された日時。
  7. 名前:ファイル名またはディレクトリ名。

cat

cat コマンドは、テキストファイルの内容を画面に表示したり、複数のファイルを合成したりする。以下のように使用する。

cat file.txt

catした値をexportする

export PRIVATE_KEY=$(cat key.txt)

less

  • catではファイルの内容をコンソールに出力するだけだが、lessを使用すると上下にスクロールして内容を閲覧できる。特に記述量の多いファイルを参照するのに便利
  • キーボードの上下キー(またはjkキー)を使用してスクロールでき、/を使用して検索も可能
less largefile.txt

vi

ファイルの閲覧と編集が可能

vi myfile.txt

複数コマンドを続けて実行

&

実行したいコマンドに続けて&を付与するとバックグラウンドでそのコマンドを実行することが可能。(=sleepコマンドの実行がコンソールを占有しないので、他のコマンドを続けて入力できる)

sleep 60 &

以下の例の場合、60秒の待機時間を待たずにhogeという文字列が出力される

sleep 60 & echo "hoge"

&&

&とは異なり順次実行(最初のコマンドが正常に完了するのを待ってから次のコマンドが実行される) 

sleep 60 && echo "hoge"

;

&&と異なり、最初のコマンドの成功・失敗に関係なく次のコマンドを実行

sleep 60 ; echo "hoge"

パイプ

パイプを使用すると、連続したコマンドにおいて、1つ目のコマンドの実行結果を2つ目のコマンドへ渡すことができる

echo "foo" | echo $(cat) #foo

kill

プロセスIDを指定して特定のプロセスを強制終了。lsofは指定したポートで起動しているプロセスのIDを取得できる

kill $(lsof -t -i:8000)

以下で直接プロセス名を指定して終了させることも可能

killall python

mv

ファイルの移動とリネームが可能

移動

mv /path/to/source/myfile.txt /path/to/destination/myfile.txt

リネーム

mv oldname.txt newname.txt

find

ファイル検索コマンド。以下のようなディレクトリ構造の場合

dir1/
 ├ dir2/
    ├ hoge.php
    └ foo.php
 └ bar.php

以下のように-name '*.php'とするとファイル名が.phpで終わるすべてのファイルを検索する。*はワイルドカードで、任意の文字列を表すので、カレントディレクトリとそのすべてのサブディレクトリ(どの深さであっても)のphpファイルを検索する。

find . -name '*.php'

./bar.php
./dir2/hoge.php
./dir2/foo.php

grep

ディレクトリ内のすべてのファイルで特定の文字列を検索する。/path/to/searchディレクトリ(およびそのサブディレクトリ)のすべてのファイルでmystringという文字列を検索する。-rオプションにより、ディレクトリを再帰的に検索する

grep -r 'mystring' /path/to/search

mkdir

ディレクトリ作成コマンド

mkdir dir1

touch

ファイル作成コマンド

touch file1.txt

rm

rm コマンドは、ファイルやディレクトリを削除するためのコマンド。以下のように使用する。

ファイル

複数指定も可能

rm file_a file_b

ディレクトリ

複数指定も可能

rm -r dir_a dir_b

強制的に削除

fオプションで削除していいかどうかの質問をスキップして強制的に削除する

rm -rf dir_c

chmod

ファイルやディレクトリのパーミッションを変更するためのコマンド

chmod 755 myfile.txt # myfile.txtという名前のファイルのパーミッションを755(所有者は読み書き実行、グループとその他のユーザーは読み取りと実行)に設定

chown

ファイルやディレクトリの所有者を変更するためのコマンド

chown username:groupname myfile.txt # myfile.txtという名前のファイルの所有者をusernameに、グループをgroupnameに変更

シンボリックリンク

  • 以下のようにすると、/path/to/originalというパスの元のファイルまたはディレクトリへのシンボリックリンクを/path/to/symlinkというパスに作成できる。
  • シンボリックリンクは元のファイルへの「ショートカット」のようなものであるため、元のファイルが移動されたり削除されたりすると、シンボリックリンクは壊れるので注意
  • シンボリックリンクは、ソフトウェアの複数のバージョンを保持し、「現行バージョン」を指すためによく使用されたりする。新しいバージョンに切り替えるときは、シンボリックリンクを新しいバージョンに更新する。
ln -s /path/to/original /path/to/symlink

history

bashシェルで以前に実行したコマンドのリストを表示することが可能

history

1146  jobs
1147  c
1148  history
1149  ls -la
1150  pwd
1151  cat app.yaml

alias

bashシェルでコマンドのショートカットを作成することが可能

alias ll='ls -l' # llと入力するだけでls -lコマンドを実行できるようにするエイリアス

# 登録したエイリアスはaliasコマンドで確認可能
alias

gb='git branch'
gc='git checkout'
gd='git diff'
・・・・

終了コード

コマンド実行時、終了コードは特殊変数$?に代入される。正常終了した場合は0を返す

ok="ok"
echo $ok
echo $? # 0

正常終了以外の場合はエラーコードが返される

ng = "ng"

echo $? # 127

まとめ

以上、エンジニアなら知っておきたいシェルスクリプトの基本的なコマンドについて解説しました。シェルスクリプトは作業自動化のための重要なツールでなので、本記事で解説した内容を参考にしてみてください