😎

Envaderを利用して、findコマンドを学ぶ

2022/03/27に公開

今回は、いつもお世話になっているEnvaderを利用して、findコマンドについて学んでみたので、その振り返りとまとめです。

Envaderは環境構築が不要で、オンラインでLinux環境について学べるサービスになっています。
手軽にコマンドの確認や環境構築について実践的に学べるので、利用させていただいてます。

Envaderについて気になる方は、リンクを貼っておきますので参考にどうぞ。

コース一覧

今回使用したシナリオ

findコマンド

findコマンドは、指定したディレクトリ以下から、検索条件にマッチするファイルやディレクトリを検索するコマンドです。
オプションを指定する事で、更新日時やファイル名を条件に検索することもできます。

以下基本の書き方

find 検索ディレクトリ 検索式

注意点

その1

上記の検索ディレクトリを省略した場合には、カレントディレクトリ(現在自分が作業しているディレクトリ)が検索対象になります。
検索対象のディレクトリにアクセスできる権限を持っていないとPermission deniedになってしまうそうです。

この意味がよく分からなかったので、実際にコマンドを実行してみて理解できました。
注意しないといけませんね。

# rootディレクトリにはその他のグループの権限がない

envader@172-19-1-2:/$ ls -l
total 84
drwxr-xr-x   1 root root    4096  411  2021 bin
drwxr-xr-x   2 root root    4096  710  2020 boot
drwxr-xr-x   5 root root     340  324 19:15 dev
-rwxr-xr-x   1  502 dialout  268  620  2021 docker-entrypoint.sh
drwxr-xr-x   1 root root    4096  324 19:15 etc
drwxr-xr-x   1 root root    4096  830  2021 home
drwxr-xr-x   1 root root    4096  98  2020 lib
drwxr-xr-x   2 root root    4096  98  2020 lib64
drwxr-xr-x   2 root root    4096  98  2020 media
drwxr-xr-x   2 root root    4096  98  2020 mnt
drwxr-xr-x   1 root root    4096  324 19:15 opt
dr-xr-xr-x 147 root root       0  324 19:15 proc
drwx------   2 root root    4096  98  2020 root

# rootディレクトリの中を検索してみるとエラーが発生
envader@172-19-1-2:/$ find /root -name "*.txt"
find: ‘/root’: Permission denied

その2

LinuC教科書によると、検索式の部分は、メタキャラクタとしてシェルに解釈されないように、引用符である""で囲んだ方が良い。と紹介されていました。

カレントディレクトリに.goファイルが複数存在すると、引数が多くなりすぎてエラーになってしまいます。findコマンドに引数が渡される前に、シェルによってメタキャラクタが展開されてしまうためです。

どう言うことか理解できなかったので、自分で試してみました。

envader@172-19-1-2:~$ ls
main.go  main.py  main2.go  main2.py  main3.go  main3.py  main4.go  main4.py

# エラーが発生
envader@172-19-1-2:~$ find -name *.go
find: paths must precede expression: main2.go
Try 'find --help' for more information.

# 引用符で囲むことにより、ちゃんと検索された
envader@172-19-1-2:~$ find -name "*.go"
./main4.go
./main2.go
./main.go
./main3.go

確かに""で囲まない場合、エラーになっていますね。

ちなみに、""ではなく\バッククオーテーションをつける事でもエラーが回避できるようです。

envader@172-19-1-2:~$ find -name \*.go
./main4.go
./main2.go
./main.go
./main3.go

どちらを利用するかは自分次第ですね。

メタキャラクタ

上の検索コマンドでも使用しましたが、メタキャラクタと呼ばれるファイル名のパターンを表す特殊な記号を使用することで、柔軟性の高い検索処理を行うことも可能です。

メタキャラクタ 説明
* 0文字以上の文字または文字列にマッチする。a*だと、a,ab,abc,aaaaのいずれにもマッチする。
? 任意の1文字にマッチする。a?はaa,ab,a1など2文字にマッチして、abcなど3文字にはマッチしない。

他にもメタキャラクタはありますが、今回は割愛させていただきます。

