目次
趣旨
シェルスクリプトは、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"
donewhile
$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.txtechoした結果をechoする
``でコマンド結果を使用することが可能
echo `echo 'foo'` # foosed
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.txtexport
export コマンドは、環境変数を設定するためのコマンドで、子プロセスに変数を引き継ぐことができる。次のようにして使用する。
export PRIVATE_KEY="private key"
echo $PRIVATE_KEYコマンド置換
コマンド置換は、$() の形式で、コマンドの出力結果を取り込むために使用する。
echo "$(echo 'hoge')" # hogeバッククォートで囲む記述方法でも同じ
echo `echo 'hoge'` # hogepwd
カレントディレクトリの取得
cd /Users/username
pwd # /Users/usernamecd
カレントディレクトリを切り替える
cd /Users/username/Desktopls
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- ファイルタイプとパーミッション:
dはディレクトリを示し、-は通常のファイルを示す。その後のrwxr-xr-xはファイルのパーミッションを示す。それぞれ所有者、グループ、その他のユーザーに対するパーミッション。 - ハードリンクの数:ファイルやディレクトリへのハードリンクの数
- 所有者:ファイルの所有者のユーザー名。
- グループ:ファイルの所有者のグループ名。
- サイズ:ファイルのサイズ(バイト単位)。
- 最終更新日時:ファイルが最後に変更された日時。
- 名前:ファイル名またはディレクトリ名。
cat
cat コマンドは、テキストファイルの内容を画面に表示したり、複数のファイルを合成したりする。以下のように使用する。
cat file.txtcatした値をexportする
export PRIVATE_KEY=$(cat key.txt)less
- catではファイルの内容をコンソールに出力するだけだが、lessを使用すると上下にスクロールして内容を閲覧できる。特に記述量の多いファイルを参照するのに便利
- キーボードの上下キー(または
jとkキー)を使用してスクロールでき、/を使用して検索も可能
less largefile.txtvi
ファイルの閲覧と編集が可能
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) #fookill
プロセスIDを指定して特定のプロセスを強制終了。lsofは指定したポートで起動しているプロセスのIDを取得できる
kill $(lsof -t -i:8000)以下で直接プロセス名を指定して終了させることも可能
killall pythonmv
ファイルの移動とリネームが可能
移動
mv /path/to/source/myfile.txt /path/to/destination/myfile.txtリネーム
mv oldname.txt newname.txtfind
ファイル検索コマンド。以下のようなディレクトリ構造の場合
dir1/
├ dir2/
├ hoge.php
└ foo.php
└ bar.php以下のように-name '*.php'とするとファイル名が.phpで終わるすべてのファイルを検索する。*はワイルドカードで、任意の文字列を表すので、カレントディレクトリとそのすべてのサブディレクトリ(どの深さであっても)のphpファイルを検索する。
find . -name '*.php'
./bar.php
./dir2/hoge.php
./dir2/foo.phpgrep
ディレクトリ内のすべてのファイルで特定の文字列を検索する。/path/to/searchディレクトリ(およびそのサブディレクトリ)のすべてのファイルでmystringという文字列を検索する。-rオプションにより、ディレクトリを再帰的に検索する
grep -r 'mystring' /path/to/searchmkdir
ディレクトリ作成コマンド
mkdir dir1touch
ファイル作成コマンド
touch file1.txtrm
rm コマンドは、ファイルやディレクトリを削除するためのコマンド。以下のように使用する。
ファイル
複数指定も可能
rm file_a file_bディレクトリ
複数指定も可能
rm -r dir_a dir_b強制的に削除
fオプションで削除していいかどうかの質問をスキップして強制的に削除する
rm -rf dir_cchmod
ファイルやディレクトリのパーミッションを変更するためのコマンド
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/symlinkhistory
bashシェルで以前に実行したコマンドのリストを表示することが可能
history
1146 jobs
1147 c
1148 history
1149 ls -la
1150 pwd
1151 cat app.yamlalias
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まとめ
以上、エンジニアなら知っておきたいシェルスクリプトの基本的なコマンドについて解説しました。シェルスクリプトは作業自動化のための重要なツールでなので、本記事で解説した内容を参考にしてみてください