Linux標準教科書 第4章(v304対応)
正規表現とパイプ
4.1 標準入出力
Linuxのプログラムには「1つの入り口と2つの出口」があります。それを標準入力(キーボード)・標準出力(プログラムの実行結果を書き出す先端末のディスプレイ)・標準エラー出力(プログラムを実行した端末のディスプレイ)と言います。
4.2 リダイレクト
コンソールに標準出力された文字はリダイレクトを使ってファイルに書き込む事ができます。「 > 」を使います。
4.2.1 出力のリダイレクト
次のコマンドは ls の結果を出力をリダイレクトして、ファイルに書き込む例です。>の記号を用 いることでリダイレクトができます。
実行例
$ ls > ls-output
$ cat ls-output
コマンドを実行すると ls-output というファイルが作成されます。cat コマンドで、ファイル ls-output の中身を確認してください。ls を実行したときと同じ内容が含まれています。このように リダイレクトを用いると、出力先を変更しファイルに出力を格納することができます。
実習:ファイルへのリダイレクト
$ cd /etc
$ ls > ~/ls-output
$ cat ~/ls-output
ls-output というファイルが作成されてその中に ls の出力結果が保存されました。すでに ls- output が存在しているときは、前の ls-output が削除されて新しい ls-output が作成されます。上 書きせず追記したい場合は、アペンド (>>) の記号を用います。
4.2.2 cat コマンドによるファイル作成
cat (3.3.1参照)コマンドとリダイレクトを組み合わせると自由な内容でファイルを作成できます。
実習:cat コマンドによるファイル作成
$ cd ~
$ cat > cat-output
Hello
This is cat redirect.
「Ctrl」D は EOF(End Of File) を示すキーで、データ入力の終わりを示します。Linux ではデー タの読み込みが最後になると、この EOF が入力され終わる決まりがあります。cat は EOF を受け 取ったことで入力が終わったと判断し、リダイレクトを終了します。
4.3 標準エラー出力
コンピュータを操作しているとさまざまなエラーが起きることがあります。エラーは画面とログ に出力されます。
例えば以下のコマンドを実行する場合を考えてみましょう。実行例では tekitou というディレク トリの内容を ls-l-ouput というファイルに出力しようとしています。
$ ls -l tekitou > ls-l-output
ls: tekitou: No such file or directory
(tekitou というディレクトリが見つからなかったというエラーメッセージ)
しかし、tekitou というディレクトリが存在しなかった場合、「そのようなファイルやディレクト リはありません」といったエラーメッセージが標準出力されます。 このようにエラーメッセージは通常は標準出力されますが、リダイレクトを用いて任意のファイ ルにファイル出力することもできます。
実行例
$ ls -l tekitou 2> ls-l-output
(エラー出力を ls-l-output にリダイレクト)
この場合、エラーメッセージは画面に現れず、指定したファイルに出力されます。コマンド中で 指定している“2”は、標準エラー出力を示しています。標準出力は“1”を指定します。標準出力と標準 エラー出力を 1 つのファイルに出力したい場合、次のように入力します。
実行例
$ ls -l tekitou 2> ls-l-output
$ ls -l tekitou > ls-l-output-second 2>&1
標準出力とエラー出力を ls-l-output-second にリダイレクトしました。ファイルの指定と、1,2 の 指定の位置を間違えないようにしてください。
4.3 パイプ
標準入力からデータを入れる事により特別な処理ができるコマンドがあります。
実行例
$ ls -l /usr/bin
合計 50788
lrwxrwxrwx 1 root root 45 7月 16 2015 VBoxClient -> /opt/VBoxGuestAdditions-4.3.28/bin/VBoxClient
lrwxrwxrwx 1 root root 46 7月 16 2015 VBoxControl -> /opt/VBoxGuestAdditions-4.3.28/bin/VBoxControl
-rwxr-xr-x. 1 root root 41448 6月 10 2014 [
-rwxr-xr-x 1 root root 107824 3月 6 2015 a2p
-rwxr-xr-x. 1 root root 29016 3月 5 2015 addr2line
-rwxr-xr-x. 1 root root 29 3月 5 2015 alias
lrwxrwxrwx. 1 root root 6 7月 16 2015 apropos -> whatis
※以下略
ファイルがたくさんあり見切れていまします。そこで コマンドとコマンドを「 | 」(パイプ シフト+¥)でつなげることでパイプ前のコマンドを後ろのコマンド less (ページャ)の標準入力とする事ができます。
GNOME などのデスクトップ環境がインストールされている場合は、端末上でカーソルキーを押 すことでページングすることができるため、操作する端末が目の前にある場合は、ページャにパイ プで繋ぐ必要はあまりないかもしれません。しかし端末をリモート操作している場合やデスクトッ プ環境がインストールされていない Linux 環境の場合は、パイプでつなげる方法を知っておくと大 変便利です。
$ ls -l /usr/bin | less
合計 50788
lrwxrwxrwx 1 root root 45 7月 16 2015 VBoxClient -> /opt/VBoxGuestAdditions-4.3.28
/bin/VBoxClient
lrwxrwxrwx 1 root root 46 7月 16 2015 VBoxControl -> /opt/VBoxGuestAdditions-4.3.2
8/bin/VBoxControl
-rwxr-xr-x. 1 root root 41448 6月 10 2014 [
-rwxr-xr-x 1 root root 107824 3月 6 2015 a2p
-rwxr-xr-x. 1 root root 29016 3月 5 2015 addr2line
-rwxr-xr-x. 1 root root 29 3月 5 2015 alias
lrwxrwxrwx. 1 root root 6 7月 16 2015 apropos -> whatis
-rwxr-xr-x. 1 root root 58472 3月 5 2015 ar
-rwxr-xr-x. 1 root root 33048 6月 10 2014 arch
-rwxr-xr-x. 1 root root 365200 3月 5 2015 as
-rwxr-xr-x. 1 root root 28800 3月 5 2015 aserver
※以下略
標準エラー出力で説明した、標準出力と標準エラー出力を 1 つのファイルに出力する場合の方法 も利用可能です。次のように入力してください。
実行例
$ ls -l xxx /usr/bin 2>&1 | less
xxx は存在しませんが、その旨のメッセージはリダイレクトにより標準出力に出力されます。
実習:コマンドの実行結果をlessコマンドでページング表示
$ ls -l /usr/bin | less
:
: 操作
:
(q を入力して終了)
4.5 grep コマンド
grep コマンドはファイルの中からデータを検索します。「 | grep 」 とする事で標準入力から入ったデータに対して検索を行う事も可能です。また * ワイルドカードを利用した複数ファイルの指定もできます。検索条件として正規表現が用いられます。非常に重要な機能です。
4.5.1 正規表現
正規表現は文字列のみならず、意味のある記号を用いる事で高度な検索条件を与える表現方法です。
実習:grep コマンドの実行
/etc ディレクトリにあるファイルで abc という文字列を含むものを検索します。
$ grep abc /etc/*
・
・
/etc/services:abcvoice-port 3781/tcp # ABCvoice server port
/etc/services:abcvoice-port 3781/udp # ABCvoice server port
/etc/services:abcsoftware 3996/tcp # abcsoftware-01
/etc/services:abcsoftware 3996/udp # abcsoftware-01
/etc/services:omabcastltkm 4359/tcp # OMA BCAST Long-Term Key Messages
/etc/services:omabcastltkm 4359/udp # OMA BCAST Long-Term Key Messages
・
・
/etc ディレクトリにあるファイルで行の先頭が xy で始まっているものを検索
$ grep ^xy /etc/*
・
・
/etc/services:xyplex-mux 173/tcp # Xyplex
/etc/services:xyplex-mux 173/udp # Xyplex
/etc/services:xybrid-rt 9978/tcp # XYBRID RT Server
・
・
・
先頭が root 文字から始まり何かかしらの文字を /etc/passwd から抽出します。
$ su –
パスワード:
su – で rootに入ります。
# grep “^root.*” /etc/passwd
root:x:0:0:root:/root:/bin/bash
4.5.2 さまざまな条件を用いた grep コマンドの実行
実習:さまざまな条件を用いた grep コマンドの実行
オプション -i で 大文字小文字の hostname という文字列を含むファイルの検索
# grep -i hostname /etc/*
grep: /etc/ppp: Ist ein Verzeichnis
grep: /etc/prelink.conf.d: Ist ein Verzeichnis
/etc/profile:HOSTNAME=`/usr/bin/hostname 2>/dev/null`
/etc/profile:export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
grep: /etc/profile.d: Ist ein Verzeichnis
grep: /etc/puppet: Ist ein Verzeichnis
オプション -v で abc という文字列含むが tcp という文字列を含まないファイルの検索
# grep abc /etc/* | grep -v tcp
grep: /etc/yum: Ist ein Verzeichnis
grep: /etc/yum.repos.d: Ist ein Verzeichnis
/etc/services:abcvoice-port 3781/udp # ABCvoice server port
/etc/services:abcsoftware 3996/udp # abcsoftware-01
/etc/services:omabcastltkm 4359/udp # OMA BCAST Long-Term Key Messages
4.5.3 標準出力にマッチさせる
実習:標準出力の結果を grep で検索
grep コマンドはファイルの内容に一致させる以外に、標準入力からの入力をマッチさせる事が可能です。
/usr/bin にあるコマンド一覧を出力します。 grep -e d$ と指定し -e オプションで文字列を検索パターンとして扱いファイル名が d で終わるファイルを /usr/bin から検索しています。
# ls /usr/bin/ | grep -e d$
cd
chmod
command
db_load
dbus-send
dd
expand
find
firewall-cmd
firewall-offline-cmd
4.6 章末テスト(解答は下記へ)
(1) grep コマンドを利用し、行頭が a または b で始まる業を抽出できる正規表現を以下の4つの中から選びなさい。
- grep -e ^(ab)
- grep -e ^”ab”
- grep -e ^{ab}
- grep -e ^[ab]
(2) 「ls /usr/bin | grep -e ^a..$」というコマンドを実行した場合、どのような結果になるが答えなさい
(3) パス /etc の中にあるファイルでファイル名が conf で終わるものを grep とパイプを用いて記述しなさい。
(4) ls -l を実行した結果を ls-result ファイルに書き込む場合のコマンドを記述しなさい。
(5) chkconfig –list の実行結果から iptables だけを絞り込んで表示するコマンドを grep を使って記述しなさい。
テキストと問題集の購入は下記の画像をクリックして下さい。
章末テスト解答
(1) 4
(2) /usr/bin ディレクトリ以下にあるファイル群からファイル名が a から始まりファイルの文字が3文字であるファイルを抽出
(3) ls /etc/ | grep “conf$”
(4) ls -l > ls-result
(5) chkconfig –list | grep iptables
※CentOS7から/etc/sysconfig/iptablesがありません。iptablesを利用する場合には、iptables.serviceをインスールしないといけません。 さらに、firewalldがデフォルトでオンになっているからオフにしないと競合する。systemctl list-unit-files | grep firewalld かな?