- 投稿日:2019-11-26T23:36:53+09:00
shell やlinuxでファイル名の特殊文字をエスケープしたい!
タイトルそのままlinuxコマンドで
問題
wc -l /var/tmp/20191126-(2,135,397個)テストファイル.csvのように「20191126-(2,135,397個)ファイル.csv」ファイルの行数を取得しようとしたらエラー
-bash: syntax error near unexpected token `('シンタックスエラーだと。。。
解決策
どうやら「(」が特殊文字でエスケープする必要があるとのこと
ファイル名をシングルクォートで囲めばOK!
wc -l '/var/tmp/20191126-(2,135,397個)テストファイル.csv'PHPであれば、、
$filePath = '/var/tmp/20191126-(2,135,397個)テストファイル.csv' $totalRows = exec("wc -l '${filePath}'");これで正常にできるはず
かんたん
- 投稿日:2019-11-26T23:17:42+09:00
Linuxコマンドのパイプ
コマンド1 | コマンド2という風に
Linuxコマンドの基本であるパイプ。
コマンド1 | コマンド2 という風に書いて、
複数コマンドを組み合わせて使えます。コマンド1によってターミナルに表示される文字に対して、
コマンド2を実行します。具体例
ls | wc -l
ls | wc -l
lsコマンドは存在するファイルを表示するコマンド。
wcコマンドは行数、文字数を表示するコマンド、
-lは行のみを表示するオプション。lsコマンドでファイルを全て表示して、
wc -lコマンドで行数を表示する。
このように組み合わせて、ファイル数を数えるといった使い方が出来ます。grep 文字列 ファイル名 | 文字列 ファイル名
grep 文字列 ファイル名 | 文字列 ファイル名
grep c 101.cpp | grep d 101.cpp
grepコマンドは文字列を、入力したファイル名のファイルから見つけて、
該当する行を表示してくれます。
この例ではgrepを2回使っています。なので、先に入力したgrepコマンドで101.cppからcを含む行を表示。
表示された文字に対して後から入力したgrepコマンドで101.cppからdを含む行を表示。
結果的に101.cppからcとdを含んだ行を抽出して表示してくれます。コマンドは3つ以上でも使える
先に書いたように、表示された内容に対してコマンドを実行するだけ。
なのでコマンド1 | コマンド2 | コマンド3 | コマンド4 | コマンド5...
という風に大量のコマンドを繋げることも可能。
例にあげたコマンド以外でももちろん利用できます。標準であるコマンドとパイプを使えば
ターミナル操作で殆どのことができるので、
使ったことがなければ是非活用してください。
- 投稿日:2019-11-26T23:05:29+09:00
Linux プロセス
今回はlinuxのプロセス
つまり稼動経緯について書きます。プロセス
WEBサーバやコマンドなどLinux上で実行されている処理
プロセスはプロセス名とプロセスIDという番号が自動的に付与されてます。プロセスの性質として
- プロセス毎に自分だけのメモリを割り当てられる
- WEBサーバなどネットワーク機能を利用するプロセスはポートを専有する
1つのCPUが一度に実行できるプロセスは1つだけなので
基本格プロセスが順番に使っている形です。psコマンド (プロセスを確認)
ターミナル$ ps 確認例 PID TTY TIME CMD 1139 ttys000 0:00.03 -bashpsコマンドのオプション
オプション名 意味 -a 自分以外のユーザーのプロセスも表示する。 -r 実行中のプロセスのみを表示する。 -u ユーザー名とプロセスが実行された時刻を表示する。 -aux 実行中のすべてのプロセスに関してCPU使用率などの詳細な情報つきで表示する。 | (パイプ)処理 (複数のコマンドを組み合わせ)
パイプ処理とは、あるコマンドの結果を次のコマンドに渡す処理のことです。パイプ処理を用いたコマンドの組み合わせは以下の様になります。
ターミナル$ <最初に実行されるコマンド> | <右の結果を受けて最終的な結果を返すコマンド> 例 $ cd ~ #ホームディレクトリに移動 $ ls | grep p #ホームディレクトリ以下のファイル群から 'p'という文字が含まれるものだけを表示 $ ps aux | grep mysql | grep -v grep #mysqlサーバーの実行プロセスを探しだして表示grepコマンド
grepコマンドは特定の文字列が含まれる一行を抽出するためのコマンドです。
ターミナルgrep [検索ファイル] [検索パターン]kill <...> (プロセスを終了)
プロセスIDに対して特定のコマンドを実行することで、プロセスを再起動したり、強制終了したりできます。
ターミナル$ kill [プロセスID] # プロセスを終了させる $ kill -9 [プロセスID] # プロセスを強制終了させる強制終了の場合、オプションで-9をつけます。
通常のkillコマンドで削除できない場合はこちらを使用。
- 投稿日:2019-11-26T20:33:23+09:00
linuxでリンクを貼ろう!
ネストの深いディレクトリにアクセスしやすくなる。シンボリックリンクは最強最高!
最強最高lnコマンド!!!
Macだったらエイリアス、Windowsだったらショートカット。便利なこいつらをLinuxではリンクを貼るといい、
ln
コマンドで再現できます。
こんな感じ~$ ls Desktop Documents ~$ touch Documents/test/test2/test3/hoge.txt ~$ ln Documents/test/test2/test3/ -s test3 ~$ cd test3 ~/test3$ ls hoge.txt無駄に深層にあるディレクトリの
test3
に簡単にアクセスできているのがわかります。lnコマンドでリンクをはろう
lnコマンドで貼れるリンクには以下の2種類があります。
- ハードリンク
- シンボリックリンク
ハードリンク
エイリアスやショートカットと違い、一つのファイルに複数の名前を付けるようなイメージで扱われるのがハードリンクで,
オプション無しのlnコマンドで生成できます。~$ ln file1 file2file1とfile2は、名前違いで同じデータを参照しており、どちらもオリジナルデータです。最後の1つのハードリンクが消えて初めて参照しているデータが削除されます。
ちなみにディレクトリのハードリンクは作れない。
シンボリックリンク
こいつは例でも見せた見慣れた挙動を見せます。
-s
オプションをつけたlnコマンドで生成できます。~$ ln -s file1 file2これでfile1のシンボリックリンクとしてfile2が作られました。シンボリックリンクは、lsコマンドを用いると水色にハイライトされます。
ハードリンクと違いfile2にはfile1のアドレスが保存されているだけだので、file1が別のディレクトリに移動したり削除されたりすると使えなくなります。(リンクが壊れる)
シンボリックリンクはディレクトリでも作れてとても便利なので、ハードリンクよりよく使われるぞ
あとがき
lsコマンドのハイライト機能は正確には
ls --color=auto
の機能なのでaliasに設定されていなければハイライト入らなかったりする。
いっちばん最初の例とか絶対見にくいってわかってるんだけどどうもこれ以上にいい例が浮かばなかった...
- 投稿日:2019-11-26T19:56:36+09:00
Linuxカーネル内のリスト型データ構造とその操作
list in linux kernel
カーネルに於けるリスト型データ構造
LinuxカーネルはCで書かれており、C言語には標準でリストが無い。
どうやってリストを作るかは実装した本人次第だ。
Linuxカーネルのような大規模なコードでは、リストの標準化を行っている。
その実装はCの特異な言語仕様を駆使したものであり、Cをある程度理解していないとかなり難しい。
実装
リストにしたいデータ構造(構造体)に特殊なデータ構造をメンバとして持たせる事で、リストを実装している。
struct student_entry { char *name; int num; struct list_head head; };以降、このデータ構造をサンプルとする。
list_head
list_head
自体は至極シンプルなデータ構造で、前後の要素のポインタを持つだけだ。struct list_head { struct list_head *next, *prev; };つまり、リストとして繋がっているのはあくまで
list_head
同士である。それをメンバとして持つ構造体をリストとして操作する為に使うのが、非常に複雑な仕組みだ。
リスト操作
初期化
リストの初期化はマクロ
LIST_HEAD(name)
で行う。
name
はリストにしたいデータ構造の名前を指定する。#define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name)サンプル
LIST_HEAD(student_list); struct student_entry { char *name; int num; struct list_head head; };これで
student_entry
というリストの要素の型とstudent_list
という名前のリストを定義する。追加
list_add
カーネルでの定義は少し複雑なので、動きは変えずに少しシンプルに書く
void list_add(struct list_head *new, struct list_head *head) { struct list_head *next = head->next; next->prev = new; new->next = next; new->prev = head; head->next = new; }サンプル
struct student_entry *e = malloc(sizeof(student_entry)); list_add(&e->head, &student_list);
list_add_tail
また少し簡略化
感の良い方は何かに気づくと思うが詳細は後で
void list_add_tail(struct list_head *new, struct list_head *head) { struct list_head *prev = head->prev; head->prev = new; new->next = head; new->prev = prev; prev->next = new; }削除
list_del
リストの前の要素のnext
を次の要素に、リストの次の要素の
prev
を前の要素にする事でリストから削除する。void list_del(struct list_head *entry) { struct list_head *next = entry->next, *prev = entry->prev; next->prev = prev; prev->next = next; next = LIST_POISON1; prev = LIST_POISON2; }また、削除する要素の
next
、prev
にはNULL
ではない値を入れる。走査
リストに対する走査も複数あり、マクロで定義されたfor文が多い。
ここでは、リストの各要素に対して操作を行う
list_for_each_entry
を例に解説する。#define list_for_each_entry(pos, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member); \ &pos->member != (head); \ pos = list_next_entry(pos, member))
posに指定したリストの先頭要素を代入し、リスト末尾まで走査するfor文。
サンプル
LIST_HEAD(student_list); struct student_entry { char *name; int num; struct list_head head; }; struct student_entry *e = malloc(sizeof(student_entry)); e->name = "hoge"; e->num = 1; list_add(&e->head, &student_list); struct student_entry *itr; list_for_each_entry(itr, &student_list, head) { printf("%s %d\n", itr->name, itr->num); }マクロ
上で解説した事がわかれば、使用する上では充分だろう。
しかし完全に理解できていない。
それぞれ簡略化して説明した部分を改めて掘り下げる。
本当の
list_add
実際のカーネル内での
list_add
の定義はstatic inline void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); }
__list_add
を呼び出している。また、
list_add_tail
もstatic inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); }引数が違うだけで、同じように
__list_add
を呼び出している。では
__list_add
はどうなっているのかstatic inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { if (!__list_add_valid(new, prev, next)) return; next->prev = new; new->next = next; new->prev = prev; WRITE_ONCE(prev->next, new); }まず最初の
__list_add_valid
だが、CONFIG_DEBUG_LIST
が定義されていない場合はただtrue
を返す。#ifdef CONFIG_DEBUG_LIST extern bool __list_add_valid(struct list_head *new, struct list_head *prev, struct list_head *next); #else static inline bool __list_add_valid(struct list_head *new, struct list_head *prev, struct list_head *next) { return true; }
CONFIG_DEBUG_LIST
が定義されていた場合はlist_debug.c
で定義されているbool __list_add_valid(struct list_head *new, struct list_head *prev, struct list_head *next) { if (CHECK_DATA_CORRUPTION(next->prev != prev, "list_add corruption. next->prev should be prev (%px), but was %px. (next=%px).\n", prev, next->prev, next) || CHECK_DATA_CORRUPTION(prev->next != next, "list_add corruption. prev->next should be next (%px), but was %px. (prev=%px).\n", next, prev->next, prev) || CHECK_DATA_CORRUPTION(new == prev || new == next, "list_add double add: new=%px, prev=%px, next=%px.\n", new, prev, next)) return false; return true; }~めんどくさい~
next->prev != prev
prev->next != next
new == prev
のいずれかがtrue
だった場合、(場合によっては警告を出し、)false
を返す。次に、
next->prev
をnew
にするなどしているがnext->prev = new; new->next = next; new->prev = prev; WRITE_ONCE(prev->next, new);
WRITE_ONCE
とはstatic __always_inline void __write_once_size(volatile void *p, void *res, int size) { switch (size) { case 1: *(volatile __u8 *)p = *(__u8 *)res; break; case 2: *(volatile __u16 *)p = *(__u16 *)res; break; case 4: *(volatile __u32 *)p = *(__u32 *)res; break; case 8: *(volatile __u64 *)p = *(__u64 *)res; break; default: barrier(); __builtin_memcpy((void *)p, (const void *)res, size); barrier(); } } #define WRITE_ONCE(x, val) \ ({ \ union { typeof(x) __val; char __c[1]; } __u = \ { .__val = (__force typeof(x)) (val) }; \ __write_once_size(&(x), __u.__c, sizeof(x)); \ __u.__val; \ })簡潔に言うと、gccによって余計な最適化が行われる事を防ぎながら代入を行っている。
即ち、
prev->next = new
と読み替えても本質的な意味は変わらない。本当の
list_for_each_entry
サンプルでは
list_for_each_entry(itr, &student_list, head) {
定義は変わらない。
#define list_for_each_entry(pos, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member); \ &pos->member != (head); \ pos = list_next_entry(pos, member))
しかし、この中の
list_first_entry
、list_next_entry
はどうなっているのか。#define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member)
で、またラッパー
#define list_entry(ptr, type, member) \ container_of(ptr, type, member)
またラッパー。
そしてこの
container_of
は超重要頻出マクロで、受験生なら覚えるべき。
kernel.h
で定義されている。#define container_of(ptr, type, member) ({ \ void *__mptr = (void *)(ptr); \ BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ !__same_type(*(ptr), void), \ "pointer type mismatch in container_of()"); \ ((type *)(__mptr - offsetof(type, member))); })
早速またマクロ
まず
BUILD_BUG_ON_MSG
名前の通り、第一引数が
true
ならビルド時にエラーメッセージを出力する。第一引数は
!__same_type(*(ptr), ((type *)0)->member) && !__same_type(*(ptr), void)
__same_type
は名前通り引数の方が一致しているか返すマクロつまりこの行は
*ptr
と((type*)0)->member
の型が異なり、かつ*ptr
がvoid
型で無い時にビルドエラーを発生させる次の行が本質的で
((type *)(__mptr - offsetof(type, member))); })
__mptr
はvoid*
にキャストしたptr
また別のマクロがある
offsetof
も名前通り、member
を持つtype
での、member
のオフセットを求める。#define offsetof(type, member) ((size_t) &((type*)0)->member)
よって展開すると、
container_of
は((type*)((void*)ptr - ((size_t) &((type*)0)->member)));何をしているか簡潔に言うと
ptr
をmember
というメンバ名で持つtype
型のポインタを求めているコレが理解出来れば良いだろう。
本題に戻る。
list_for_each_entry
の理解の為、マクロを少しずつ展開してみるとlist_for_each_entry(itr, &student_list, head) {が
for (itr = list_first_entry(&student_list, typeof(*itr), head); &itr->head != student_list; itr = list_next_entry(itr, head))となり、さらに
for (itr = container_of((&student_list)->next, typeof(*itr), head); &itr->head != student_list; itr = container_of(itr->head.next, typeof(*itr), head))となる
つまり、サンプルコードのマクロを少し展開すると
struct list_head student_list { &student_list, &student_list}; struct student_entry { char *name; int num; struct list_head head; }; struct student_entry *e = malloc(sizeof(student_entry)); e->name = "hoge"; e->num = 1; list_add(&e->head, &student_list); struct student_entry *itr; for(itr = container_of((&student_list)->next, struct student_entry, head); &itr->head != student_list; itr = container_of(itr->head.next, struct student_entry, head)) { printf("%s %d\n", itr->name, itr->num); }
struct student_entry *
型のitr
に、リストの先頭要素を代入。head
のアドレスがstudent_entry
になる(つまりリスト終端)までitr
をitr->head.next
を持つリストの要素(リストの次の要素)で更新sample code
#include <stdio.h> #include <stdlib.h> struct list_head list_head; struct list_head { struct list_head *next, *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) #define offsetof(type, member) ((size_t) &((type *)0)->member) #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type, member) );}) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #define list_next_entry(pos, member) \ list_entry((pos)->member.next, typeof(*(pos)), member) #define list_for_each_entry(pos, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member); \ &pos->member != (head); \ pos = list_next_entry(pos, member)) void list_add(struct list_head *new, struct list_head *head) { struct list_head *next = head->next; next->prev = new; new->next = next; new->prev = head; head->next = new; } LIST_HEAD(student_list); struct student_entry { char *name; int num; struct list_head head; }; int main() { struct student_entry *a = malloc(sizeof(struct student_entry)); a->name = "hoge"; a->num = 1; struct student_entry *b = malloc(sizeof(struct student_entry)); b->name = "fuga"; b->num = 2; struct student_entry *itr; list_add(&b->head, &student_list); list_add(&a->head, &student_list); list_for_each_entry(itr, &student_list, head) { printf("%s %d\n", itr->name, itr->num); } }
- 投稿日:2019-11-26T18:58:47+09:00
LinuxでHDDの温度を計る
はじめに
ubuntuでcpuの温度を取得する方法を調べていたらhddの温度も
取得できるらしいことを知った環境は Ubuntu18.0.4だがCentOS系や他ディストリも基本的にやり方は同じ
hddtempを使う
$ apt install hddtemp (省略) $ hddtemp /dev/sda /dev/sda: HGST HTS545025A7E380: 35°Chddtemp の引数でドライブを指定。*ドライブを指定しないと使えない
/dev/以下は環境により読み替えが必要。inxiを使う
$ apt install inxi (省略) $ inxi -xD Drives: HDD Total Size: 250.1GB (16.8% used) ID-1: /dev/sda model: HGST_HTS545025A7 size: 250.1GB temp: 35Cpsensorを使う(GUI)
これはCPUの温度計測でつかったものと同じやつ
$ apt install psensor (省略) $ psensor参考にしたサイト
https://linuxconfig.org/obtain-hard-drive-temperature-information-using-linux
https://www.2daygeek.com/view-check-cpu-hard-disk-temperature-linux/
- 投稿日:2019-11-26T18:19:58+09:00
【最速メモシリーズ】Vagrantで仮想環境をサクッと作る!
前置き
とりあえず早く仮想環境を準備したい!という方に。細かい説明は入れてません。
解説は後々に記載したいと思います。前提条件
- ホストはWindows10(未検証ですがおそらくMacもできます)
- Vagrant 2.2.6
- VirtualBox 6.0.14
- 仮想環境のOSはCentOS7を導入するとします
- ターミナルはGitBash使いました(Windowsの方はコマンドプロンプトやPowershellでも大丈夫です、macはターミナルで)
方法
下準備
1.pluginを更新
vagrant plugin update2.hostsupdaterを入れる
vagrant plugin install vagrant-hostsupdater3.適当にディレクトリを準備してVagrantfileを生成
vagrant init --minimal centos/74.Vagrantfileを下記に修正
Vagrant.configure("2") do |config| config.vm.box = "centos/7" config.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--ostype", "RedHat_64"] end end5.vagrantを立ち上げる
vagrant up6.sshでゲストOSへ
vagrant sshこれでひとまずは仮想環境の準備はできる(汗)
- 投稿日:2019-11-26T17:50:34+09:00
オフラインでパッケージをインストールする
オフラインでインストールするには?
yumコマンドの利用
Linuxにてインストールする際、利用するコマンドはyumです。
yumと聞くとオンラインでのインストールをイメージするかもしれませんが、オフラインでもインストール出来ます。# mount -t iso9660 /dev/cdrom /media[定型文] # yum --disablerepo=* --enablerepo=local_dvd install <インストールしたいもの>引用
CentOSオフライン環境でパッケージグループのyumインストール
https://densan-hoshigumi.com/server/centos-offlineinstall-package#DVDyum
- 投稿日:2019-11-26T12:43:12+09:00
isoをマウントする
isoをマウントするには?
mountコマンドの利用
Linuxではmountコマンドを使用します。
しかし、サーバにcdromやmediaを搭載するディレクトリがあるとは限りません。
存在しない場合はディレクトリから作成し、作成したディレクトリへisoをテラタームなどを用いて転送します。
サーバにisoを持ってきた後、isoマウントする方法をここでは説明します。①まず、現在のディレクトリ内にisoファイルが存在することを確認します。
# ls -l /media -rw-r--r--. 1 root root 531628032 4月 17 2019 CentOS-7-x86_64-NetInstall-1810.iso②次に対象のisoをマウントします。
[定型文] # mount -t iso9660 <isoイメージファイル> <マウント場所> # mount -t iso9660 /dev/cdrom /media③マウントされたのか、dfコマンドにて確認します。
# df -Tアンマウントされるには?
umountコマンドの利用
[定型文] # umount <アンマウントするディレクトリ> [使用例] # umount /media引用
DVD-ROMイメージファイルをマウントしてデータを参照
isoイメージをマウントする方法
以上がisoのマウント方法でした。
最後までお読みいただきありがとうございました!
- 投稿日:2019-11-26T12:26:43+09:00
リモートのLinuxを手元のWindowsで操作する(GUI編)
リモートのLinuxを手元のWindowsで操作する(GUI編)
知識をアップデートしたのでメモ。
概要
リモートのLinux機を自分の手元のWindowsで操作する。
SSH経由でX11に接続し、GUI操作できるようにする。設定の流れ
- Linux機のSSHサーバーの設定を行う
- WindowsにX server(VcXsrv)をインストールする
- WindowsのputtyからLinux機にssh接続する
- 動作テストをする
Linux機のSSHサーバーの設定を行う
設定ファイルを修正する。
$ sudo vi /etc/ssh/sshd_config書き換える内容(抜粋)。もとから設定されているならそのままでOK。
sshd_configX11Forwarding yes書き換えたらサービスを起動。
# systemctl start sshd.service
WindowsにX server(VcXsrv)をインストールする
下記からVcXsrvをダウンロードする。
VcXsrv Windows X Server download | SourceForge.net
インストーラーを起動してインストールする。
設定は全部初期値。スタートメニューから起動する。
初回は設定を色々きかれるが、全部デフォルトでOK。WindowsのputtyからLinux機にssh接続する
puttyを起動して、下記の項目にチェックする。
Connection -> SSH -> X11 -> Enable X11 forwarding
Linux機にログインする。
動作テストをする
ターミナルから下記コマンドを実行する。
(X11のアプリならどれでもOK)動作テスト$ nautilus
LinuxのGUIアプリがWindows上で表示される。
ファイルをダブルクリックするとLinux機内のアプリで表示される。
- 投稿日:2019-11-26T12:21:13+09:00
リモートのLinuxを手元のWindowsで操作する(CUI編)
リモートのLinuxを手元のWindowsで操作する(CUI編)
概要
リモートのLinux機を自分の手元のWindowsで操作する。
操作はCUIのみとし、SSH経由で接続する。設定の流れ
- Linux機でSSH接続用のサーバー設定を行う
- ファイアウォールを設定する
- Windows機にSSH接続用のクライアントソフトをインストールする
- SSH接続を実際に行う
Linux機でSSH接続用のサーバー設定を行う
SSHサーバーの設定を行う
設定ファイルを修正する。
$ sudo vi /etc/ssh/sshd_config書き換える内容(抜粋)。もとから設定されているならそのままでOK。
X11Forwading yes
は今後GUIのリモート接続をするための設定。Port 22 HostKey /etc/ssh/ssh_host_rsa_key PermitRootLogin no PasswordAuthentication yes X11Forwarding yes書き換えたらサービスを起動。
# systemctl start sshd.service
ファイアウォールを設定する
ssh接続を許可する。(既に設定済みなら不要)
# firewall-cmd --permanent --add-service=ssh
Windows機にSSH接続用のクライアントソフトをインストールする
下記から「putty-gdi-年月日.zip」をダウンロードする
zipを解凍する。場所はどこでもよい。
これでインストールは完了。SSH接続を実際に行う
インストールしたフォルダの中は下記のようになっている。
putty.exeをWクリックして起動する。下記のような画面が表示される。
<LinuxのIPアドレス>
の箇所に実際のIPアドレスを入力して
Open
ボタンをクリックする。ログイン名とパスワードを聞かれるので入力する。
パスワードは画面に何も表示されないが入力は受け付けられている。Linux機にログインが成功する。
後はLinux機に直接ログインした時と同様に操作ができる。
- 投稿日:2019-11-26T09:57:57+09:00
RHEL5,6,7,8で変更された主要まとめ
RHEL5,6,7,8で変更された主要まとめ
RHELのバージョン混在環境で、困惑するのでまとめてみました。
まあ、今更RHEL5はないでしょうが一応、記載しておきます。
また、調査しても分からない箇所もありましたので、追々追加していきます。
パッケージ RHEL 5 RHEL 6 RHEL 7 RHEL 8 カーネル 2.6.18 2.6.32 3.10.0 4.18 Grub Grub 0.97 Grub 0.97 Grub2 v2.00 GUI Gnome 2.16 Gnome 2.28 Gnome 3.8 Gnome 3.28 起動シーケンス SVR4 init Upstart systemd systemd Loging Syslog Rsyslog journalctl plus Rsyslog journalctl plus Rsyslog User Password MD5 SHA-512 SHA-512 SHA-512 パッケージ管理 yum
rpmyum
rpmyum
rpmdnf
yum
rpm時刻同期 ntp ntp ntp
chronychrony ディスプレイサーバ Xorg Xorg Xorg Wayland パケットフィルタリング iptables iptables
firewalldiptables
firewalldnftable RHEL8の主なバージョン
OpenSSL 1.1.1、TLS 1.3,GCC 8.2、OpenJDK 11/8などがサポートされる。PythonはPython 3.6がデフォルト、Node.jsのサポートや、PHP 7.2、Ruby 2.5、、Perl 5.26などが提供される。データベースはMariaDB 10.3、MySQL 8.0、PostgreSQL 10/9.6、redis 5、Apache HTTP 2.4、nginx 1.14がデフォルト。サービス系コマンド
RHEL 7,8では、サービス起動デーモンとして、SysVinit/Upstartに代わり、systemdが導入されました。これにより、サービス系コマンドが大幅に変更されています。RHEL8でもsystemdが採用されていることからRHEL7とは差異はありません。
サービス逐次起動系
処理内容 RHEL 5,6 RHEL 7,8 状態の表示(サービス単位) /sbin/service ※1 status /usr/bin/systemctl status 状態の表示(全サービス) /sbin/service --status-all /usr/bin/systemctl list-units ※2--type service 起動 /sbin/service start /usr/bin/systemctl start 終了 /sbin/service stop /usr/bin/systemctl stop 強制終了 kill -9 PID kill -s 9 再起動 /sbin/service <service_name? restart /usr/bin/systemctl restart 設定反映 /sbin/service reload /usr/bin/systemctl reload ※1:/etc/init.d/service_nameでも同様
※2:list-unitsは省略可サービス自動起動系
処理内容 RHEL 5,6 RHEL 7,8 (全サービス)定義の表示 ls /etc/init.d/ /usr/bin/systemctl list-unit-files --type (サービス単位の)定義の登録 /sbin/chkconfig --add /usr/bin/systemctl daemon-reload
※3自動起動の確認 /sbin/chkconfig --list /usr/bin/systemctl is-enabled 自動起動の有効化 /sbin/chkconfig on /usr/bin/systemctl enable 自動起動の無効化 /sbin/chkconfig off /usr/bin/systemctl disable ※3:Unitファイルを再読み込みすることにより登録される
systemdでは、「Unit」という単位でさまざまな処理を行います。従来のサービスに相当する処理は「.service」という拡張子がつくファイルとして管理されており、サービス関連の処理を行うときは、この名前を指定します。Unitには、ほかにもマウントポイントの処理を行う「.mount」、デバイスの処理を行う「.device」、Unitをグループ化する「.target」などがあります。
また、自動起動の登録を行ったUnitは、「/usr/lib/systemd/system/unit_name」内の[Install]セクションのWantedByオプションで指定されているUnitのディレクトリ(例:/etc/systemd/system/multi-user.target.wants/)にシンボリックリンクが張られることにより、自動起動が有効となります。
RHEL 6と同じコマンドを利用したい方は……
RHEL 7,8のserviceコマンドやchkconfigコマンドは、systemctlコマンドにリダイレクトするシェルスクリプトとなっているのでそのまま利用できます。
- サービスの一時停止
$ sudo service crond stop Redirecting to /bin/systemctl stop crond.service
- サービスの自動起動の無効化
$ sudo chkconfig crond off Note: Forwarding request to 'systemctl disable crond.service'. rm '/etc/systemd/system/multi-user.target.wants/crond.service'ただし、chkconfig --listについては、出力結果にも注意書きがあるとおり、一部のサービスしか表示されないため注意が必要です。
$ chkconfig --list Note: This output shows SysV services only and does not include native systemd services. SysV configuration data might be overridden by native systemd configuration.ランレベル
RHEL 7,8では、従来のランレベルに相当する起動モードも「.target」という拡張子がつくUnitで管理されるようになっています。これまでのランレベルとの対応は、下記のとおりです。なお、targetファイルを自作して、独自の起動モードを利用することも可能です。
処理内容 RHEL 5,6 RHEL 7,8 システム停止 0 poweroff.target シングルユーザモード 1 rescue.target マルチユーザモード 3 multi-user.target グラフィカルモード 5 graphical.target 再起動 6 reboot.target 緊急モード N/A mergency.target 通常の起動の際は、いずれかのtargetへのシンボリックリンク(通常はmulti-user.targetかgraphical.target)となっているdefault.targetが参照されます。
ランレベル系コマンドの一覧
処理内容 RHEL 5,6 RHEL 7,8 起動モードの変更 telinit
initsystemctl isolate 起動モードの認 runlevel systemctl list-units --type target Default起動モードの変更 /etc/inittabの編集 sudo systemctl set-default Default起動モードの確認 /etc/inittabの参照 systemctl get-default
- rescue.target(従来のシングルユーザモード相当)に変更
$ sudo systemctl isolate rescue.target
- デフォルトの起動モードをマルチユーザモードへ変更
$ sudo systemctl set-default multi-user.target $ rm '/etc/systemd/system/default.target' $ ln -s '/usr/lib/systemd/system/multi-user.target' '/etc/systemd/system/default.target'
- RHEL 6と同じコマンドを利用したい……
現在と1つ前のランレベルを表示するrunlevelコマンド、ランレベルを一時的に変更するtelinit(init)コマンドも利用できます。ただし、/etc/inittabは、ファイルそのものはあるもののコメントだけとなっているため、標準起動モードの変更については、systemctl set-default の実行が必要なようです。
ログ確認系コマンド
systemdによって起動されたUnitのログは、/var/log/journal以下にバイナリ形式で保存されるようになっています。そのため、ログの確認にはjournalctlコマンドを利用します。
ログ確認系コマンドの一覧は下記のとおりです。
処理内容 RHEL 5,6 RHEL 7,8 (サービス単位の)ログ確認 cat /var/log/ journalctl -u ログの更新監視 tail -f /var/log/ journalctl -f -u 起動ログの確認 dmesg systemctl journalctl --dmesg journalctlによる表示には、デフォルトでページャ(less)で表示されます。パイプ処理などでページャを利用したくない場合は、--no-pagerオプションを付加します。また、--sinceオプションで相対時間(例:30 min ago)、絶対時間(2015-04-30)以降のログ出力、--outputオプションでJSONなどの各種形式で出力、-bオプションでN世代前のブートログ表示など、数多くの機能を備えています。
ただし、デフォルト設定のままの場合、/run/systemd/journal以下にログが書き込まれ、再起動すると消えてしまうので注意が必要です。再起動後もログを残すには、/var/log/journalを作成して、journaldの再起動(systemctl restart systemd-journald)を行う必要があります。ネットワーク系コマンド
RHEL 7,8では、ifconfigやnetstatといった馴染みのあるコマンドが含まれている、net-toolsパーッケージがインストールされなくなりました。
ネットワーク系コマンドの一覧は下記のとおりです。なお、ipコマンドのオプションは、一意な文字列まで入力すれば認識してくれるので、短縮表記例も併記しておきます。
処理内容 RHEL 5,6 RHEL 7,8(フル表記) RHEL 7,8(短縮表記例) 全アクティブインターフェイスの情報表示 /sbin/ifconfig /sbin/ip address show
or /sbin/ip link show/sbin/ip a
or /sbin/ip特定インターフェイスの情報表示 /sbin/ifconfig eth0 /sbin/ip address show
dev enp0s3/sbin/ip a s
dev enp0s3ルーティングテーブルの表示 /sbin/route /sbin/ip route /sbin/ip r デフォルトゲートウェイの追加 /sbin/route add default gw xxx.xxx.xxx.xxx ip route add default via xxx.xxx.xxx.xxx /sbin/ip r a default via xxx.xxx.xxx.xxx デフォルトゲートウェイの削除 /sbin/route del default gw xxx.xxx.xxx.xxx ip route del default via xxx.xxx.xxx.xxx /sbin/ip r d default via xxx.xxx.xxx.xxx TCPの接続状態の表示 /bin/netstat -tan ss -tan 左に同じ インターフェイスごとの統計情報 /bin/netstat -i ip -s link ip -s ARPテーブルの表示 /sbin/arp -n /sbin/ip neighbour /sbin/ip n MAC Address /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/udev/rules.d/70-persistent-net.rules
RHEL 6と同じコマンドを利用したい方は……
net-toolsパッケージをインストールすれば、RHEL 6で使用していたネットワーク系コマンドはすべて利用可能となります。NetworkManager系コマンド
NetworkManagerは、RHEL 4から搭載されているネットワークユーティリティで、RHEL 7で新しく追加されたわけではありません。しかし、RHEL 7より、ネットワーク設定にはこのユーティリティを使用することが推奨されるようになったので、今後は利用頻度が高くなると思います。
NetworkManagerには、X上で動作するGUIツールのほか、ターミナル上でGUIで設定できるnmtuiコマンド、CUIで設定するnmcliコマンドがあります。ここでは、最も利用しやすいとnmcliコマンドを用いたNetworkManager系コマンドを下記に紹介します。
なお、デバイスを示す「デバイス名」と、接続に名前をつけた「接続名」は異なることがあるので注意してください。
処理内容 nmcliコマンド(フル表記) nmcliコマンド(短縮表記例) デバイス一覧の表示 /usr/bin/nmcli device /usr/bin/nmcli d デバイス情報の表示 /usr/bin/nmcli device
show device_name/usr/bin/nmcli d sh device_name 接続の作成 /usr/bin/nmcli connection add type type_name ifname if_name con-name connection_name /usr/bin/nmcli c a type type_name ifname if_name con-name connection_name 接続の削除 /usr/bin/nmcli connection delete connection_name /usr/bin/nmcli c de connection_name 接続一覧の表示 /usr/bin/nmcli connection /usr/bin/nmcli c 接続情報の表示(すべて) /usr/bin/nmcli connection show connection_name /usr/bin/nmcli c s connection_name 接続の変更 /usr/bin/nmcli connection modify .... /usr/bin/nmcli c m ... 接続の開始 /usr/bin/nmcli connection up connection_name /usr/bin/nmcli c u connection_name 接続の停止 /usr/bin/nmcli connection down connection_name /usr/bin/nmcli c d connection_name 接続情報の表示(特定フィールド) /usr/bin/nmcli --fields field_name connection show connection_name /usr/bin/nmcli -f field_name c s connection_name RHEL6でのNetworkManager
デフォルトで NetworkManager サービスが起動するため /etc/sysconfig/network-scripts/ifcfg-XXX の書式が従来と変わっています。
従来の書式で設定ファイルを書く場合は、設定ファイルに下記の1行を追加します。
NM_CONTROLLED=noもしくは NetworkManager サービスを停止します。
# chkconfig NetworkManager off # service NetworkManager stopRHEL6でのethX と MAC Address の紐付け
RHEL5では/etc/sysconfig/network-scripts/ifcfg-XXXにHWADDRとして記載していたが
RHEL6では、/etc/udev/rules.d/70-persistent-net.rules で指定します。# cat /etc/udev/rules.d/70-persistent-net.rules # This file was automatically generated by the /lib/udev/write_net_rules # program, run by the persistent-net-generator.rules rules file. # # You can modify it, as long as you keep each rule on a single # line, and change only the value of the NAME= key. # PCI device 0x14e4:0x164c (bnx2) (custom name provided by external tool) SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:14:5e:fa:98:a2", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1" # PCI device 0x14e4:0x164c (bnx2) (custom name provided by external tool) SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:14:5e:fa:98:a0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"が、相変わらず、/etc/sysconfig/network-scripts/ifcfg-ethX にも HWADDR 指定があるので、両方を合わせないといけない。ifcfg-ethX の HWADDR は削除した方が幸せになれるかも知れません。
ロードモジュール
RHEL6では、/etc/modprobe.conf が無くなりました。目的別に対応を説明します。
(1) initrdに投入する内蔵ディスク用のデバイス・ドライバの指定(alias scsi_hostadapterXX)
RHEL5 までは、mkinitrd コマンドは /etc/modporbe.conf をみて、そのサーバを起動するために必要なドライバを含む initrd を作成しました。initrd に含まれる初期化スクリプト init では、下記の例のように必要なドライバを直接 insmod しています。echo "Loading ehci-hcd.ko module" insmod /lib/ehci-hcd.ko echo "Loading ohci-hcd.ko module" insmod /lib/ohci-hcd.ko ...RHEL6 では、initrd の作成が dracut に変わって、サーバ個別の initrd ではなく、汎用的な initrd が作成されるようになったので、/etc/modprobe.conf による指定は不要になりました。dracut が作成する initrd では、udev によって、サーバに接続されたデバイスに応じたドライバを自動判別してロードします。
具体的には、initrd に含まれる etc/udev/rules.d/80-drivers.rules のルールから modprobe が呼び出されます。
# cat 80-drivers.rules # do not edit this file, it will be overwritten on update ACTION!="add", GOTO="drivers_end" DRIVER!="?*", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe -b $env{MODALIAS}" SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", RUN+="/sbin/modprobe -b tifm_sd" SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", RUN+="/sbin/modprobe -b tifm_ms" SUBSYSTEM=="memstick", RUN+="/sbin/modprobe -b --all ms_block mspro_block" SUBSYSTEM=="i2o", RUN+="/sbin/modprobe -b i2o_block" SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -b sg" SUBSYSTEM=="module", KERNEL=="parport_pc", RUN+="/sbin/modprobe -b ppdev" LABEL="drivers_end"そうは言っても特定のドライバを特定の順序で読み込ませたい場合は、カーネルオプション rdloaddriver にドライバを読み込む順に記載します。具体的には、init スクリプトから下記のスクリプトが実行されて、指定のドライバがロードされます。
# cat cmdline/01parse-kernel.sh #!/bin/sh for p in $(getargs rdloaddriver=); do modprobe $p donedracut が標準で initrd に含めないドライバを使用する際は、dracut の -d オプションで強制的に initrd に入れておきます。dracut については、レッドハットニュースレター:vol.53 - dracut もどうぞ。
http://www.jp.redhat.com/magazine/jp/201102/rhel.html2) NIC用のデバイス・ドライバの指定(alias ethXX)
サーバ起動後の追加のドライバのロードは、すべて udev で処理されるようになっています。具体的には、rc.sysinit から start_udev したタイミングで、/lib/udev/rules.d/80-drivers.rules に従って自動的に modprobe されます。(dracut 内部の動作と基本的には同じです。)
# cat /lib/udev/rules.d/80-drivers.rules # do not edit this file, it will be overwritten on update ACTION!="add", GOTO="drivers_end" DRIVER!="?*", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe -b $env{MODALIAS}" SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", RUN+="/sbin/modprobe -b tifm_sd" SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", RUN+="/sbin/modprobe -b tifm_ms" SUBSYSTEM=="memstick", RUN+="/sbin/modprobe -b --all ms_block mspro_block" SUBSYSTEM=="i2o", RUN+="/sbin/modprobe -b i2o_block" SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -b sg" SUBSYSTEM=="module", KERNEL=="parport_pc", RUN+="/sbin/modprobe -b ppdev" LABEL="drivers_end"ちなみに、udev が必要なドライバを判別する方法は次のとおりです。まず、PCI デバイスなどは、/sys に登録されるとカードに固有の modalias 情報が登録されます。
# cat /sys/devices/pci0000:00/0000:00:06.0/0000:03:00.0/0000:04:00.0/modalias pci:v000014E4d0000164Csv00001014sd00000342bc02sc00i00一方、各ドライバは、サポートするデバイスの modalias 情報を持ちます。下記の alias: 部分です。
# modinfo bnx2 filename: /lib/modules/2.6.32-71.el6.x86_64/kernel/drivers/net/bnx2.ko firmware: bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw firmware: bnx2/bnx2-rv2p-09-5.0.0.j10.fw firmware: bnx2/bnx2-mips-09-5.0.0.j15.fw firmware: bnx2/bnx2-rv2p-06-5.0.0.j3.fw firmware: bnx2/bnx2-mips-06-5.0.0.j6.fw version: 2.0.8-j15 license: GPL description: Broadcom NetXtreme II BCM5706/5708/5709/5716 Driver author: Michael Chan <mchan@broadcom.com> srcversion: 8CDA41B3E0DF70A112FBA80 alias: pci:v000014E4d0000163Csv*sd*bc*sc*i* alias: pci:v000014E4d0000163Bsv*sd*bc*sc*i* alias: pci:v000014E4d0000163Asv*sd*bc*sc*i* alias: pci:v000014E4d00001639sv*sd*bc*sc*i* alias: pci:v000014E4d000016ACsv*sd*bc*sc*i* alias: pci:v000014E4d000016AAsv*sd*bc*sc*i* alias: pci:v000014E4d000016AAsv0000103Csd00003102bc*sc*i* alias: pci:v000014E4d0000164Csv*sd*bc*sc*i* alias: pci:v000014E4d0000164Asv*sd*bc*sc*i* alias: pci:v000014E4d0000164Asv0000103Csd00003106bc*sc*i* alias: pci:v000014E4d0000164Asv0000103Csd00003101bc*sc*i* depends: vermagic: 2.6.32-71.el6.x86_64 SMP mod_unload modversions parm: disable_msi:Disable Message Signaled Interrupt (MSI) (int)これらの情報は、depmod がまとめて /lib/modules/$(uname -r)/modules.alias に記録しており、「modporbe 」を実行すると modules.alias から必要なドライバを判別して自動的にロードします。/lib/udev/rules.d/80-drivers.rules では、Kernel が udev に通知した modalias を使って modprobe しています。udev に勝手にロードしてほしくないドライバは、/etc/modprobe.d/blacklist.conf 内に blacklist オプションで指定しておきます。
ホスト名操作系コマンド
RHEL 7,8では、ホスト名もsystemdが管理しているため、永続的なホスト名の変更方法も変更されました(hostnameコマンドを利用した一時的なホスト名の変更はRHEL 6と同じです)。
ホスト名操作系コマンドの一覧は下記のとおりです。
処理内容 RHEL 5,6 RHEL 7,8 ホスト名の確認 hostname hostname or hostnamectl ホスト名の変更(永続的) /etc/sysconfig/networkを編集 hostnamectl set-hostname new_host_name
,/etc/hostnameを編集なお、「
nmcli global hostname new_host_hame
」を実行して、NetworkManager経由でも変更することができます。ファイアウォール系コマンド
RHEL 7では、ファイアウォールとしてfirewalldが導入されました。これは、内部的にはiptablesを利用しているものの、「ゾーン」と呼ばれるiptablesとはまったく異なる機能を提供しているため、コマンド一覧は割愛します(iptabelesサービスとの併用もできません)。
RHEL 8では、ファイアウォールとしてnftablesが新たにiptableと置き換えで実装されたパケットフィルターです。
デフォルトでは nftablesは RHEL 7 での iptables と同様に、firewalld のバックエンドとして動作するので、既に firewalld に移行している場合はあまり気にならないかもしれません。
nftables を利用するメリット
フィルターの処理が、線形処理からテーブル探索に(処理速度の高速化)
IPv4とIPv6をひとつのコマンドで管理可能に(ip6tables のような、IPv6専用コマンドは使いません)
ネットワーク層以外のプロトコルも管理可能に(entablesとarptablesは、nftablesに統合されました)
一貫性があり、簡潔な文法(iptables の –dport のようなプロトコル独自の拡張はありません)
モジュール組み込み
aliasの記載もRHEL6,7では変更されている。
RHEL 5 RHEL 6 RHEL 7,8 /etc/modprobe.conf /etc/modprobe.d/
※bondingのaliasはnet-alias.conf/etc/modprobe.d/
※bondingのaliasはnet-alias.confStorage
FS Type,Size
Release Default FS 暗号化 FS Maximum Volume size File size RHEL5 ext3 LUKS 4-32TiB 16GiB-2TiB RHEL6 ext4 LUKS 1EiB 16TiB RHEL7 xfs LUKS 16EiB 8EiB RHEL8 xfs LUKS2 16EiB 8EiB 利用可能なFS
Release 利用可能なFS RHEL5 ext3,ext4,GFS,GFS2,XFS RHEL6 ext3,ext4,GFS2,XFS RHEL7 ext3,ext4,GFS2,XFS,Btrfs RHEL8 XFS,ext3,ext4、NFS、SMB、GFS2、Stratis Diskパーティション系コマンド
ブート方式 パーティション管理 BIOS MBR形式 UEFI GPT形式
処理内容 MBR形式 GPT形式 サポートするファームウェア BIOS,UEFI UEFI 基本パーティション 最大4 最大128 拡張パーティション 1 無し 拡張パーティション内の論理パーティション 制限無し 無し ツール fdisk、parted parted,gdisk,gparted ブートローダの制限 ハードディスクの2.2TB内 9.4ZB(ゼタバイト) Redhat Linux サポート状況 RHEL 5 x86
RHEL 5 x86_64
RHEL 6 x86
RHEL 6 x86_64RHEL 6 x86_64
RHEL 7 x86_64
RHEL 8 x86_64(*)各ディスクの先頭に保存されているMBR(マスター・ブート・レコード)はパーティション・テーブルのデータ長が32bitです。よって2の32乗セクタ×512bytes=約2.2Tbytesとなります。
BIOSとUEFIではパーティション管理形式も異なります。BIOSではMBR形式のみです。一方UEFIではMBR形式とGPT形式がサポートされています。
RHEL5,6ではpartedが OS 標準のRPMとして含まれている。
RHEL7 では gdisk が OS 標準のRPMとして含まれている。2TBを越えるディスク領域を使用する際の注意事項
パーティション作成にはpartedユーティリティを使用し、GPT(GUIDパーティションテーブル)を使用します。fdiskでは2TBを越えるディスクスペースは扱えません。
Anacondaインストーラーは、GPTをサポートしていない為、2TBを越えるディスクスペースは扱えません。
/boot, / パーティションは 2TB未満のディスク領域にインストールする必要があります。■■■ ファイルシステム系コマンド ■■■
RHEL 7ではファイルシステムもext4からxfsに変更されています。
・EXT4 と XFS コマンドの参照表
処理内容 ext3 ext4 XFS Btrfs FS作成 mkfs.ext3 mkfs.ext4 mkfs.xfs mkfs.btrfs FSをマウントする mount mount mount mount FSのサイズを変更する resize2fs resize2fs xfs_growfs
[※1]btrfs filesystem resize FSの準備を整える e2fsck
fsck.ext3e2fsck
fsck.ext4xfs_repair btrfsck FSのラベルを変更する e2label e2label xfs_admin -L btrfs property ディスク領域およびファイル使用量を報告 quota,quotaon, repquota quota,quotaon, repquota xfs_quota btrfs quota FSをデバッグする debugfs debugfs xfs_db FSの重要なメタデータをファイルに保存する e2image e2image xfs_metadump btrfs-image FSの情報表示 dumpe2fs dumpe2fs xfs_info FSのメタデータの変更 tune2fs tune2fs xfs_admin btrfs property FSのバックアップ dump dump xfsdump btrfs image FSのリストア restore restore xfsrestore btrfs image ファイルのディスク上のブロック一覧表示 filefrag filefrag xfs_bmap FSのデフラグ e4defrag e4defrag xfs_fs btrfs filesystem defragment FSの一時停止 fsfreeze fsfreeze xfs_freeze,fsfreeze ※1:XFSファイルシステムのサイズは縮小できません。サイズを拡大する場合にのみコマンドを使用します。
XFSの設定のポイント
ほとんどのシステムでは特別なチューニングを行うことなくデフォルトの状態でXFSを利用できますが、要件によっては設定次第で性能が向上する可能性があります。例えば、RAIDアレイ上にXFSを構築する場合、ストライプユニットをRAIDアレイのストライプユニットと一致させることにより、性能向上が期待できます。ストレージデバイスがOSに自身のストライプユニットを通知している場合は、特にユーザーが設定する必要はありません。手動でストライプユニット、ストライプ幅を設定する場合、以下のようにしてファイルシステムを作成します。
# mkfs.xfs -d su=64k,sw=4 /dev/sda1suはファイルシステムのストライプユニット、swはストライプ幅を意味します。swにはストライピングを構成するハードディスクの数(パリティディスクは含まない)を設定します。
上記の設定をした場合、ジャーナル領域へのログ書き込みのストライプユニットも同様の値に設定されます(上記の例では64kB)。もし同期書き込みが多いワークロードでXFSを使用する場合、ログ書き込みのストライプユニットが大きいと性能低下の原因となることがあります。そのような場合、以下のようにログ書き込みのストライプユニットを最小値(1ブロックサイズ:通常は4kB)に設定すると性能が改善するかもしれません。
# mkfs.xfs -d su=64k,sw=4 -l su=4k /dev/sda1また、ログ書き込みのオーバヘッドを改善する対処策としては、ログが書き出されるジャーナル領域を、データ用の領域として使用するデバイスとは別に用意するという方法も考えられます。
その場合、以下のようにしてファイルシステムを作成します。# mkfs.xfs -d su=64k,sw=4 -l logdev=/dev/sdb1 /dev/sda1上記コマンドでは、データ用の領域を/dev/sda1に、ジャーナル領域を/dev/sdb1に作成しています。
最後に
今回調べてみて、RHEL 7,8での変更点の多さを改めて痛感しました。もはや、これまでのRHELとは別のOSになったような雰囲気すらあります。ただし、RHELにかぎらず、多くのディストリビューションがsystemdへの対応を表明していますので、使いこなせるようになっておきたいところです。そのためにも、今回は詳しくは触れられなかった、Unitの仕組みの理解が不可欠と思いました。
- 投稿日:2019-11-26T05:57:43+09:00
LinuxでCPU温度を計測する
環境
ubuntu 18.04.3 LTS
catでtempファイルを直接表示
$ cat /sys/class/thermal/thermal_zone0/temp 58200ディレクトリの "thermal" 以下はOSやCPUで違うため適宜読み替えが必要。
lm_sensorsを使う
$ apt-get install lm-sensors (省略) $ sensors coretemp-isa-0000 Adapter: ISA adapter Package id 0: +60.0°C (high = +87.0°C, crit = +105.0°C) Core 0: +57.0°C (high = +87.0°C, crit = +105.0°C) Core 1: +60.0°C (high = +87.0°C, crit = +105.0°C)psensorを使う(GUI)
$ apt-get install psensor (省略) $ psensorチェックボックスにチェックを入れるとグラフ表示も可能
xsensorを使う
$ apt-get install xsensors (省略) $ xsensorsおわり
紹介したツールのインストールは他ディストリビューションでも基本的に同じ(未確認)
それぞれ大きな違いはなさそうなのであとは好みで。
HDDの温度も同時に見れるpsensorが便利。参考サイト
https://wiki.archlinux.jp/index.php/Lm_sensors
https://www.addictivetips.com/ubuntu-linux-tips/check-cpu-temperature-on-linux/
https://www.cyberciti.biz/faq/how-to-check-cpu-temperature-on-ubuntu-linux/
- 投稿日:2019-11-26T04:56:35+09:00
Linux 作業メモ: 時間を進める/戻すコマンド
Linuxのシステム時間を進めたり戻したりするコマンド。テストの時に重宝するのでメモ。
基本的には使うのはこのコマンドのみでOK.
date --set="STRING"
- 例1. 時間を"4 DEC 2019 15:30:00"へ進めます。
# date Mon Nov 25 11:41:16 PST 2019 # date --set="4 DEC 2019 15:30:00" Wed Dec 4 15:30:00 PST 2019
- 例2. 時間を25 NOV 2019 11:45:00"へ戻します。
# date --set="25 NOV 2019 11:45:00" Mon Nov 25 11:45:00 PST 2019
便利なので是非ご利用ください。
- 投稿日:2019-11-26T01:51:37+09:00
hostsを使って集中を切らすサイトへのアクセスをブロックする
背景
Macbookを作業専用として使っているが、僕は意志薄弱なのですぐにTwitterやYouTubeを開いてしまう。
これらのサイトドメインへのアクセスをブロックすることで作業中の集中力を上げたい。
ブラウザ(Chrome)のブックマークや拡張機能は他のPCと同期しているので、その辺りは利用したくない。環境
OS: macOS Catalina v10.15.1
ブラウザ: Google Chrome v78.0.3904.108(Official Build) (64 ビット)対応
hostsファイルを編集し、対象ドメインの名前解決先を127.0.0.1にすることでアクセスをブロックする。
$ sudo vi /etc/hosts # 以下追記 127.0.0.1 twitter.com 127.0.0.1 tweetdeck.twitter.com 127.0.0.1 www.youtube.com設定反映のためにDNSキャッシュを削除する必要がある。
DNSキャッシュはmDNSResponderプロセスが保持している。
Chromeでは、このプロセスへのSIGHUP送信では設定が反映されなかったため、一旦プロセスをKILLする。$ sudo killall mDNSResponder確認
ブラウザから今回ブロックしたサイトにアクセスできなくなっていることを確認する。
- 投稿日:2019-11-26T01:40:46+09:00
aliasの便利コマンドを教えてほしい話
UNIXやLINUX上でコマンドを省略した形で登録することのできるaliasについて紹介する
alias:コマンドの省略形が作成できる
bash
$ alias 登録したい単語='登録したいコマンド'$ alias histail='history | grep curl | tail' $ histail 3295 curl "http://localhost:8080" 3296 curl "http://localhost:8080" 3297 curl "http://localhost:8080" 3298 curl "http://localhost:8080"zsh
~/.zshrcにbashと同じように記述することでaliasを登録できる
$ vi ~/.zshrc alias histail='history | grep curl | tail' alias rezsh='source ~/.zshrc' alias redoc='docker-compose stop && yes | docker-compose rm && docker-compose up -d' alias -g @b64='| base64 ' alias -g @d64='| base64 -D' alias -g g='|grep ' alias vish='vi ~/.zshrc'zshにはグローバルエイリアスと呼ばれるエイリアスが登録できる
グローバルエイリアスは普通のエイリアスと違い、呼ばれる場所を問わない(普通のエイリアスは文頭限定)なので
$ echo aaaaaaa @b64とすることでbase64エンコードをかけることなどができる
(あまり省略できてないとは言わないでください)aliasメモ
便利だと思ったaliasをメモ的に列挙しておきたいので、教えてください(他力本願)
alias 元のコマンド 操作説明 rezsh source ~/.zshrc zshの設定ファイルを再読み込みさせる redoc docker-compose stop && yes | docker-compose rm && docker-compose up -d |docker-composeの再起動を行う sd docker-compose stop docker-composeを止める rd docker-compose rm docker-composeの設定を削除する ud docker-compose up -d docker-composeを立ち上げる vish vi ~/.zshrc zshの設定ファイルを編集する @b64 | base64 base64エンコーディングを行う @d64 | base64 -D base64デコーディングを行う