WordPress→php→Linuxに到達しました。
調べれば調べるほど奥が深く、面白いLinux。
今でこそ何ができて何ができないのか、どう考えればいいのかが少しずつ分かってきましたが、最初はわからないことだらけで思い通りに動かないLinuxが大嫌いでした。
サッとみて、「ふぅん、こんなことができるんだ」というページになれば幸いです。
はじめに
自分がLinuxについて学んでいったことを、時系列に沿って記録しています。
上のほうが初期に学んだこと、下に行くほど最近学んだことです。
それぞれ断片的、必要最低限のことしか記載されていません。
細かいことはリンク先を見るなり検索してください。
$
のドルマークはコマンド入力が待機中であることを示しています。
Linuxを学ぶ上での心構え
Linuxが出力する英語はパターンが少ないから読む
Linuxは出力が英語のことが多く、英語であることが学習コストを上げている部分があります。
大事なのは「Linuxが出力する英語は大したパターンがない」ことです。
1回、辞書を引きながら読めば後々応用できることが非常に多いので、ちゃんと読みましょう。
エラーメッセージが出たらコピーして検索
自分がみているエラーメッセージは、世の中の誰もが一度は検索しています。
75%くらいの確率でズバリの答えが見つかることが多い(当人調べ)ので、まずは検索してみましょう。
サーバをぶっ壊すくらいの気持ちで触りまくる
「これやったら動かなくなって大惨事になるんじゃないか…」が一番のハードルだと思います。
今はいい時代で、AWSなんかでは本番環境とほぼ同じものを簡単にコピーして使えます。
もし自分で作れなければ、一番最初だけ先輩に作ってもらって、作り方を教えてもらってメモして自分で作れるようになりましょう。
そのうえでコピーしたものを、ぶっ壊すくらいの気持ちでとにかく触りまくると、何をすると壊れるのか、何をしても壊れないのかがだんだんわかってきます。
しかもLinuxは意外と壊れません。
わからないコマンドや文字列はとにかく検索
コマンドの内容を全部わかる必要はありません。
でも、「ああ、このコマンドは大体こういうことやってるんだな」ということは検索しないとわかりません。
Linux完全に理解した
僕は完全に理解してません。
完全に理解するためにこれだけは理解しとけ、ってやつ。
パイプ(パイプライン) | を完全に理解すべし
ほぼ何でも組み合わせられる?驚くべきLinuxの超便利機能。
パイプを理解し、使いこなすことがLinuxの真髄の一つ。
https://eng-entrance.com/linux-pipeline
実行結果$?を完全に理解すべし
とっかかりはこちらで。
コマンド成功時には「0」
失敗時には「1」(コマンドやエラーの種類によっては 0 以外)
https://shellscript.sunone.me/exit_status.html
これを読むと具体例がわかる
mkdir hoge && cd $_
は、コマンドラインで直接入力した場合、
mkdir hoge && cd hoge
と同義となります。
https://teratail.com/questions/1033
これを読むと完全に理解できる。
変数 内容 MS-DOS相当
$? 直前に実行されたコマンド(や関数)の戻り値(→PIPESTATUS) %ERRORLEVEL%
$0 実行コマンド名 %0
$1 $2 … 実行時引数(個別) %1 %2 …
$* 全引数 %*
$@ 全引数(それぞれの引数がダブルクォーテーションで囲まれる)
$# 引数の個数
$$ 当シェルのプロセスID
$! 最後に呼び出されたバックグラウンドコマンドのプロセスID [2006-08-26]
$- シェルのオプション(フラグ)の内容。[2008-11-29]
$_ シェルスクリプト内で使った場合、起動されたシェルのファイル名。$0と同じ。[2008-11-29] それ以外の場合、直前に実行したコマンドの最後の引数。(引数が無かった場合はコマンド名) > $PIPESTATUS パイプの各コマンドの戻り値が入った配列。[2012-03-04]
$LINENO 現在の行番号。[2012-03-04]
$IFS 区切り文字。(→使用例)[2014-05-01]
http://www.ne.jp/asahi/hishidama/home/tech/unix/sh.html#$()
-を完全に理解すべし
こういうやつ
$ wget -O- http://www.example.com/example.gpg.key | \ sudo apt-key add -
上は以下と同じ(パイプ|の後のバックスラッシュ\は改行のエスケープ)
$ wget -O tmpfile http://www.example.com/example.gpg.key $ sudo apt-key add tmpfile $ rm tmpfile
参考: Linuxにおけるハイフンの意味 https://www.nemotos.net/?p=996
あとこれね。補足。
コマンドでファイル名を渡す際にハイフンを指定すると基本的には標準入力(標準出力)として解釈してくれます。
$ cat - hoge (←入力) hoge nullpo (←入力) nullpo
参考: ハイフンを使った便利な標準入出力指定でのコマンドライン
https://qiita.com/bami3/items/d67152d19aa8ac2d47de
リダイレクト> >> < <<と割り振り番号0 1 2を完全に理解すべし
リダイレクトはGUIに慣れ親しんだ人にとっては、いまいち直感的にわかりにくく、しかもどう活用すべきかよくわからない機能の一つでは。
でもこれを完全に理解すると、自由度が非常に上がる。
概念が直感的に理解しにくいので特にリダイレクトは挫折しかけますが完全に理解しましょう。
完全に理解すべし…(自分に言い聞かせてる)。
# リダイレクトの使い方 $ echo Close_World > Test_Hello_World.txt # 上書き $ echo Close_World >> Test_Hello_World.txt # 追記 $ grep "test" < testfile.txt # testfile.txtの中身をtestで検索 $ cat << "EOF" > testfile.txt # 終端文字列を指定して標準入力を流しこむ。この場合はEOFまで入力を受け付ける
Linuxデフォルトの割り振り番号
標準入力には0
標準出力には1
標準エラー出力には2
https://eng-entrance.com/linux-redirect
リダイレクトの前にディスクリプタ番号(割り振り番号)を指定すると指定したディスクリプタをリダイレクトできる。
「&」を追加すると出力先を同一にできる。わかりにくいが「2>&1」という表現をすると「2の出力を1と同一にする」ということになる。 https://eng-entrance.com/linux-redirect
コマンド > ファイル コマンド結果をファイルへ書き込む
コマンド < ファイル ファイルの中身をコマンドの標準入力へ
コマンド >> ファイル コマンドの出力結果をファイルへ追記
コマンド 2> ファイル エラー出力をファイルへ書き込む
コマンド 2>> ファイル ファイルにエラー出力を追記
コマンド > ファイル 2>&1 ファイルに標準出力と標準エラー出力を書き込む
コマンド >> ファイル 2>&1 ファイルに標準出力と標準エラー出力を追記
コマンド << 終了文字 終了文字が現れるまで標準入力へ送る
コマンド &> ファイル 標準出力と標準エラー出力を同じファイルに書き込む
コマンド > /dev/null 2>&1 表示をしない。(表示をゴミ箱へ)
https://eng-entrance.com/linux-redirect
/dev/stdin /dev/stdout /dev/stderr を完全に理解すべし
/dev/std{in,out,err}は標準入力、標準出力、標準エラーを表す
https://qiita.com/richmikan@github/items/a3803d816c196ecebff5
/dev/nullを完全に理解すべし
出力が出たものを受け取らなかった時に出るエラーをブラックホール(/dev/null)に投げることで、エラーが出ないように先回りする
UNIXやUnix系OSのソフトウェアは、動作時に標準出力や標準エラー出力に動作状況や、エラーや警告を伝えるメッセージを出力することがある。これらはデフォルトで画面に表示され、cronデーモンで自動的に実行された場合は出力されたメッセージ文がメールでユーザに送られたりする。シェルスクリプトなどにおいてもこれらのメッセージ出力が邪魔になることがある。ソフトウェアによっては、コマンドラインオプション等でこれらのメッセージを出力しないようにできるものもあるが、できないものもある。 >
そのような場合に、ソフトウェアが標準出力や標準エラー出力に出力するメッセージを /dev/null にリダイレクトするようにあらかじめ指定しておくと、これを回避できる。
参考: Wikipedia/dev/null https://ja.wikipedia.org/wiki//dev/null
ifを完全に理解すべし
phpやjavascriptなどと書き方が違うので学習コストが高いけど、ifが使えないとシェルスクリプトは書けませんし、理解できません。
完全に理解するならこっち。
https://shellscript.sunone.me/if_and_test.html
簡単に理解するならこっち。
https://www.sejuku.net/blog/53707
test []を完全に理解すべし
オプションが超たくさんあるので、一気に覚えなくていいけど、逐一参照して覚えていくべし。
https://tech.nikkeibp.co.jp/it/article/COLUMN/20060227/230901/
バッククォート $()を完全に理解すべし
標準出力のみを変数に設定する
VAR=command
画面に表示されるコマンドの実行結果 (標準出力に出力される文字列) を全て変数に設定する。
https://shellscript.sunone.me/variable.html
理解しにくいLinuxの挙動
daemonというバックグラウンド・プロセスがいるから反応してくれる
普段MacやWindowsなどのGUI系OSを使ってると意識することがないけれど、Linuxで超重要なのが「daemon」。 demon(悪魔・デーモン)ではなくdaemon(守護神・ダイモン)。
daemonが常に見張っていてくれるので、別のサーバからリクエストがあったときに対応してくれる。
daemonの管理はserviceコマンドやchkconfigコマンドで行う。
https://qiita.com/manjiroukeigo/items/2b217ffbb50b119d5f58
hostはipやドメインのこと
「この人を探して」を特定するための情報がhostname。
ipでもドメインでも、どちらでも示される。
ipは住所(東京都新宿区歌舞伎町1-4-1)、
ドメインは表札や物件名(新宿区役所)と考えると覚えやすい。
ドメインはipを人間に読みやすいように書き換えたもの。
一つのファイルにたくさん書き込みがあっても遅延は起きにくい
logの記述などでファイルにたくさん書き込みがあっても、あまり遅延は起こらない。
1GB(ギガバイト)とかの書き込みになってくると別だけど。
一つのserviceに対して複数のプロセスは作れない
例えばすでにswatch(ログ監視)がdaemon(待機プロセス)で実行中だったら、新たにswatch~~とやっても実行できない。
一つのプロセスの中で、複数の監視などを行うようにする必要がある。
inodeの管理
「容量は残ってるけどinodeが枯渇して新しいプロセスを動かせない」が起こる。
https://wa3.i-3-i.info/word14803.html
inodeはlogrotateも関連が深い
daemonなどserviceの管理
https://qiita.com/manjiroukeigo/items/2b217ffbb50b119d5f58
サブシェル(command ; command)
$ (cd src ; make)
複数のプロセスを並行して実行できる。
また、カレントディレクトリを変更しない。
http://x68000.q-e-d.net/~68user/unix/pickup?%A5%B5%A5%D6%A5%B7%A5%A7%A5%EB
root配下のフォルダ名(binやetcなど)
homeとかvarとかtmpとかetcとか、いつどこに何を置くべきなのかよくわからないのですが、適当に置いてはいけないそうです。
各ディレクトリの役割を知ろう(ルートディレクトリ編)
/ ルートディレクトリ ├ /bin 基本コマンド ├ /boot 起動に必要なファイル ├ /dev デバイスファイル ├ /etc 設定ファイル ├ /home(オプション) ユーザーのホームディレクトリ ├ /lib 共有ライブラリ ├ /lib(オプション) ├ /mnt 一時的なマウントポイント ├ /opt 追加アプリケーション ├ /proc(Linux固有) プロセス情報など ├ /root(オプション) root用ホームディレクトリ ├ /sbin システム管理用コマンドなど ├ /tmp 一時的なファイル ├ /usr 各種プログラムなど └ /var 変更されるデータ
https://www.atmarkit.co.jp/ait/articles/0108/07/news002.html
各ディレクトリの役割を知ろう(サブディレクトリ編)
https://www.atmarkit.co.jp/ait/articles/0109/07/news002.html
tmp テンポラリーファイル。一時的なファイル置き場
https://qiita.com/ryoya-s/items/8084d0f7de0e907eadc7
GNU版とBSD版で改行の挙動が変わる
GNUは最後に改行が入らない。
BSDは最後に自動で改行が入る。
sed OS
GNU版 Windows(GitBash for Windows)
BSD版 Mac
https://qiita.com/ponsuke0531/items/a264a7be2beb189cfccb
コマンド
cd 現在のディレクトリを変更する
change directoryの略
頭につける文字によって参照元が変わります。
/(スラッシュ) ルートディレクトリから。
#現在のディレクトリにかかわらず移動できる。いわゆる絶対パス。 $ cd /home/username
~(チルダ) ホームディレクトリから。ユーザーごとに指定されてることがある。
# homeディレクトリが/home/usernameの場合 $ cd ~/hogehoge/ #/home/username/hogehogeになる
(何もなし) 現在のディレクトリから。
#現在のディレクトリからさがす。いわゆる相対パス #/home/usernameにいる場合 $ cd hogehoge #/home/username/hogehogeになる
ls 現在のディレクトリの中身を表示する
listの略
$ ls
vi ファイルの内容を閲覧・編集する
テキストファイルとして編集できる。
$ vi filename
viを入力した直後は「閲覧モード」になっている。
「閲覧モードで」iを押すと、「編集モード」になりカーソルがあっているところから編集できるようになる。
「編集モード」でESCキーを押すと「閲覧モード」に戻る。
「閲覧モード」で:(コロン)を押すとファイル操作を行うモードになる。
:q(終了)
:w(保存)
:wq(保存して終了)
:q!(保存せずに終了)
viで貼り付けるとインデントがめちゃくちゃになる!を回避
:a!(インデントを守ってペーストできるモードに入る。viでも使える)
https://qiita.com/quwa/items/019250dbca167985fe32
viでファイルの中身を全部コピー
:%y
https://qiita.com/kiduki/items/dc03f17fc47c28a73dfb
cat ファイルの中身を表示する
viでファイルの中身を編集するけど、中身を確認したいだけならcatのほうが使い勝手がいい。
編集する危険性もないし、ファイル内容をコピーしたりできる
$ cat filename
xclip ファイルの中身をクリップボードにコピー
$ xclip test.txt
https://qiita.com/watertight/items/2d6c579c1777076f70f4
ssh ほかのサーバにセキュアに(安全に)接続する
$ ssh -i "鍵のパス" username@hostname
crontab 定期的に実行する
時間を指定して自動定期チェックや定期削除ができる
ps 現在動いてるプロセスを確認できる
daemonがちゃんと動いてるかを確認するときに使ったりする。
$ ps aux
このままだと多すぎるので、grep(絞り込み)と合わせて使う
$ ps aux | grep httpd
https://webkaru.net/linux/ps-command/
logrotate
https://qiita.com/Esfahan/items/a8058f1eb593170855a1
swatch logファイルなどを監視してメールやプログラムを実行
daemonに監視させる。
AWSのEC2で行う場合はサーバー直でメールを送ろうとするとスパム防止フィルターに引っ掛かるので対応が必要。
slack通知などを使うのもアリ。
grep
https://www.atmarkit.co.jp/ait/articles/1604/07/news018.html
shellスクリプト
!bin/bashなど1行目に書くおまじないについて
https://qiita.com/yn-misaki/items/6fcfab082dd664f10d4e
シェルスクリプトを書くときはset -euしておく
https://qiita.com/youcune/items/fcfb4ad3d7c1edf9dc96