unixコマンドの基本的まとめ
<目次>
- 基本編
- ディレクトリ間の移動
- ディレクトリの操作
- ファイルの操作
UNIXコマンド入門 [一般ユーザー編] (全24回) - プログラミングならドットインストールを一通りやり終えたのでメモ + 調べたことまとめ。
基本編
コマンド | 説明 |
---|---|
pwd | 現在のディレクトリを表示(print working directory) |
clear または ctrl + l | 画面クリア |
ディレクトリ間の移動
コマンド | 説明 |
---|---|
cd | ディレクトリの移動cd .. 1つ上の階層に移動cd - 直前のディレクトリに移動cd ホームディレクトリに移動 |
clear または ctrl + l | 画面クリア |
ディレクトリの操作
コマンド | 説明 |
---|---|
mkdir | ディレクトリの作成mkdir -p hoge/fuga hogeディレクトリがなくてもfugaディレクトリが作成できる(parents) |
ls | ファイル、ディレクトリの表示(list)ls -a 隠しファイルも含めて表示ls -l パーミッション権限など詳細を表示 |
cp | コピーcp -r 再帰的(recursive)にコピー |
mv | ファイル、ディレクトリの移動 ※同ディレクトリ内で使うと名前の変更になる 例) mv hoge.txt hoge2.txt |
rmdir | 空ディレクトリの削除 |
rm | ファイルやディレクトリの削除rm -r ディレクトリを削除(再帰的:recursive)rm -rf ディレクトリごと警告なしで削除 |
ファイルの操作
コマンド | 説明 |
---|---|
cat | ファイルの中身をすべて表示(画面に収まらない場合、上部は見切れてスクロールさせる必要あり) |
less | ファイルの中身を画面内に収まる範囲で表示スペースキー orctrl + F 一画面先に移動(forward)、ctrl + B 一画面前(back)に戻るg 先頭に移動G 末尾に移動/検索語 検索語で検索n 次の箇所に移動(next)N 前の箇所に戻るq 終了(quit) |
bashの便利機能
キー操作 | 説明 |
---|---|
tabキー |
補完 |
ctrl + c |
キャンセル、中止 |
↑ or ↓ |
履歴表示 |
ctrl + r |
履歴検索ctrl + r で再検索 |
コマンドの履歴
コマンド | 説明 |
---|---|
history | コマンド履歴表示 |
!履歴番号 | そのコマンドを実行 |
!! | 1つ前のコマンド実行 |
!-n | n個前のコマンド実行 |
!$ | 直前のコマンドに渡した最後の文字列 例) mkdir hoge/fuga cd !$ -> hoge/fugaが!&の引数に渡される |
!検索語 | 検索語から始まる直近のコマンドの実行 |
!検索語:p | 検索語から始まる直近のコマンドの確認 |
コマンドの詳細(ヘルプ)
コマンド | 説明 |
---|---|
〇〇 --help | ヘルプ表示 |
man 〇〇 | コマンド〇〇の詳細を表示(less表示) |
シンボリックリンクの作成
コマンド | 説明 |
---|---|
ln -s {元のディレクトリパス} {シンボリックリンク名} | シンボリックリンク作成 例) ln -s path/to/hoge fuga |
unlink {シンボリックリンク名} | シンボリックリンク削除 例) unlink fuga |
ユーザー、グループの確認
ls -l
で詳細表示
drwxrwxr-x. 3 vagrant vagrant 4096 1月 20 11:50 2018 config lrwxrwxrwx. 1 vagrant vagrant 26 1月 20 12:06 2018 dbconfig -> config/production/database -rw-rw-r--. 1 vagrant vagrant 1342 1月 20 11:07 2018 hello.txt
▼表示内容
- 1文字目がタイプを表す。
d
ディレクトリl
シンボリックリンク-
ファイル- パーミッションに関する情報。
- リンク数
- このファイルを所有しているユーザーとグループ
- ファイルサイズ
- 最終更新日
- ファイル名
ユーザーの確認
cat /etc/passwd
でユーザー一覧表示
(略) vagrant:x:500:500:vagrant:/home/vagrant:/bin/bash (略)
▼表示内容
- ユーザー名
x
パスワードが表示されている意味- ユーザーのID
- メインで所属しているグループのID
- ユーザーに付けられたコメント
- homeディレクトリの位置
- シェルとして使うコマンド
グループの確認
cat /etc/group
でグループ一覧表示
(略) vagrant:x:500:vagrant (略)
▼表示内容
- グループ名
x
パスワードが表示されている意味- グループのID
- グループに所属しているユーザー名
※groups
コマンドでも自分が所属しているグループ名を確認できる。
パーミッションについて
パーミッションの見方
権限 | 説明 |
---|---|
r | (read) 読み込み可 |
w | (write) 書き込み可 |
x | (execute) 実行可 |
※ディレクトリに関しては実行するものではないため、x
が付いていたらそのディレクトリを開くことができるという意味になる。
図の場合、
vagrant
ユーザーは「読み・書き・実行」が可能。
vagrant
グループに属するユーザーは「読み・書き」が可能。
その他ユーザーは「読み」が可能。
パーミッションの変更
chmod {パーミッション変更} {対象ファイル}
で変更
# グループ(g)の実行を許可 chmod g+x sample.txt # 所有ユーザー(u)とその他ユーザー(o)の書き込みを不認可 chmod uo-w sample.txt # すべてのユーザー(a)の読み・書きを許可。実行を不認可 chmod a+rw-x sample.txt
パーミッションを数値で表現
権限 | 2進数 |
---|---|
r | 4 |
w | 2 |
x | 1 |
ステータスは上記2進数の合計値で表す。
# すべてのユーザーに「読み・書き・実行」許可 chmod 777 sample.txt # 所有ユーザー「読み・書き・実行」許可 # グループユーザー「読み・書き」許可 # その他ユーザー「読み」許可 chmod 761 sample.txt # すべてのユーザー「読み・書き」を許可 # グループユーザー「読み・実行」許可 # その他ユーザー 許可なし chmod 650 sample.txt
コマンドの作成
「Hello」と書かれたテキストファイルを現在のディレクトリに出力するコマンドhello
を作る
作成手順
- 既にそのコマンドがないか確認する
type hello bash: type: hello: not found
- コマンドファイルの作成
touch hello
#!/bin/bash echo "Hello" > ./Hello.txt
- そのままでは実行できないので権限を追加
chmod u+x hello
- 実行(ディレクトリを指定する必要あり)
./hello
PATHを通す(環境変数の操作)
上記で作成したhello
コマンドは、./hello
とディレクトリを指定する必要があった。
これはUNIXでは、コマンドを検索するディレクトリが決められており、そのディレクトリ外にあるコマンドを実行する場合は、そのファイルがどこにあるか指定しなければいけないルールがあるため。
その「コマンドを検索するディレクトリ」は環境変数というもののひとつに保存されておりecho $PATH
もしくはprintenv PATH
で確認できる。
echo $PATH /home/vagrant/.pyenv/plugins/pyenv-virtualenv/shims:/home/vagrant/.pyenv/shims:...(略)
ディレクトリは:
で区切られていて、コマンドを実行する際はこれらディレクトリを最初から探索していく。
なお、$PATH以外のすべての環境変数を見るにはprintenv
を実行する。
環境変数に追加
hello
でコマンドを実行させるには、上記を踏まえて、環境変数$PATH
にコマンドのディレクトリを追加すればよい。
# コマンドのディレクトリを確認 pwd /home/vagrant/unix_lessons/myapp # 上記ディレクリをPATHの先頭に追加 # ※ $PATHには追加直前のPATH情報が入っている # ※ 「:」で区切るのを忘れない export PATH=/home/vagrant/unix_lessons/myapp:$PATH # 正しく追加されたか確認する echo $PATH /home/vagrant/unix_lessons/myapp:/home/vagrant/.pyenv/plugins/pyenv-virtualenv/shims:/home/vagrant/.pyenv/shims:...(略)
これでhello
でコマンド実行可能となる。
このように特定のディレクトリをPATH
に追加することを「PATHを通す」と呼ぶ。
どこのディレクトリから呼び出されているか確認する
which
コマンドを使うことで確認可能
which hello ~/unix_lessons/myapp/hello
新たな環境変数の作成、削除
上記では既存のPATH
に追加したが、新規で追加するのもほぼ同じ。
# HOGEという環境変数にfugaを追加する export HOGE=fuga # 保存されたか確認する echo $HOGE fuga
削除をするにはunset
を使う
unset HOGE # 確認すると何も表示されない = 環境変数がない echo $HOGE
設定した環境変数はログアウトすると消える
通常は、ログアウトすると設定した環境変数は消えてしまう。
これをログアウトしても設定されている状態にするには、~.bash_profile
か~.bashrc
に設定する。
結論をいうと ~.bash_profile
に設定が望ましい。
その理由は下記。
~.bash_profile
ログイン時に一度だけ実行される~.bashrc
bashが読み込まれる度に更新される
「bashが読み込まれるタイミング」というのは、
~.bash_profile
が読み込まれるとき = ログイン時(.bashrc
は.bash_profile
から呼び出しているから)bash
コマンドを叩いた時
環境変数の設定はログイン時に行えればいいので、~.bash_profile
に設定が望ましい。
# .bash_profileに設定 [vagrant@localhost ~]$ vi ~./bash_profile # (略)
.bash_profile
の変更の反映には、1.ログインしなおすか、2.source
コマンドを実行する。
1. ログインしなおして反映する場合
# 書き込みを反映させるためにログアウトする(rootユーザーへ) [vagrant@localhost ~]$ su - パスワード: # パスワード入力 # 元のユーザーに戻る(「-」を忘れない) [root@localhost ~]# su - vagrant [vagrant@localhost ~]
2. sourceコマンドで反映する場合
[vagrant@localhost ~]$ source ~/.bash_profile
※自分の環境ではsource
コマンドでの場合、~/.bash_profile
に追記したときは問題ないが、削除した場合は反映がされなかった。(hello
コマンドが実行できてしまう)
.bashrc
と.bash_profile
についての話は下記記事が参考になった。
管理者ユーザーになる
管理者ユーザーでしか操作できない(読み・書き・実行が行えない)ファイルを操作するためには、ユーザーを変更して管理者ユーザーになる必要がある。
例えば、システムのログファイル(/var/log/messages
)を確認したいとする。
# ファイルの詳細を確認 [vagrant@localhost ~]$ ls -l /var/log/messages -rw-------. 1 root root 55861 1月 20 19:58 2018 /var/log/messages
管理者(root)ユーザーにしか読み書きの権限がないため管理者ユーザーに切り替える。
任意のユーザーに切り替えるためにはsu
コマンド(substitute user)を使う。
- ユーザー名を省略すると
root
ユーザーになる -l
オプションをつけるとroot
ユーザーとしてログインし直す。
-l
をつけないと、ユーザーを切り替えるのみで、現在のディレクトリの位置や環境変数をそのまま引き継ぐ- 通常はログインし直した方が良いため
su -l
で良いが、l
は省略できるためsu -
というコマンドが良く使われる
- 通常はログインし直した方が良いため
[vagrant@localhost ~]$ su - パスワード: # ローカル開発環境では「vagrant」がパスワード # ログイン完了 [root@localhost ~]#
この状態であれば/var/log/messages
ファイルを確認できる。
[root@localhost ~]# cat /var/log/messages
管理者ユーザーとして実行する
上記の、管理者ユーザーへ変更してからの操作は、権限が広すぎるためミスすると大変なことになりかねない。
そのため一般的には管理者ユーザーに切り替えるのではなく、sudo
を使ってコマンド単位で管理者ユーザーとして実行する。
# vagrant ユーザーのまま実行できる [vagrant@localhost ~]$ sudo cat /var/log/message
ファイルの所有者を変更する
chown
(change owner)コマンドを使うとファイルの所有者を変更できる。
先ほどのログファイルを手元にコピーして編集する場合を想定。
まず、そのままコピーをしようとすると管理者ユーザーではないためエラーとなる。
[vagrant@localhost ~]$ cp /var/log/messages . cp: `/var/log/messages' を 読み込み用でオープンできません: 許可がありません
sudo
で実行するとうまくいく。
[vagrant@localhost ~]$ sudo cp /var/log/messages .
しかしこれを編集するとなるとまたsudo
で実行しなくてはならず面倒なので、chown
コマンドでこのファイルの所有者をroot
から変更する。
(chown
コマンドもsudo
から実行する必要があるので注意)
# 所有者がrootユーザーとrootグループであると確認 [vagrant@localhost ~]$ ls -l messages -rw-------. 1 root root 55861 1月 20 22:49 2018 messages # ユーザーとグループをそれぞれvagrantに変更 [vagrant@localhost ~]$ sudo chown vagrant:vagrant messages # 正しく変更されているのを確認 [vagrant@localhost ~]$ ls -l messages -rw-------. 1 vagrant vagrant 55861 1月 20 22:49 2018 messages
これで読み書き権限が付いたので編集が可能となった。
テキストを操作する
コマンド | 説明 |
---|---|
wc | (word count) 行数、単語数、バイト数、ファイル名の順に表示 (日本語は英語と異なり、単語の区切りが空白やタブではないため正確な単語数は出てこない) -l --lines 行数を表示-w --words 単語数を表示-m -chars 文字数を表示-c -bytes バイト数を表示 |
head | ファイルの先頭を表示(デフォルトでは先頭10行)-〇 n - 〇 先頭から〇行表示(0だと表示なし)-v ファイルごとにファイル名を出力※ head -vn 3 a.txt b.txt (先頭3行表示されるため簡単な比較をしたいときに便利かも) |
tail | ファイルの末尾を表示(デフォルトでは末尾10行) 他はほぼ head と同じ |
grep | ファイルの中から文字列を検索 ※オプションが豊富で正規表現での検索も可能。詳しくはまた別途。 |
ファイルディスクリプタ、リダイレクション、パイプ
ファイルディスクリプタとは
UNIXでは標準入力、標準出力、標準エラー出力という3つのファイルディスクリプタと呼ばれるものが存在する。
ファイルディスクリプタとは、はっきりとはよくわからないが、下記の記事が分かりやすかった。
ここに書かれているように「ファイルを識別するための目印」というイメージでいる。
リダイレクションとは
基本的に、
- 標準入力はキーボード
- 標準出力はディスプレイ
- 標準エラー出力はディスプレイ
という具合でデバイス(装置)とディスクリプタは紐づいているが、この入出力先を変更することをリダイレクションという。
この説明だと抽象的で微妙なので具体的な例で言うと、処理結果をファイルに出力したり、逆に処理内容をファイルから呼び出したりすることである。
リダイレクションを行うためのコマンドは下記になる。
コマンド | 説明 |
---|---|
a > b |
aの処理結果をbに出力(bがすでにあれば上書き) |
a >> b |
aの処理結果をbの末尾に追記 |
a < b |
aの処理内容をbから入力 |
サンプル
# 'hello'文字列をhello.txtに保存 $ echo 'hello' > hello.txt
# hello.txtの末尾に'world'を追加 $ echo 'world' >> hello.txt # 結果確認 $ cat hello.txt hello world
# 「echo 'hello'」と内容が書かれたhello.txtがあるとする $ bash < hello.txt hello
組み合わせての実行もできる。
# 「echo 'hello'」と内容が書かれたhello.txtがあるとする $ bash < hello.txt > result.txt # 結果確認 $ cat result.txt hello
パイプとは
コマンドの処理結果(出力)を別のコマンドに振り分けることをパイプという。
パイプを行うためのコマンドは下記になる。
コマンド | 説明 |
---|---|
`a | b| aの処理結果をbに渡す<br>※パイプは複数つなげることできる<br> a | b | c | d |...` |
サンプル
# 'hello'文字列の文字数表示 $ echo 'hello' | wc -m 6
上記は非常に簡単な例だが、wc -m
に渡される内容が'hello'
となっていることが分かる。
もう少し実用的なサンプルで確かめてみる。
# /etc直下のディレクトリから'conf'が含まれているリストを作ってその行数を出力 $ ls -l /etc | grep 'conf' | wc -l 34
使いこなせば複雑な処理も1行で記述できるようになりそうである。
ワイルドカード
そもそもワイルドカードとは
もともとカードゲームのワイルドカードに由来するもので、他のカードの代用が可能な特殊なカードのことをいうようである。
コンピューターに関しても同じことがいえて、検索などのgrobの際に使用する特殊文字の種類で、どんな文字列にもマッチするもののことをワイルドカードという。
このような特性を持つワイルドカードを活用するとより便利にコマンド操作が行える。
UNIXコマンドでは下記のワイルドカードが使える。
コマンド | 説明 |
---|---|
* |
0文字以上の任意の文字列 |
? |
1文字のみの任意の文字列 |
サンプル
# logフォルダの中から拡張子が.logのものを表示 $ ls /var/log/*.log /var/log/VBoxGuestAdditions.log /var/log/anaconda.log /var/log/anaconda.storage.log /var/log/boot.log /var/log/mysqld.log /var/log/vboxadd-install.log /var/log/anaconda.ifcfg.log /var/log/anaconda.program.log /var/log/anaconda.yum.log /var/log/dracut.log /var/log/vboxadd-install-x11.log /var/log/yum.log
# logフォルダの中から.(ドット)の前から3文字前が「y」の.logファイルを表示 $ ls /var/log/*y??.log /var/log/anaconda.yum.log /var/log/yum.log
ファイル、ディレクトリの検索
先に紹介したgrep
コマンドはファイルの中身に関して検索をしたが、ファイルやディレクトリの検索にはfind
コマンドを使う。
find
コマンドの基本的な使い方は下記。
$ find {検索開始ディレクトリ} {検索条件}
find
は「検索開始ディレクトリ」に指定されたディレクトリに対して再帰的に検索をかける。
そのため$ find ~ ...
とするとホームディレクトリ配下全ファイル対象に検索する。
検索条件ではいろいろと複雑な条件指定が可能。
ひとまずシンプルな検索条件を見てみる。
例)
-type d
ディレクトリのみを検索
-type f
ファイルのみを検索
-name {filename}
ファイル名で検索
# /var/log/ディレクトリ配下にある.logファイルを出力 # (読み取り権限に引っかかるものがあるので sudo コマンドで実行) $ sudo find /var/log/ -name "*.log" /var/log/yum.log /var/log/anaconda.yum.log /var/log/anaconda.program.log /var/log/boot.log ...
検索したファイルに対して別のコマンドを実行
大きく2つの方法がある。
1. -exec
オプションを使う方法
書き方がぱっと見は少し独特。
# /var/log/ディレクトリ配下にある.logファイルの文字数をそれぞれ表示 $ sudo find /var/log/ -name "*.log" -exec wc -m {} + 20820 /var/log/yum.log 32257 /var/log/anaconda.yum.log 29439 /var/log/anaconda.program.log 2613 /var/log/boot.log ...
要は-exec
コマンドでつないだ後、{}
に、find
で出力されたものが入るということ。そう理解できると難しくはない。
末尾の +
と \;
の違い
下記のコマンドは似ているが実はロジックが少し異なっている。
$ sudo find /var/log/ -name "*.log" -exec wc -m {} + 20820 /var/log/yum.log 32257 /var/log/anaconda.yum.log 29439 /var/log/anaconda.program.log 2613 /var/log/boot.log ... $ sudo find /var/log/ -name "*.log" -exec wc -m {} \; 20820 /var/log/yum.log 32257 /var/log/anaconda.yum.log 29439 /var/log/anaconda.program.log 2613 /var/log/boot.log ...
処理結果を見ると分かるのだが、 +
を使った場合、 {}
に入っているリストに対して、まとめて wc -m
コマンドを実行している。つまり下記と同じ意味。
$ sudo wc -m /var/log/yum.log /var/log/anaconda.yum.log /var/log/anaconda.program.log /var/log/boot.log ...
対して \;
を使った場合は、{}
に入っているリストに対して、1つずつコマンドを実行している。つまり下記と同じ意味。
$ sudo wc -m /var/log/yum.log $ sudo wc -m /var/log/anaconda.yum.log $ sudo wc -m /var/log/anaconda.program.log $ sudo wc -m /var/log/boot.log ...
どちらもほぼ同じ結果だが、+
を使った場合の方が処理コスト的には低くて高速に動作しそうではある。
このあたりの参考としては下記記事が分かりやすかった。
2. xargs
コマンドを使う方法
下記のコマンドは同一の内容である。
# -execを使う $ sudo find /var/log/ -name "*.log" -exec wc -l {} + # xargsを使う(自分の場合、xargsの前にsudoが必要であった) $ sudo find /var/log/ -name "*.log" | sudo xargs wc -l
xargsは、複数の結果をコマンドへ送りだすことができるコマンド。
-exec
とは異なり、find
の結果に限らない。
例えば下記のようにls
を使って「ディレクトリ直下にある.txtファイルそれぞれの先頭一行だけを表示する」ということも可能。
$ ls *.txt | xargs head -1
ブレース展開
ブレースとは{}
のことで、{}
の中にカンマ区切りやドットを2つ続けて文字列や数値を記述すると、コマンド実行時に展開される。
$ echo {1,2,3} 1 2 3 $ echo {1..10} 1 2 3 4 5 6 7 8 9 10
{}
の前に文字列や数値、{}
を続けて書くと、数学の展開のように展開が可能。
# a(1+2+3) のような展開 $ echo a{1..3} a1 a2 a3 # (a+b+c)(1+2)(x+y+z) のような展開 $ echo {a,b,c}{1,2}{x,y,z} a1x a1y a1z a2x a2y a2z b1x b1y b1z b2x b2y b2z c1x c1y c1z c2x c2y c2z
この特性を生かすと様々な操作が効率的に行える。
# ディレクトリを一気に作成 $ mkdir test{1..5} # 作成したディレクトリにファイルを挿入 $ touch !$/file{1..3}{.txt,.png} # 確認 $ ls test{1..5} test1: file1.png file1.txt file2.png file2.txt file3.png file3.txt test2: file1.png file1.txt file2.png file2.txt file3.png file3.txt ... # すべてのファイルから.pngだけ削除する $ rm test{1..5}/*.png # 確認 $ ls test{1..5} test1: file1.txt file2.txt file3.txt test2: file1.txt file2.txt file3.txt ...
他にも多数あり、下記が詳しくまとまっている。