駆け出しエンジニアがシェル芸に入門してみた。(2)


bashを使用することが前提。Linux基礎コマンドチートシート風。
前回の記事:

今回の記事は新しいLinuxの教科書を参照している。

こんな人に読んで欲しい

  • Linuxの基礎を知りたい。
  • 基礎的なコマンドを自分で打ってみたい。

Linuxカーネルとシェルの役割

Linuxの内部では、下記のようなコマンドを実行する際に

  • キーボードから入力されたコマンドの文字列を受け取る。
  • コマンドを探す。(例えばdateというコマンドがないか探す)
  • 見つかったコマンドを実行する。
  • 実行結果を画面に表示する。

といった処理が走っている。コマンドを実行する処理に関してはLinuxカーネルが担っており、コマンド実行の他にもCPUやメモリの管理、裏で走っているプロセスの管理も行なっている。
Linuxカーネルは直接人が操作するようにはできていないため、ユーザとカーネルの間に仲介役となるインターフェースが必要になり、「シェル」はこの仲介役を果たす。

bashとは?なぜbashを使うか?

bashとはshという別のシェルが持つ機能を拡張して、利用しやすくしたシェルの一種。多くのLinux環境でデフォルトのログインシェルとして利用されている。シェルスクリプトを書く上で便利な機能が搭載されている。

利点としては、

  • 多くの場合Linuxでデフォルトのログインシェルとして使われており、利用する機会が多い。
  • 対話的に使うにも、シェルスクリプトを書くうえでも十分な機能を持っている。
  • shとの互換性を持っているため既存のシェルスクリプトを流用できる。
  • Linux以外にもMac OSなどの環境に移植されている。
  • 利用者が多いためwebからの情報収集がしやすい。

等が挙げられる。(だからbashを使おう!と教科書には書いてある。)
(今のとこRuby使う人が多いから、GoじゃなくてRubyから入門しましょうみたいな意見に似てますね。)
以下では実際にシェルスクリプトを書いていく前準備として、頻出のコマンドを紹介する。

(1)date

日付と日時を表示する。

mbp:~ kentaroyoshizumi$ date
2022年 3月19日 土曜日 19時13分44秒 JST

(2)echo

指定した文字列を表記する。

mbp:~ kentaroyoshizumi$ echo Hello
Hello

パスを表示するのにも利用される。

mbp:~ kentaroyoshizumi$ echo $PATH
/Users/kentaroyoshizumi/

(3)sh

シェルを一時的にshに切り替える。

mbp:~ kentaroyoshizumi$ sh
sh-3.2$

(4)bash

シェルを一時的にbashに切り替える。

mbp:~ kentaroyoshizumi$ bash
bash-3.2$

(5)exit

非ログインシェルを脱出する。管理者モードやviエディタを抜けて、通常のモードに切り替える。

bash-3.2$ exit
exit
sh-3.2$ exit
exit
mbp:~ kentaroyoshizumi$

(6)whoami

ユーザIDを表示する。

mbp:~ kentaroyoshizumi$ whoami
kentaroyoshizumi

(7)ping

対象のIPアドレスに対してネットワークの疎通を確認する。

mbp:~ kentaroyoshizumi$ ping 192.168.2.67
ping 192.168.2.67
PING 192.168.2.67 (192.168.2.67): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4
Request timeout for icmp_seq 5

(8)ipconfig/ifconfig

ネットワークインターフェイスの設定を確認する。

mbp:~ kentaroyoshizumi$ ifconfig
lo0: flags=8***<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16***
	options=12**<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet 127. **.*.* netmask ****000000
	inet6 ::* prefixlen 1**
	inet6 fe**::1%lo0 prefixlen ** scopeid 0x1
	nd6 options=2**<PERFORMNUD,DAD>
gif0: flags=8010<POINTOPOINT,MULTICAST~割愛

(9)インクリメンタル検索について

Ctrl + rでインクリメンタル検索(1文字入力するたびに履歴を検索する)を起動する。

