WindowsSubsystemForLinux
Kuin
KuinDay 21

CSセミナー007 bash入門


概要

第7回では、Windows Subsystem for Linux(Ubuntu)の基本操作を学ぶために、そのデフォルトのシェルであるbashについて解説します。


Ubuntuを立ち上げる

Microsoft StoreからUbuntuをインストールされましたでしょうか?Ubuntuを立ち上げるためには、Cortanaにubuntuと入力して、Ubuntuと記載のあるアプリを選択します。

001.png

すると、コマンドプロンプトのような画面が表示されます。

002.png

この画面では、実際にはbashというプログラムが動いています。Linuxではキーボード入力によってコンピュータを操作するプログラムのことをシェルと言います。bashはUbuntuがデフォルトで設定しているシェルです。


ディレクトリ

エクスプローラは、とあるフォルダを表示しています。

003.png

この画面は、デスクトップを表示しています。ところでWindowsのフォルダは一般的にはディレクトリ(directory)と言います。bashも、とあるディレクトリを参照しています。bashが参照しているディレクトリのことをカレントディレクトリ(current directory)と言います。

ディレクトリ(directory)をOxford Directoryで検索すると以下のような定義が出てきます。


A book or website listing individuals or organizations alphabetically or thematically with details such as names, addresses, and telephone numbers.


用例としては、company directoryが社員名簿、telephone directoryが電話帳といった感じです。

カレント(current)は、形容詞としては「現在の」、名詞としては「流れ、傾向、電流」という意味があります。したがってカレントディレクトリとは「現在のディレクトリ」という意味です。

カレントディレクトリを表示するにはpwdコマンドを入力します。

user1@tamuken8:~$ pwd

/home/user1

ここで、user1は私のユーザー名であり、tamuken8はマシン名です。

次に、WindowsのCドライブのルートディレクトリに移動します。WindowsでいうC:¥のことです。

user1@tamuken8:~$ cd /mnt/c

user1@tamuken8:/mnt/c$ pwd
/mnt/c

cdコマンドはカレントディレクトリを変更します。/はLinuxのファイルシステムのルートディレクトリです。ルート(root)とは「木の根」のことであり、ルートディレクトリとは親のいないディレクトリのことです。Windowsのファイルシステムにおいてルートディレクトリはドライブレターの数だけ存在しますが、Linuxのファイルシステムでは1つです。

WSLでは/mntディレクトリの下に、ドライブレターの名前のディレクトリがあります。これがWindowsのルートディレクトリになります。したがって、D:¥のディレクトリパスは/mnt/dとなります。


ファイルを検索する

さて、Linuxでファイルを検索するにはどうすればいいのでしょうか。ブラウザに「Linux ファイルを検索」と入力して検索してみましょう。findコマンドを使うと書いてあったのではないかと思います。さて、findと入力してみましょう。

001.gif

findコマンドは引数無しで呼び出すとカレントディレクトリと、そのサブディレクトリのすべてのファイルを表示します。しかしC:¥の中にはたくさんのファイルが入っているのでこのコマンドが終了するのにとても時間がかかります。コマンドを途中で強制終了させるためには[Ctrl + C]キーを入力します。

ここで、grepファイルを併用してみます。例えば、C:¥以下にあるkernel32.dllというファイルを検索してみます。

002.gif

このとき、findコマンドは大量のPermission deniedというエラーメッセージを出力します。Windowsにはユーザーがアクセスできないファイルやディレクトリが多数存在しています。さて、findコマンドの簡易ヘルプを見るためにfind --helpと入力してみます。

user1@tamuken8:/mnt/c$ find --help

Usage: find [-H] [-L] [-P] [-Olevel] [-D debugopts] [path...] [expression]