こちらの記事に詳しく解説されていました。

Linuxのメタキャラクタ~メタキャラクタについて~

findコマンドのオプション

オプション 内容
-name ファイル名で検索する
-atime アクセスした時間を指定して検索する
-mtime 更新した時間を指定して検索する
-perm 権限を指定して検索する
-size ファイルサイズを指定して検索する
-type ファイルの種類で検索する fファイル dディレクトリ lシンボリックリンク
-user 所有者で検索する
-print マッチしたファイルを表示する
-ls ls -lコマンドのようにファイルの詳細を表示する
-exec マッチしたファイルに対してコマンドを実行する
-empty 空のファイルやディレクトリを検索する

-name

ファイル名を指定して検索する。
先ほども紹介していた検索方法です。

envader@172-19-1-2:~$ find -name \*.go
./main4.go
./main2.go
./main.go
./main3.go

-atime

ファイルにアクセスした時間を指定して検索する

  • atimeの後ろに任意の日数を入力する。
  • 0は今日、1は昨日、2は一昨日を表す。
  • 日数の数字の前に-を付けた場合には、その日数以内を表す。-3であれば、3日以内にアクセスされたファイルを表す。
  • 逆に、日数の前に+を付けた場合には、その日数より前を表す。+3であれば、3日よりも前にアクセスされたファイルを意味する。
envader@172-19-2-2:~$ ls -lt | grep .py                                           
-rw-r--r-- 1 envader envader  41  324 19:45 main4.py
-rw-r--r-- 1 envader envader  48  324 19:45 main.py
-rw-r--r-- 1 envader envader  49  322 19:45 main2.py
-rw-r--r-- 1 envader envader  48  321 19:45 main3.py

# 本日27日から3日以内にアクセスされたファイルを検索
envader@172-19-2-2:~$ find -name "*.py" -atime -3
./main4.py
./main.py

# 3日よりも前にアクセスされたファイルを検索
envader@172-19-2-2:~$ find -name "*.py" -atime +3
./main3.py
./main2.py

ちゃんとできていますね。

-type

個人的に便利だなと思ったのはこの-typeオプション。
ファイル ディレクトリ シンボリックリンク などを指定して検索できる。

# ディレクトリを指定して検索
envader@172-19-2-2:~$ find -type d
.
./.ssh

# ファイルを指定して検索
envader@172-19-2-2:~$ find -type f
./.profile
./.bashrc
./.bash_logout
./.bash_history
./main4.go
./main4.py
./main.py
./main3.py
./main2.go
./main2.py
./main.go
./main3.go
./.tmux.conf

-empty

中身が空のファイルやディレクトリを検索する。

envader@172-19-2-2:~$ find -empty
./.ssh

# なんで./.sshが出てくるのかと思ったら.sshディレクトリの中身が空だった
envader@172-19-2-2:~$ cd .ssh/
envader@172-19-2-2:~/.ssh$ ls
envader@172-19-2-2:~/.ssh$

-ls

ls -lコマンドのようにファイルの詳細を表示する

envader@172-19-2-2:~$ find -name "*.py" -ls
  1178070      4 -rw-r--r--   1 envader  envader        41  324 20:29 ./main4.py
  1178043      4 -rw-r--r--   1 envader  envader        48  324 20:29 ./main.py
  1178061      4 -rw-r--r--   1 envader  envader        48  321 20:29 ./main3.py
  1178052      4 -rw-r--r--   1 envader  envader        49  322 20:29 ./main2.py

まとめ

  • findコマンドを使うことで、カレントディレクトリや指定したディレクトリにどんなファイルがあるのかを検索できる。
  • オプションを指定する事で、更新日や権限などを指定して検索することができる。
  • *?などはメタキャラクタと呼ばれ、特殊な文字である。利用する時は、バックスラッシュか""で囲むようにすることでエラーを回避できる。

最後まで読んでいただきありがとうございました。

参考にさせていただいた記事等

Envader

Linuxのメタキャラクタ~メタキャラクタについて~

LinuCレベル1 教科書

Discussion