(reverse-i-search)`':

例えば"e"と入力すると、直前に入力したeが含まれるコマンドが表示される。

(reverse-i-search)`e': clear

(10)pwd

今いるディレクトリ(カレントディレクトリ)を指す。

mbp:~ kentaroyoshizumi$ pwd
/Users/kentaroyoshizumi

(11)cd

めっちゃ使います!
cd(チェンジディレクトリ)

mbp:~ kentaroyoshizumi$ cd ..
mbp:Users kentaroyoshizumi$ cd ..
mbp:/ kentaroyoshizumi$ cd ..

(13)ls -l (-lを付けるのは、これによってファイル名だけでなく詳細情報を表示するため)

カレントディレクトリのファイル一覧を表示する。

-rw-r--r--    1 kentaroyoshizumi  staff    35  3 ** 23:19 todo.txt
-rw-r--r--    1 kentaroyoshizumi  staff    71  3 ** 23:39 todo1.txt

(14)touch

新しくファイルを作成する。

mbp:/ kentaroyoshizumi$ touch Pikachu.sh
touch: Pikachu.sh: Read-only file system

(15)cat

ファイルを参照する。

mbp:~ kentaroyoshizumi$ cat Pikachu.sh


~
~
~
~
~
~
~
~

(16)less

スクロール表示する。

mbp:~ kentaroyoshizumi$ less /etc/bashrc

# System-wide .bashrc file for interactive bash(1) shells.
if [ -z "$PS1" ]; then
   return
fi

PS1='\h:\W \u\$ '
# Make bash check its window size after a process completes
shopt -s checkwinsize

[ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"

(17)cp

ファイル・ディレクトリをコピーする。

mbp:~ kentaroyoshizumi$ touch zenigame
mbp:~ kentaroyoshizumi$ cp zenigame zenigame2
mbp:~ kentaroyoshizumi$ ls -F
zenigame
zenigame2

(18)mv

ファイルを移動する。(今回はファイルの名前を変えている。)

mbp:~ kentaroyoshizumi$ mkdir mvtest
mbp:~ kentaroyoshizumi$ cd mvtest
mbp:mvtest kentaroyoshizumi$ touch hitokage
mbp:mvtest kentaroyoshizumi$ mv hitokage hitokage2(移動先に新ファイル名を指定している。)
mbp:mvtest kentaroyoshizumi$ ls
hitokage2

(19)find

find <検索開始ディレクトリ> <検索条件> <アクション>

(20)locate

locate [オプション] <検索パターン>

(21)man

マニュアルを表示する。

mbp:~ kentaroyoshizumi$ man cd
(マニュアルを表示できるコマンドと、説明がダーっと表示される。)
NAME
     builtin, !, %, ., :, @, {, }, alias, alloc, bg, bind, bindkey, break,
     breaksw, builtins, case, cd, chdir, command, complete, continue, default,
     dirs, do, done, echo, echotc, elif, else, end, endif, endsw, esac, eval,
     exec, exit, export, false, fc, fg, filetest, fi, for, foreach, getopts,
     glob, goto, hash, hashstat, history, hup, if, jobid, jobs, kill, limit,
     local, log, login, logout, ls-F, nice, nohup, notify, onintr, popd,
     printenv, pushd, pwd, read, readonly, rehash, repeat, return, sched, set,
     setenv, settc, setty, setvar, shift, source, stop, suspend, switch,
     telltc, test, then, time, times, trap, true, type, ulimit, umask,
     unalias, uncomplete, unhash, unlimit, unset, unsetenv, until, wait,
     where, which, while -- shell built-in commands

SYNOPSIS
     builtin [-options] [args ...]

DESCRIPTION
     Shell builtin commands are commands that can be executed within the run-
     ning shell's process.  Note that, in the case of csh(1) builtin commands,
     the command is executed in a subshell if it occurs as any component of a
     pipeline except the last.

(22)which

コマンドのフルパスを表示する。

mbp:~ kentaroyoshizumi$ which aws
bin/bash

(23)chmod

ファイルモードを変更する。

mbp:~ kentaroyoshizumi$ chmod 755 zenigame2(zenigame2のファイルに読み書き権限を与えている。)

(24)groups

自分が今どの権限を持ったグループに属しているか確認。

mbp:~ kentaroyoshizumi$ groups
staff everyone localaccounts _appserverusr

(25)source

ファイルに書かれたコマンドを現在のシェルで実行する。(実行権限は不要)

mbp:~ kentaroyoshizumi$ source ~/.bashrc

(bashの環境設定ファイル~/.bashrcの内容を反映させる)

(26)su

ユーザを変更する。(パスワードの入力を求められる。)

mbp:~ kentaroyoshizumi$ su
Password:

...
mbp:~ kentaroyoshizumi$ exit(管理者モードから抜ける。)

(27)sudo

ホントはダメだけど。。。 めっちゃ使います!
管理者権限をもってコマンドを実行する。(Permission deniedという文言がターミナルに表示された際、力技でコマンド実行するためによく使っていました。笑)

mbp:~ kentaroyoshizumi$ sudo cat /etc/shadow
[sudo] password for kentaroyoshizumi:(今ログインしているユーザのパスワードを求められる)

(28)vi

viエディタを起動してファイルの編集を行う。

mbp:~ kentaroyoshizumi$ vi zenigame2
~
~
~
~
~
~
:wq(保存して終了するという、viエディタ特有の書き方。)

(29)ps

動作しているプロセスを表示する。

mbp:~ kentaroyoshizumi$ ps
  PID TTY           TIME CMD
74312 ttys001    0:00.13 -bash

(30)jobs

実行中のジョブ一覧を表示する。

mbp:~ kentaroyoshizumi$ jobs
[1]- 停止        man bash
[2]+ 停止        man vi /etc/crontab

(31)fg

ジョブをフォアグラウンドにする。

mbp:~ kentaroyoshizumi$ fg %1
(bashのmanコマンドを画面に表示し、キーボードで操作できるようにする。)

(32)bg

ジョブをバックグラウンドにする。

mbp:~ kentaroyoshizumi$ bg %1
(処理に長い時間がかかる動作を裏側で実行させて、キーボード側で別の操作ができるようにする。)

mbp:~ kentaroyoshizumi$ jobs
[1]+ 実行中  %1  (裏側で%1が実行中であると表示が出る。)

(33)kill

バックグラウンドで実行中のジョブを停止する。(Ctrl+c では停止できないジョブを停止する。)

mbp:~ kentaroyoshizumi$ kill %1

(34)crontab

cronの設定をする。(ここで詳しくは解説できないので、興味のある方は調べてみて下さい。)
こんなのが表示される。

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed

(35)history | less

これまで打ったコマンドの履歴をスクロール表示する。(historyとlessを同時に行えという命令。)

  0  touch zenigame
  1  cp zenigame zenigame2
  2  ls -F
  3  rm zenigame
  4  rm zenigame2
  5  ls -F
  6  clear
  7  mkdir mvtest
  8  cd mvtest
  9  touch hitokage
  10  mv hitokage hitokage2
  11  ls
  12  rm hitokage2
  13  cd ..
  14  rmdir mvtest
  15  ls
  16  man cd
  17  /etc/crontab
  18  groups

(36)grep

指定した検索パターンに一致する行だけを表示する。

mbp:~ kentaroyoshizumi$ grep cooking todo1.txt
・cooking

(37)du

指定したファイルやディレクトリの使用容量を表示する。

~一部割愛
4152	./docker-rails/tmp/cache/assets/sprockets/v3.0
4152	./docker-rails/tmp/cache/assets/sprockets
4152	./docker-rails/tmp/cache/assets
4152	./docker-rails/tmp/cache
0	./docker-rails/tmp/sockets
4160	./docker-rails/tmp
0	./docker-rails/vendor/assets/javascripts
0	./docker-rails/vendor/assets/stylesheets
0	./docker-rails/vendor/assets
0	./docker-rails/vendor
7080	./docker-rails
19615736	.

(38)clear

めっちゃ使います!
ターミナルに表示された履歴を一旦リセットする際に使う。

mbp:~ kentaroyoshizumi$ ls -l
Applications
AssetTest
Desktop
Documents
Downloads

mbp:~ kentaroyoshizumi$ clear

(表示が消えている!)

(39)wc

行数やバイト数を表示する。(オプションもなんもつけずに実行して、ひどい目に遭いました。笑)

mbp:Downloads kentaroyoshizumi$ wc
^C

(40)sort

「ABC..」と順に並び替える。(duしたものでサイズの大きい上位5つを表示。)

mbp:Downloads kentaroyoshizumi$ du * | sort -n | head -n 5
0	OnVUE 2.app/Contents/Resources/am.lproj
0	OnVUE 2.app/Contents/Resources/ar.lproj
0	OnVUE 2.app/Contents/Resources/bg.lproj
0	OnVUE 2.app/Contents/Resources/bn.lproj
0	OnVUE 2.app/Contents/Resources/ca.lproj(AWS SAA受けた時のゴミが出てきたw)

(41)uniq

重複行を取り除く。

prefecture.txt
Fukuoka
Fukuoka
Tokyo
Osaka

こんなファイルを用意したとして、下記のように表示される。

mbp:~ kentaroyoshizumi$ uniq prefecture.txt
Fukuoka
Tokyo
Osaka

(42)cut -d -f [ファイル名]

mbp:~ kentaroyoshizumi$ cut
usage: cut -b list [-n] [file ...]
       cut -c list [file ...]
       cut -f list [-s] [-d delim] [file ...](横着してたら怒られた。笑)

(43)tr

入力の文字を入れ替える。削除する。例えば下記のようなファイルを作成して。

mbp:~ kentaroyoshizumi$ touch todo.txt
mbp:~ kentaroyoshizumi$ vi todo.txt
todo.txt
・shopping
・studying
・cooking
mbp:~ kentaroyoshizumi$ cat todo.txt | tr ・ :    (・を:に書き換えるよう命令しました。)
:shopping
:studying
:cooking

(44)tail

末尾部分を表示する。(デフォルトで末尾10行を表示するため今回は変化無し。)

tail todo.txt
・shopping
・studying
・cooking

(45)diff

差分を抽出する。

mbp:~ kentaroyoshizumi$ cp todo.txt todo1.txt
mbp:~ kentaroyoshizumi$ vi todo1.txt

todo1.txtファイルに内容を追加していく。($ vi todo1.txt を実行する。)

todo1.txt
・shopping
・studying
・cooking
・eating
・washing
・watching TV
mbp:~ kentaroyoshizumi$ diff todo1.txt todo.txt
4,6d3
< ・eating
< ・washing
< ・watching TV

(46)ホームディレクトリのディレクトリのファイル使用量を表示する。(唐突なシェルスクリプトw)

$ du -h ~| tail -n 1
$ vim homefilesize.sh
#!/bin/bash

du -h ~| tail -n 1
実行権限を付与する。
$ chmod +x homefilesize.sh
$ ./homefilesize.sh(実行してみたらやばいコマンドだったので、Ctrl+cで逃げましょう。)

du: /Users/kentaroyoshizumi/Pictures/Photos Library.photoslibrary: Operation not permitted
du: /Users/kentaroyoshizumi/Library/Application Support/MobileSync: Operation not permitted
du: /Users/kentaroyoshizumi/Library/Application Support/CallHistoryTransactions: Operation not permitted

(47)tar

複数のファイルを1つにまとめた“アーカイブファイル”を作成/展開する。

$ tar cf <アーカイブファイル> <アーカイブ元ファイルパス>という使い方をする。
ここではtodos.tarというファイルをカレントディレクトリに作成する。

mbp:~ kentaroyoshizumi$ tar cf todos.tar ./
mbp:~ kentaroyoshizumi$ ls
todos.tar  todo.txt  todo1.txt

次回からはいよいよ本格的にシェルスクリプトを書いていきます!