default path is the current directory; default expression is -print
expression may consist of: operators, options, tests, and actions:
operators (decreasing precedence; -and is implicit where no others are given):
( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2
EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2
positional options (always true): -daystart -follow -regextype

normal options (always true, specified before other expressions):
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
--version -xdev -ignore_readdir_race -noignore_readdir_race
tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N
-cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME
-ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN
-links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE
-nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN
-readable -writable -executable
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N
-used N -user NAME -xtype [bcdpfls] -context CONTEXT

actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print
-fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit
-exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;
-execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;

Valid arguments for -D:
exec, help, opt, rates, search, stat, time, tree
Use '-D help' for a description of the options, or see find(1)

Please see also the documentation at http://www.gnu.org/software/findutils/.
You can report (and track progress on fixing) bugs in the "find"
program via the GNU findutils bug-reporting page at
https://savannah.gnu.org/bugs/?group=findutils or, if
you have no web access, by sending email to <bug-findutils@gnu.org>.

たいていの場合、この簡易ヘルプを見れば分かるのですが、分かりづらいですね。ブラウザに「find Permission Denied」と入力して検索してみましょう。だいたいこのように入力することで解決しているようです。

003.gif

find 2> /dev/null | grep kernel32.dll'と入力したのですが、これの2> /dev/nullというのはfindコマンドの標準エラー出力をファイル/dev/nullにリダイレクトするという意味です。デフォルトでは標準出力と標準エラー出力の2つがコンソールに出力されますが、2> /dev/nullと入力することによって標準エラー出力の出力を抑制しています。Linuxで/dev/null`というファイルがどういう意味を持っているのかを検索してみましょう。

/dev/null - Wikipedia

Wikipediaでもいいのですが、Linuxのマニュアルを読みたいところですね。「manual /dev/null」で検索すると「null(4)」と書いてあるページが散見されます。この、(4)(3)などがついているようなページはmanコマンドで見ることができる可能性が高いので、man nullと入力してみます。

004.png

/dev/nullのマニュアルページが表示されました。スペシャルファイル/dev/nullまたはdev/zeroに書いたデータは破棄されます、とあります。ちょっと分かりづらいですがそういうものなのだと覚えておいてください。このマニュアルページはqボタンを押すと終了します。


ホームディレクトリ

さて、今はカレントディレクトリが/mnt/cになっているはずです。bash起動時のディレクトリは/home/user1(私の場合)でしたが、このディレクトリのことをホームディレクトリ(home directory)と言います。それではホームディレクトリに戻ってみましょう。

user1@tamuken8:/mnt/c$ pwd

/mnt/c
user1@tamuken8:/mnt/c$ cd ~
user1@tamuken8:~$ pwd
/home/user1

cd ~と入力するとホームディレクトリに戻ります。bashでは、~(チルダ)はホームディレクトリを表します。


echoコマンド

echoコマンドは標準出力にechoコマンドの引数を出力します。ABCを出力してみます。

user1@tamuken8:~$ echo "ABC"

ABC

次の3行の出力をさせることを考えます。

くいなちゃん6さい

Kuin Language
Windows

これをechoコマンドで行うには、文字列記述の中で改行してやります。

004.gif


grepコマンド

さて、grepコマンドは与えられた標準入力かファイルの中でパターンにマッチした行を出力するコマンドです。先ほど、find | grep kernel32.dllと入力しましたが、この意味は、「findコマンドの標準出力をgrepの標準入力に渡してkernel32.dllというパターンにマッチした行を標準出力に出力する」という意味です。|(バーティカルライン)はパイプというOSの機能を使うための記述です。今度はechogrepを組み合わせてみましょう。

user1@tamuken8:~$ echo "ABC" | grep "ABC"

ABC
user1@tamuken8:~$ echo "ABCDEF" | grep "BCDE"
ABCDEF
user1@tamuken8:~$ echo "" | grep "ABC"
user1@tamuken8:~$ echo "ABC" | grep "くいなちゃん"
user1@tamuken8:~$ echo "くいなちゃん6さい" | grep "くいなちゃん6さい"
くいなちゃん6さい
user1@tamuken8:~$ echo "くいなちゃん" | grep "くいなちゃん6さい"
user1@tamuken8:~$ echo "くいなちゃん6さい" | grep "くいなちゃん"
くいなちゃん6さい
user1@tamuken8:~$ echo "くいなちゃん6さい" | grep "6さい"
くいなちゃん6さい

この挙動はどことなく正規言語に似ているように思いませんか?ただし正規言語では完全一致をさせていましたが、grepの正規表現では部分一致のパターンマッチを行います。完全一致を行うにはパターンを^$で囲みます。

user1@tamuken8:~$ echo "くいなちゃん" | grep "^くいなちゃん$"

くいなちゃん
user1@tamuken8:~$ echo "くいなちゃん6さい" | grep "^くいなちゃん$"
user1@tamuken8:~$ echo "おはようくいなちゃん" | grep "^くいなちゃん$"

前方一致を行うにはパターンの後ろに$を書きます。

user1@tamuken8:~$ echo "くいなちゃん" | grep "くいなちゃん$"

くいなちゃん
user1@tamuken8:~$ echo "くいなちゃん6さい" | grep "くいなちゃん$"
user1@tamuken8:~$ echo "おはようくいなちゃん" | grep "くいなちゃん$"
おはようくいなちゃん

後方一致を行うにはパターンの前に^を書きます。

user1@tamuken8:~$ echo "くいなちゃん" | grep "^くいなちゃん"

くいなちゃん
user1@tamuken8:~$ echo "くいなちゃん6さい" | grep "^くいなちゃん"
くいなちゃん6さい
user1@tamuken8:~$ echo "おはようくいなちゃん" | grep "^くいなちゃん"


exitコマンド

bashを終了させるにはexitと入力します。


まとめ

今回はbashの使用方法について簡単に学びました。