#/usr/binとその同種の周辺を探る

あとmkfsコマンドのforceフラグがファイルシステムによって-fだったり-Fだったりするのも許してないからな
gzファイルのヘッダーに更新時刻があるのでhardlinkでディスク節約バックアップができない。書き出した後にまた開いてヘッダー書き換えるか、そもそもヘッダー無しのデータを書き出すか。後者はPerlIO::gzipで簡単にできるがgzipコマンドで読めないファイルになる。
そう言えばLinuxにはteeコマンドがあるけど、標準入力を標準出力とファイルの両方にリダイレクトするものだ。これが結構便利で、C++内でも使えるようにios_baseで書いてやった。すごい簡単です。両方出力すればいいだけだから。そして見た目は一箇所に出力してるように見える。
ddコマンドは、ファイルシステムの種類などに関係なく、デバイスに対して入出力を行える。 #lpic
*.zipファイルがあったらunzipするような手順を作りたいんだけど、コマンドどうすっかな…
rpmコマンドの-qlオプションにpを付加すると、引数に指定した未インストールパッケージ(拡張子が.rpmのパッケージファイル名。パッケージ名ではないことに注意)がインストール時に展開するファイル一覧を表示できる。 #lpic
システムにインストールされているファイルが、どのRPM形式パッケージに由来するかを調べるには、rpmコマンドに-qfオプションを指定し、引数としてファイル名を渡す。 #lpic
久しぶりにデスクトップの方のPCを起動したらCドライブの空き容量が0になっていて一瞬ギャーととなったけど、インテルさんのツールがSSDにTrimコマンドを発動させている間は一時的にダミーファイルで空き容量を埋める模様ですぐに復活した(;・∀・)
古い画像ファイル削除しようとしてもなぜかフリーズしてしまってた。 GUIでダメならCUIならと思いタスマネでエクスプローラ落として、プロンプトから削除コマンド叩いたら消せた。 やっぱりプロンプト優秀だな。
なので各アプリやコマンド用の設定ファイルを一種のviewと考えてそちらは生成するのが正しく。とは言え手続き的な生成の場合には何がどうなっているのか煩雑になりそう。そこで宣言的な記述が行えるようにしたい。yamlに直で書けたら良いのでは?みたいな話になっていたっぽい。頭の中では。
[私見]なるべくなら、gzipやbzip2を直接使うより、tarコマンドのオプションで一気に圧縮・解凍を行ったほうがよい。なぜなら、tarコマンドは元のファイルを削除しないので安全だから。gzipやbzip2も-cオプションで同じことができるが、つけ忘れが怖い。 #lpic
chmodコマンド ファイルの権限を変更できる。 chmod 777 test.txt だとフル権限に変更できる。 権限というのはls -lを叩いた時に 表示される。rwxr--r-- というもの。
今日ファイルリネーマーの話がTLで出たんだけど、個人的にはコマンドラインで処理するのがはやいのと環境依存が少なくて良いと思ってる。 アプリだとElectronがWin/Macで使えて良いのかな。ファイルやフォルダはD&Dで、正規表現はInput属性にすれば良いんじゃないかな。
CTRL-G → 現在の(パス名+)ファイル名とカーソル位置を表示 [さまざまなコマンド] #Vim
ldconfigコマンドは、/etc/ld.so.confの内容を元に、バイナリのキャッシュファイル/etc/ld.so.cacheファイルを構築する。 #lpic
"del"コマンド・・・ファイルを削除します。 #Human68k #X68000
【Linux】/etc/yum.repos.dディレクトリにはyumコマンドで使用されるリポジトリ情報の設定ファイルが格納される。/etcyum.confはyumコマンドでパッケージ管理する際の設定ファイル。
>for /f "usebackq" %i in ("ファイル名") do echo %i >for /f "usebackq" %i in ('文字列') do echo %i >for /f "usebackq" %i in (`コマンド`) do echo %i
第1弾から失礼するゾ~(デーモン・コマンド)最初の悪魔かっこよスギィ!自分、コレクションいいっすか? 傷付きそうだからカードファイルにぶち込んでやるぜー!上位互換多すぎてすいません!許してください!なんでもしますから!(なんでもするとは言ってない) 混沌の獅子デスライガー
splitコマンドを用いて、100行単位にファイルを分割する場合、「split -100 hoge.txt output.」などとする。この場合、分割後のファイルは、output.aa、output.ab・・・といったように作成される。 #lpic
【メニューバーをキー操作で】 メニューバーのコマンドを、[Alt]と矢印キーでできる。 まず、[Alt]キーを押します。すると[ファイル]の表示が四角く浮き出る 次に[↓]キーを押すと凹んで[ファイル]のコマンドメニューが現れるので、[↑][↓]で選択して[Enter]で確定。
sedコマンドは、入力されたテキストストリームに、コマンドの実行結果を反映しない。リダイレクトで別ファイルに出力するなどして変更結果を保存する。 #lpic
dfコマンドで、システムにマウントされているファイルシステムの残り容量を調べることができる。 #lpic
docker コンテナ内の環境構築している内にホストの容量が逼迫してしまい本当に残念なことになった。一時ファイル的なものを生成するすべてのコマンドが使えなくなり、rm も使えないという状況に…。/bin/rm とフルパスを指定するとなぜか使えて直せたけど、理由はよくわからない。
CTO に eryngii ってスペル打ちにくいから ei ってコマンド名にしようぜって提案してみてる。ei -l -w で実行したフォルダ以下の全ての erl ファイルを強制的に置き換える。(引数は gofmt マネした)
--disable-gpu つけて起動すればこの問題は起きないんだけど Windows でファイルを開く時にコマンドラインをつけるの面倒なので困る
xclipってコマンドを使うと他のコマンドの出力をクリップボード📋にコピーできるんですよ❗😉ファイルの一覧を表計算ソフトに入力したいときなら、「ls *.txt | xclip -selection clipboard」で一発ですね❗👍✨
chmodコマンドのオプションで、「+」は権限の追加、「-」は権限の削除、「=」は権限の上書きを表す。例えば、hogeというファイルにおいて、その他ユーザに「書き込み」「実行」権限を追加するときは、「chmod o+wx hoge」とする。 #lpic
N % → ファイルの N パーセント目に移動。このコマンドは N の指定が必須。無指定の場合は|%|コマンド扱い。 [上下の移動] #Vim
:badd {fname} → ファイル名{fname}をバッファ一覧に追加 [バッファ管理コマンド] #Vim
pvコマンド使えばよかったと後悔(500Gのファイルをコピー中,cpでやったため進捗わからん)
フューリーの読み通りね。あの船やっぱり怪しい。よほど隠したいファイルなのね。コマンドを打つとAIで書き換えられてしまう。 (ナターシャ)
CTRL-W f → ウィンドウを分割し、カーソル下のファイルにジャンプ [複数ウィンドウコマンド] #Vim
bzip2コマンドで圧縮されたファイル「xxx.bz2」を解凍するときは、bunzip2コマンドを用いる。bzip2に-dを付けるのでもよい。 #lpic
xdelta3を使った時の一括差分合成コマンド出来た diffファイルは合成前のファイル名+.diffって名前にしておく
今のところlambdaでシェルを使えるようにできた。ちゃんとIAMrole利用してaxsコマンドからs3にファイルアップまで実現済み。ただめんどくさい笑。POSIX原理主義製mojihameコマンドも持ち込めば楽だけど、そもそもnodejs挟んでる時点でPOSIX原理主義ではない
macで.からはじまるのは非表示にしてんのもまずかったな。コマンドラインから見てりゃええやろと思ってたけど、、サーバー側のファイルマネージャーみて、やっとわかった。ほんまに意味わからんかったw
teeコマンドってファイルに保存しちゃうじゃん。別のパイプに分岐させるとかできないの?
「insmod コマンドで .ko ファイル読み込むと、カーネル空間で標準出力されます。」 #osdev_moku2
私が思いつく、一番マシな設定方法はusiコマンドで返す編集可能なパラメタをusinewgameで読み込むテキスト、ファイル名だけにして、そのテキストに、クラスタを全て停止→クラスタ起動→クラスタのパラメタ設定的ななコマンドを書くという流れ。しかしこれにも問題はあります。
Cygwinのzipコマンド使うと、日本語ファイル名が化けるのだよね。仕様と言えばそれまでだが、何かいい方法ないかな?。
macで.からはじまるのは非表示にしてんのもまずかったな。コマンドラインから見てりゃええやろと思ってたけど、、サーバー側のファイルマネージャーみて、やっとわかった。ほんまに意味わからんかったw
perfコマンドからCPUフレームグラフを生成して、生成したファイルをチャットに投げてくれるスクリプトを作った方が良い気がしてきた。 いちいちサーバ入ってコマンド打ってファイルを転送してを繰り返すのがめんどくさくなってきたYO。。。
サクラエディタ、コマンド実行できるじゃん!やったー!今日偶然さわっちゃったctrl+F5で「ファイル名を指定して実行」を発見。さっきhello,worldを試してみたら出来た!なーんだ。コマンドプロンプトと行ったりきたりしなくてもデバッグ出来るんだ。
それよりも私はzipファイルについて学ばねばならない…圧縮とは…どのコマンドだ…
cpioコマンドがtarコマンドに比べて便利なケースは、アーカイブ対象のファイルの種類や数が動的に変わるときである。たとえばfindコマンドの結果などを標準入力に与えることで、find実行時点の条件にあったファイルやディレクトリのみをアーカイブにすることができる。 #lpic
iMac重い〜。特にファインダ。ダウンロードしたファイルを開くのにコマンド使うことにしました。open `ls -trd ~/Downloads/* | tail -n 1`  macのファインダってそもそも使いにくいし、コマンド使えてことかな?
rpmコマンドの-qiオプションにpを付加すると、引数に指定した未インストールパッケージ(拡張子が.rpmのパッケージファイル名。パッケージ名ではないことに注意)の情報を表示できる。 #lpic
dfコマンドに-iオプションをつけると、ファイルシステムのiノードに関する使用状況を表示できる。 #lpic
shufコマンドを使うと、行をシャッフルした結果を出力できるんですよ❗「shuf テキストファイルのパス | head -n 1」ってすれば、ファイルに書かれた内容をランダムに1行だけ取り出せますよ~😉……実はこのアカウントのランダム発言もこれでやってるんですけどね💦
#SCPをざっくり紹介 LINUXにおけるコマンド。 任意のディレクトリにデータまたはファイルをコピーする。
Visual Studioのビルド構成の意味がよくわからんね。外部ライブラリをDynamic linkしてビルドするとき、指定するライブラリファイルをdllではなくlibにしないとビルドが通らず、でも出力される実行ファイルはちゃんと外部依存している(dumpbinコマンドで確認)
作業用に使っているNASのファイル整理(※削除するファイルが百万単位)に時間が掛かるのにいい加減うんざりして、どうせLAN接続のみだしと言う事で、試しにssh接続出来るようにしてrmコマンドを実行してみたら、掛かる時間が劇的に短縮されて嬉しいようなもっと早く試せば良かったような。
岡部「コマンドラインでautojっていうコマンドが実行できるファイルをcで作りました。こいつはJavaのファイルをコンパイル、実行した上でwordを立ち上げてソースコードを貼り付けてくれるものです」 岡部、あんたホントに仕事ができるな!(教えるのが上手とは言ってない)
サクラエディタえらい!ctrl+F5使いまくり。標準出力もテキストとして書き出されるので、1日分最後に保存すれば全て残る。コマンドは毎日バッチファイル作って書き込んでいる。ctrl+F5でいつもそのバッチファイル名打ち込めばOK。
新歓曲集のやつ、独自コマンド組まれてるからファイル全部揃えてコンパイルしないとうまくいかないと思う (今週中に引き継ぎ資料どうにかします)
Excelは既存のファイルを開く時に「プログラムにコマンドを送信しているときに、エラーが発生しました。」が発生しすぎて本当にポンコツ感出てきてない?
grepコマンドは, 設定ファイルとかから変数探したりするのに 便利。 #grep #UNIX
cpioコマンドは、findコマンドなどと組み合わされて使用されることが多い。たとえば、ファイル/ディレクトリのタイムスタンプなどを条件に検索した結果を標準入力に与えることで、変更されたファイル/ディレクトリのみを差分としてアーカイブ、バックアップなどができる。 #lpic
Windowsコマンドラインがゴミなのでプログラム上でファイル開くシステムコール呼んで、ファイルを読むとcrとlfの区別失敗して死んたりする
【Oracle】SQLPlusコマンド sav[e] ファイル名:SQLバッファの内容をファイルに書き出す。get ファイル名:ファイルの内容をSQLバッファにロードする。ed[it] [ファイル名]:OSエディタを使ってSQLバッファまたはファイルの内容を変更する。
scpコマンドは、SSHの仕組みを用いた安全なファイルコピーを行う。 #lpic
引数に指定したDebian形式パッケージがインストール元となっているファイルを、検索して表示するには、dpkgコマンドに-Lアクション(あるいは--listfiles)を指定する。 #lpic
複数の人間で、複数のドキュメントをあれこれ改訂しまくり。ver.管理はファイル名のみで、訳判らない状況。なので、forfilesで日付指定して、findstrで抽出、clipコマンド経由でexcelに貼付けて整理。
万が一に備えて黙視確認はしておこうと言うスタイルです。 なので一端自分のローカルにファイルを落としてfcコマンド等で比較したり…
プログラムいくらコマンド打ってもファイルがありませんって出るんだけど ダレカタスケテ
うちのクラスもで、バッチファイルさえ組めないの多いしそもそもLinuxシェルコマンドつかえないとかブラインドタッチできないとか
お目当てのスクリプトファイルがwhichコマンドですら探し当てられなくて嘆いてる
指定した行数でファイルを分割するコマンドはsplitである。行数を指定しない場合、デフォルトで1000行毎に分割する。 #lpic
dirコマンドでファイルパスのリストファイルを作って、そいつを読み込んでファイル操作する処理を作ってたら、リストファイルから読み取ったファイルパスに改行コードが付加されていることを忘れて、ずっと「ファイル開けなねぇ」って言ってたからプログラマやめてサバゲフィールド開こうか
AWSLabmdaにあげるために assemblyコマンドでjarファイルつくってる #scala_kb
webpackとタスクランナーちがい webpack → いろんなファイルを一つのファイルにまとめる gulpとかタスクランナー → サーバを立てるとか含めていろんなコマンドを実行する #WeJS
コマンドファイルの作製は今日中に終わらせたいところだが…
nkfがPOSIXにないので、スクリプト改修のついでにiconvに置き換えてしまおうとしたが、iconvには文字コードの自動識別ないのかー。 文字列を一度ファイルに落としてfileコマンドで評価することにしよう。
淡々とLinuxサーバにコマンド叩き込んではファイルを入れ替え、アップデートするという作業を半日やったら、脳が考えることを拒否し始めて、この苦痛を、今日休んだ担当者本人にぶつけてやりたい気持ちでいっぱいになりました。(作業遅くて間に合わないので応援に駆り出された)
コマンドライン引数からファイル名指定して、関数inputに渡して先頭の値を人数としてforでんばーっと配列に入れて終わったら、変数countで60点以上抽出して、関数showで出力
そういえば、ファイル上からコマンドを実行するとかいう究極の方法が出たからサバイバルワールドで魔法を追加するadvancementとかが配布されたりスルのかね
ニック・バレンタインが行方不明のままになってしまったので、コンソールコマンドのバッチファイル群をダウンロードして使った。色々と処理が複雑なんですかね?
git for windowsのすごいところって、exe形式のコマンドの実体が全部(?)別ファイルになってるとこだと思う。/usr/lib/git-coreに同一内容で別名の実行ファイルがいっぱいある(ファイル長が同じのはだいたい内容も同一かと)。富豪的だぁ…(ロートル感)
設定ファイルを確認するコマンドで文法エラーがないか確認してOK、ポートも開放したがタイムアウトするのはなぜなのか
ちなみにsphinxの自動生成では真面目に自分でrstファイル書くの大変だけど、sphinx-apidoc というコマンドを使うと一瞬(このコマンド、公式ドキュメントでは見つけづらいので良くない)

(注:2017/04/10、いただいたフィードバックを元に翻訳を修正いたしました。)

はじめに

私はLinuxが大好きです。コンピュータとのやりとりが楽しくなるし学ぶことも多くなります。OSとハードウェアの基盤となる基本原則を学びたい人にとって、Linuxはとてもいい出発点と言えるでしょう。

ご存じのとおりLinuxとは大抵の場合プログラム(コマンド)を通してやりとりします。Linuxと他のUNIX系システムが持っている特徴は、コマンドラインと、パイプのコンセプトです。プログラムの提供する入力と出力を統合すれば、データを操作するのに非常にパワフルなプラットフォームになります。

Linuxのコマンド、プログラム、バイナリ(何と呼んでもいいのですが)の大部分は、/usr/bin、/usr/sbin/、/binそして/usr/local/binに存在しています。これらのディレクトリを見れば、プログラムがたくさん見つかるでしょう。それでふと、これらのバイナリが日々の仕事にどう関わってくるのかと考えました。それで、宝探しをしてみることに決め、発見をこのブログに投稿してみることにしました。

手始めに、私のマシンの/usr/binにある簡単なカウント機能で、データを参照してみます。

ablagoev ➜  ~  ls -la /usr/bin | wc -l 2420 

これはもちろん日々私が使っているシステムで、ここで多くのものを保管しています。Centos 6.8(X Serverなし)の標準サーバに少しだけソフトウェアを追加して稼働しています。

[root@XXXXXX ~]# ls -la /usr/bin | wc -l 1054 

半分になりましたが、まだずいぶん数が多いですね。日常業務ではおそらく平均して20コマンドくらいしか使いません。以下はzsh環境でチェックする簡単な方法です。

fc -li -146 | awk '{print $4}' | sort | uniq -c 

これで最新の146のコマンドが求められます。fcを使いタイムスタンプを参照し、今日の分だけのコマンドを抽出しました。

このデータを念頭に置いて、/usr/binやその周辺の内部を掘り下げ、隠された宝石がないかどうか調べてみることにしました。私はCentos 6.8の標準インストールをしているので、違うディストリビューションであれば違いがあるでしょう。

この投稿を書きながら各プログラムについて学びました。無知さ加減が目についたらご容赦ください。

目次

  1. Misc
  2. OS
  3. デバッグ
  4. データ操作

Misc

at

/bin/shを使用して、後で実行される標準入力または指定ファイルからコマンドを読み取る

いいですね。私はいつも単発のジョブを設定しようとしてcronの構文を間違ってしまいますが、こういったユースケースに対してはずっと簡単に使えそうです。例を挙げます。

root@XXXX:~# at 9:26 PM warning: commands will be executed using /bin/sh at> date > /tmp/test_at.log at>^D 

date > /tmp/test_at.logは同日の9:26p.m.に実行されます。保留中のジョブも参照可能です。

root@XXXX:~# atq 1   Wed Feb  8 21:26:00 2017 a root 

atはイカした日時の書式をいくつか理解しているようです。例えばお茶の時間(at teatime)も知っています。クールですね。

cal

ablagoev ➜  ~  cal    Февруари 2017 нд пн вт ср чт пт сб           1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 

今日の日付を反転表示して、しゃれたカレンダーを表示してくれます。個人的にはすごく便利だと思います。

mkfifo

これも便利です。mkfifoはシンプルなIPC(プロセス間通信)に使えます。この時生成されるnamed pipeは、Linuxでは通常そうであるように、ファイルです。つまりこのファイルに書き込むプロセス(writer)とこのファイルから読み込むプロセス(reader)が装備されています。下記の2つのPythonのスクリプトを参考にしてみてください。

#!/usr/bin/python  # reader.py  i = 0 while True:     fp = open('fifo', 'r')     line = fp.readline()     print "Item in fifo: " + line.rstrip() + " on iteration " + str(i) + "n"     fp.close     i += 1 #!/usr/bin/python  # writer.py import time  i = 0 while True:     fp = open('fifo', 'a')     fp.write("Hello " + str(i) + "!n")     fp.close()     i += 1     time.sleep(1) 

スクリプトを利用する前にFIFOを生成します。

mkfifo fifo 

writerを起動します。

./writer.py 

readerも起動します。

./reader.py 

readerがFIFOの内容を出力する出力レートに注目してください。writerと同期しています。FIFOが通常のファイルだとしたら、readerは新しいアイテムがあろうがなかろうが、常に読み込むはずです。FIFOに対する読み込みと書き込みはブロッキングオペレーションだからです。FIFOを通常のファイルに変更して違いを確認してみてください。

他にWikipediaのNetcatの項にもすばらしい例があります。

mkfifo backpipe nc -l 12345 0backpipe 

これはプロキシの例で、ポート12345のリクエストをすべてポート80のwww.google.comに転送します。パイプが単方向性なので、FIFOが必要となります。

resolveip

通常、ホストのIPアドレスを取得するのにはpingを使いますが、resolveipの方が簡単です。

ablagoev ➜  ~  resolveip en.wikipedia.org IP address of en.wikipedia.org is 91.198.174.192 

私と同類の人なら、しょっちゅうIPをコピーする必要にかられ、IPだけを返す-sオプションを使っているはずです。

resolveip -s en.wikipedia.org | xsel -b 

.bash_aliasesというファイルに保存するだけで、簡単に関数にできます。

# Copy an ip address from a domain # Usage cip domain.com function cip() {     ip=$(resolveip -s $1)     echo $ip | xsel -b     echo $ip } ablagoev ➜  ~  cip en.wikipedia.org 91.198.174.192 

timeout

時間制限をかけてコマンドを実行する

コードを編集したくない時に便利です。例を挙げます。

timeout 10 ./program 

プログラムは10秒間実行され、そのあとTERMシグナルが送られます。シグナルや、時間の単位(例えば分、時間、日)は変更できます。

w

誰がログインしていて何をしているのか表示する

マルチユーザのシステムでは便利です。

root ➜  /home/ablagoev  w ablagoev  12:20:44 up 1 day, 56 min,  5 users,  load average: 0,06, 0,13, 0,21  USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT  ablagoev :0       :0               сб11   ?xdm?   1:18m  0.59s upstart --user  ablagoev pts/4    :0               сб11   24:51m 46.01s 45.70s /home/ablagoev/.rbenv/versions/2.3.1/bin/jekyll serve  ablagoev pts/7    :0               сб23    4.00s  2.42s  4:04  gnome-terminal  ablagoev pts/25   :0               сб11   12.00s  3:10   3:10  vim _posts/2017-02-10-adventures-in-usr-bin.markdown  ablagoev pts/33   :0               сб12    1:35m  2.28s  4:04  gnome-terminal 

watch

watchはプログラムを定期的に実行したり出力を監視したりするのに便利なツールです。シンプルな時計は以下のようになります。

watch -n 1 -d date 

-nオプションはwatchにプログラムを毎秒実行するように命令します。-dオプションは出力の差異を強調するようwatchに指示します。

OS

blktrace

この項目についてはブログの投稿をすべて費やしてもいいほどですが、私は正直詳細まで記述できるほど準備ができていません。理解している範囲では、システムのI/Oをiostatよりも低レイヤーで監視することができ、I/O関連のメトリクスを多く測定することができるというものです。この件に関してはこれが優れた投稿だと思います。

これは新しいカーネルにのみ実装されています。古いものにはパッチを当てなくてはなりません。

chrt

システムに「niceness」を設定できることについてはご存じですよね。知らなかったのですが、CPUのスケジューリングポリシーも変更できます。現在、最新のカーネルは以下のポリシーをサポートしています。

  • SCHED_OTHERは標準的なラウンドロビンのタイムシェアリングポリシー
  • SCHED_BATCHはプロセスの「バッチ」処理の実行に
  • SCHED_FIFOは先入れ先出しポリシー(リアルタイムプロセスにのみ適応)
  • SCHED_RRはラウンドロビンポリシー(リアルタイムプロセスにのみ適応)

また、プロセスにはリアルタイムと標準の2種類があります。リアルタイムプロセスの方が優先度が高く、時間的な制約のあるアプリケーションに適用されます。

プロセスのポリシーを変更することで、Linuxがプロセスをスケジュールする方法を変更できます。

ユーザプロセスは通常リアルタイムではなく、デフォルトがSCHED_OTHERポリシーになっています。カーネルプロセスを調べてみたところ、SCHED_FIFOのものもありましたが、(少なくとも私のマシンには)SCHED_RRを持っているものはありませんでした。

chrtを使えばプロセスのスケジューリングポリシーの変更やクエリが可能です。例えば、initをチェックするには以下のようになります。

結果としてプロセスポリシーを以下のように変更することができます。

ablagoev ➜  ~  chrt -b -p 0 PID ablagoev ➜  ~  chrt -p PID pid 970's current scheduling policy: SCHED_BATCH pid 970's current scheduling priority: 0 

しかし、実用的なユースケースや本番環境のポリシーに干渉する意味も見つけることができません。こちらの投稿ではいくつかの評価基準が掘り下げられています。ぜひ、このポリシーに関する皆様の経験や知識を共有していただけると嬉しいです。

詳細は以下をお読みください。

man sched_setscheduler 

lstopo

これはかなりイケてます。マシン(のトポロジー)のハードウェアレイアウトの表示のために使用することができます。数多くの異なる出力フォーマットだけでなくASCIIアートにも対応しているところが最高です。以下に例を挙げています。

20170403

Istopoコマンドはhwlocパッケージで提供されます。

numactlおよびtaskset

これらのコマンドだけの投稿ができるほど話題につきません。私の知る限り、両コマンドはプロセスやスレッドのCPUアフィニティを制御するために使用されます。例えば、異なプロセスやスレッドを異なるコアやソケットに指定することが可能になります。さらに、プロセスやスレッドが使用するべきメモリノード(NUMA環境下でのバッファプール)を管理します。実際、Linuxスケジューラが最適ジョブを実行せず、スレッドや同様のプロセスをコア中に渡してしまう時に使用されています。始める前にまず、NUMAのアーキテクチャをおさらいしましょう。

[root@chat ~]# numactl -H available: 2 nodes (0-1) node 0 cpus: 0 1 2 3 8 9 10 11 node 0 size: 24566 MB node 0 free: 23075 MB node 1 cpus: 4 5 6 7 12 13 14 15 node 1 size: 24576 MB node 1 free: 23309 MB node distances: node   0   1   0:  10  21   1:  21  10 

上は2つのCPUソケットと計16コアを持つ48ギガビットのサーバです。メモリは2つのノードに分かれています。

numactlの簡単な例は以下のとおりです。

numactl --cpunodebind=0 ./program 

これで1つ目のCPUソケット(0)上のprogramを実行します。

プロセスのアフィニティを起動時に変更したい場合は、tasksetで実行できます。tasksetはソケットではなくコアで機能しますので、単体のソケットにプロセスを指定したい場合は、全てのコアを一覧にする必要があります。

taskset -p -c 0 pid 

-c 0を使用することで、PIDをコア#0に指定します。cat /proc/cpuinfoを使用すればコアを見ることができます。

さらに、プロセスの現在のCPUコアを見たい場合は、psのpsr列を見てください。

ablagoev ➜  ~  ps -o pid,psr,comm -p 1     PID PSR COMMAND     1   1 init 

つまり、この場合、initプロセスがコア#1になっていることが分かります。

numastat

プロセスやOSのノードメモリ統計をNUMA単位で表示する

[root@chat ~]# numastat                            node0           node1 numa_hit               502845176       522381709 numa_miss                      0               0 numa_foreign                   0               0 interleave_hit             22624           22649 local_node             502838421       522343368 other_node                  6755           38341 

たくさんのミス(プロセスの好むノードではないノードにメモリが割り当てられること)があるのは、システム上のどこかでアフィニティが最適ではないからと考えるのが論理的だと思います。

peekfd

このコマンドは既定のプロセスのI/Oを監視するために使うことができます。先に進める前にpeekfdのLinux Manページから以下の引用をご紹介します。

バグ 恐らく多く存在するでしょう。監視しているプロセスが異常終了しても驚かないように。

本番環境で使用する際は注意が必要です。どなたか安定性についてご存じの方は教えてください。いずれにせよ、保存時にvimの動作を監視します。

root ➜  /home/ablagoev  peekfd 20921  writing fd 1:  [1b] [?5h [1b] [?5l [1b] [?25l [1b] [m [1b] [57;1H [1b] [K [1b] [57;1H:w [1b] [?12l [1b] [?25h  [1b] [?25l"t" writing fd 5: Example IO writing fd 1:  [noeol] 1L, 10C written [1b] [1;14H [1b] [?12l [1b] [?25h writing fd 7: b0VIM 7.4 [10] 2 [a9] X [8a]  [14]  [16]  [b9] Qablagoevablagoev-VPCF22M1E~ablagoev/t [09] 3210#"!  [13]  [12] U 

ファイルに何が書き込まれるか見えるのがすごいです。もちろんstraceを使ったり出力のフィルタリングを行ったりしても同じことができます。

pidstat

このコマンドは、既定のプロセスやシステム全体のあらゆる統計を監視するために使うことができます。top/htopに似ていますが、更に詳しい情報を提供してくれます。例えば以下のような情報です。

[root@chat ~]# pidstat -p 19562 1 Linux 3.10.104-1.el6.elrepo.x86_64 (ldp3chat)   19.02.2017  _x86_64_    (16 CPU)  10,22,03          PID    %usr %system  %guest    %CPU   CPU  Command 10,22,04        19562   11,00    3,00    0,00   14,00    15  node 10,22,05        19562   10,00    1,00    0,00   11,00    10  node 10,22,06        19562   11,00    3,00    0,00   14,00    11  node 10,22,07        19562   16,00    2,00    0,00   18,00    10  node 10,22,08        19562   23,00    2,00    0,00   25,00    11  node 10,22,09        19562   16,00    1,00    0,00   17,00    14  node 10,22,10        19562   14,00    2,00    0,00   16,00    13  node 

最後の「1」は統計のポーリングを毎秒実行するようpidstatに指示します。-dオプションを使ってI/O統計を見ることができます。

[root@chat ~]# pidstat -d -p 19562 1 Linux 3.10.104-1.el6.elrepo.x86_64 (chat)   19.02.2017  _x86_64_    (16 CPU)  10,23,38          PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command 10,23,39        19562      0,00      0,00      0,00  node 10,23,40        19562      0,00      0,00      0,00  node 10,23,41        19562      0,00      0,00      0,00  node 10,23,42        19562      0,00      0,00      0,00  node 10,23,43        19562      0,00      0,00      0,00  node 

メモリは以下のとおりです。

[root@chat ~]# pidstat -r -p 19562 1 Linux 3.10.104-1.el6.elrepo.x86_64 (chat)   19.02.2017  _x86_64_    (16 CPU)  10,24,16          PID  minflt/s  majflt/s     VSZ    RSS   %MEM  Command 10,24,17        19562      2,00      0,00 1576132 524288   1,06  node 10,24,18        19562     36,00      0,00 1574416 522588   1,05  node 10,24,19        19562     47,00      0,00 1574416 522588   1,05  node 10,24,20        19562     70,00      0,00 1575440 522840   1,05  node 10,24,21        19562    186,00      0,00 1575440 523632   1,06  node 10,24,22        19562     30,00      0,00 1575440 523632   1,06  node 

タスク(コンテクスト)の切り替えは以下のとおりです。

[root@chat ~]# pidstat -w -p 19562 1 Linux 3.10.104-1.el6.elrepo.x86_64 (chat)   19.02.2017  _x86_64_    (16 CPU)  10,25,48          PID   cswch/s nvcswch/s  Command 10,25,49        19562    481,00     97,00  node 10,25,50        19562    359,00     64,00  node 10,25,51        19562    401,00     71,00  node 10,25,52        19562    383,00     63,00  node 

pwdx

このコマンドは、プロセスによって操作中のディレクトリを簡単に取得できる使い勝手のいいツールです。

ablagoev ➜  ~  pwdx 6038 6038: /home/ablagoev/workspace/ablagoev.github.io 

debugging

addr2line

このコマンドは使い方が少し難しいのですが、使うだけの価値はあります。低レイヤーのプログラミングをしている人は日常的に異なる場合において使っています。私はsegfaultのデバッグに便利だと思って使っています。

Segfaultは以下のような形式になっています。

php-fpm[6048]: segfault at 10 ip 00007f46db77a8fb sp 00007fffa155e2d0 error 4 in xcache.so[7f46db763000+23000] 

上の場合segfaultは共有ライブラリ(xcache.so)に出ています。ライブラリオフセット(xcache.so[7f46db763000+23000])を命令ポインタ(ip part)から減算してaddr2lineの正しいアドレスを算出する必要があります。

00007f46db77a8fb - 7f46db763000 = 178FB 

アドレスが分かったら、共有のオブジェクトの位置情報と一緒にaddr2lineに与えます。

addr2line -e /usr/lib64/20131226/xcache.so 178FB 

このマシンの場合の出力は以下のとおりになります。

/root/source/xcache-3.2.0/mod_cacher/xc_cacher.c:778 

これはsegfaultを生成するC言語ソースコードの違反行です。最高です。

前述のとおり、このコマンドも単独の記事が書けるほど奥が深いのです。例えば、機能させるには、デバッグシンボルの設定をONにしてバイナリをコンパイルする必要があります。さらに、アドレス計算の裏には面白い理論が存在します(私の読むべきものリストに含まれています)。また、他にもさらに踏み込んだデバッグ(gdb)をしてくれるツールがあります。

gstack

実行中のプロセスのスタックトレースを出力する

繰り返しになりますが、すごいです。暴走プロセスのスタックトレースを見ることができるということは、問題解明に絶対役立ちます。使い方はいたって簡単です。

gstack pid 

このコマンドはgdbのラッパです。そのため、ディストリビューションにない場合は、gdbで同じような効果が期待できます。

データ操作

column

このコマンドは素晴らしいのに今まで知りませんでした。列の書式入力に使うことができます。個人的に一番使い勝手がいいと思うのがCSVファイル形式です。とりわけすごいのは異なる列の区切り文字を指定することができることです。

id;event;count 1;test;10 2;test2;20 3;test3;30 

コマンドを実行します。

ablagoev ➜  ~  column -s ";" -t test id  event  count 1   test   10 2   test2  20 3   test3  30 

次のコマンドと組み合わせて使うとさらに面白くなります。

colrm

このコマンドは入力から列を削除する場合に使えます。個人的にはawkを使い慣れていますが、単純なユースケースにおいては、colrmの方が使いやすいようです。前のコマンドで得た結果を元に、このコマンドを実行して最初の列を削除することができます。

ablagoev ➜  ~  column -s ";" -t test | colrm 1 4 event  count test   10 test2  20 test3  30 

comm

分類済みの2つのファイルを行単位で比較する

commを使えば2つのファイルを比較して、片方のファイルにしか存在しない項目(行)の有無や両方のファイルに存在する行を確認することができます。例えば、以下のような2つファイルがあるとします。

ex1  Common line In both files Only in 1st file 
ex2  Common line In both files Only in 2nd file 

commを両方のファイルで実行することで、以下のような結果を得ることができます。

ablagoev ➜  ~  comm ex1 ex2         Common line         In both files Only in 1st file     Only in 2nd file 

列ごとに出力は分けられ、最初の列は最初のファイルのみに存在し、2つ目の列は2つ目のファイルのみに存在し、3つ目の列は両方のファイルに存在するといったように結果を表示します。ここでの注意点は、ファイルがアルファベット順に分類されている必要があるということです。そして、表示したい列を制御するオプションもあります。

csplit

このコマンドはsplit(ご存じない方は要チェックです)に似ていますが、csplitは大きいファイルを複数の小さいファイルに分割してくれます。splitとは異なり、csplitは正規表現で使うことができ、分割したファイルはそれぞれ異なる大きさにすることができます。以下の例を見てください(テキストファイル)。

Item: Shoes Price: 9.99 Quantity: 10 ---- Item: Dresses Price: 19.99 Quantity: 15 ---- Item: Socks Price: 1.99 Quantity: 30 

以下のコマンドを実行します。

csplit --suppress-matched data.txt '/^----$/' {*} 

結果、アイテムブロックのみを含む3つのファイルが表示されます。--suppress-matchedオプションはcsplitに共通の行は出力結果に表示しないよう指示します。{*}はcsplitにパターンマッチングを可能な限り実行するよう指示します。残念ながら、csplitは行単位で実行します。例えば、正規表現の複数行モードでは使えません。

cut

Cutはよく使われていますが、私はこれまで使ったことがありません。見た限りでは、とてもパワフルなツールのようです。colrm同様にcutコマンドはファイルの部分的(列)抽出を可能にしてくれますcolrmとは異なり、開始・終了オフセットの設定だけでなく、区切り文字を指定することもできます。これが、CSVファイルの強力な解析の実行を可能にしてくれます。例えば、以下のデータ(テキストファイル)があります。

id;name;count 1;Shoes;10 2;Dresses;15 3;Socks;30 

上でcutを実行すると以下のようになります。

ablagoev ➜  ~  cut -d';' -f1 data.txt id 1 2 3 

-dオプションで区切り文字を指定します(ここでは、「;」になります)。-fオプションで出力したい列の指定をします。列1と列3を出力したい場合は、以下のようになります。

ablagoev ➜  ~  cut -d';' -f1,3 data.txt id;count 1;10 2;15 3;30 

この他にもコマンドに柔軟性を持たせるオプションはあります。ここであえて挙げるとしたら、出力する区切り文字を制御するオプションでしょう。例えば以下のとおりです。

ablagoev ➜  ~  cut -d';' -f1,3 --output-delimiter $'t' data.txt id  count 1   10 2   15 3   30 

–output-delimter $’t’はタブ文字を使うようcutに指示します。

join

これも人気のあるコマンドです。詳しくは知りませんが、何とか説明してみましょう。2つのファイルのデータを、共通フィールド単位で結合します。例えば以下の2つのファイルがあります。

ex1  Date Count 2017-02-02 10 2017-02-03 10 2017-02-04 10 
ex2  Date Sum 2017-02-02 50 2017-02-03 60 2017-02-04 70 

joinを実行すると結果は以下のようになります。

ablagoev ➜  ~  join ex1 ex2 Date Count Sum 2017-02-02 10 50 2017-02-03 10 60 2017-02-04 10 70 

最初の列に基づいてファイルを結合することができました。このコマンドは両方のファイルでどの列を使うか、区切り文字に何を指定する(デフォルト設定は空白)かなどを柔軟に選ばせてくれます。

paste

Pasteは複数のファイルを連結したい場合に使用できます。最も簡単なケースとしては、ファイルの中の全ての行を連結したい場合に使えます。以下のファイル(データ)を例に見てみましょう。

1 2 3 4 5 6 7 8 9 10 

コマンドを実行します。

ablagoev ➜  ~  paste -s -d ',' data 1,2,3,4,5,6,7,8,9,10 

-d オプションによって区切り文字が指定され、-sオプションによってファイルの行を連結されます。ここで-sオプションの表現方法と単一ファイルでは機能しない理由が理解できていません。

-sは各ファイルからの行単位の集約ではなく、ファイル単位の集約する

恐らく-sを実行しなければ、行単位で処理が実行されるのでしょう。

ファイル結合の別の例を見てみましょう。以下のファイル(ex1とex2)があります。

Name Shoes Skirs Socks Dresses 
Quantity 10 20 30 40 
ablagoev ➜  ~  paste ex1 ex2 Name    Quantity Shoes   10 Skirs   20 Socks   30 Dresses 40 

もちろん最初に挙げた例のように区切り文字を指定することもできます。

replace

このコマンドをさえ知っていれば、簡単な検索や置換を実行するためにsedコマンドの構文を暗記する必要がなかったのにと思います。このコマンドはファイルの文字列の置き換えに使えます。以下のファイル(データ)を例として見てみましょう。

variable = 10 operation = variable + 12 print variable 

replaceを実行して「variable」を「x」に置き換えます。

ablagoev ➜  ~  replace variable x -- data data converted ablagoev ➜  ~  cat data x = 10 operation = x + 12 print x 

速くて簡単です。複数の検索や置換を同時に実行することも複数のファイルで実行することもできます。

look

このコマンドは貴重です。ファイルの各行のうち、指定された文字列で始まっている行を表示します。基本的にはgrep “^PREFIX”と同じことをしてくれますが、正規構文なしで実行してくれます。以下のファイル(データ)で見てみましょう。

pref: 123 some other thing pref: 234 another thing pref: 222 
ablagoev ➜  ~  look pref data pref: 123 pref: 234 pref: 222 

Manページでlookをスペルチェックに使用する面白いユースケースが紹介されています。恐らく/usr/share/dict/wordsに英語辞典があり、lookコマンドでスペルチェックするようデフォルト設定されているのでしょう。以下のようになります。

ablagoev ➜  ~  look defini defining definite definitely definiteness definiteness's definition definition's definitions definitive definitively 

nl

とても便利なちょっとしたツールです。ファイルに行番号を追加してくれます。以下のファイル(データ)があります。

This is the first line. This is the second line. This is the third line. 

上のファイルでnlを実行します。

ablagoev ➜  ~  nl data      1  This is the first line.      2  This is the second line.      3  This is the third line. 

tac

Catのようなコマンドですが、ファイルを逆順に出力してくれます。

ablagoev ➜  ~  cat data 1 2 3 4 5 6 
ablagoev ➜  ~  tac data 6 5 4 3 2 1 

expand

これは簡単なコマンドですが便利です。タブをスペースに変換してくれます。

unexpand

上のコマンドとは反対のことをします。スペースをタブに変換してくれます。

おわりに

以上で終わりです。この投稿を書きながら多くのことを学ぶことができ、さらにLinux愛が深まりました。システムの透明性や詳細を提供してくれていることに感嘆します。他にもすごいコマンドを知っている方はぜひ下のコメント欄で共有してください。ここで挙げたコマンドの多くは初めて見るものもあったので、誤りがあるかもしれません。もしあるようでしたらぜひご指摘ください。

  • コメント

    1. 匿名希望
      2017/04/21(金) 22:36:25

      gzファイルのヘッダーに更新時刻があるのでhardlinkでディスク節約バックアップができない。書き出した後にまた開いてヘッダー書き換えるか、そもそもヘッダー無しのデータを書き出すか。後者はPerlIO::gzipで簡単にできるがgzipコマンドで読めないファイルになる。

    2. 匿名希望
      2017/04/21(金) 22:36:25

      ddコマンドは、ファイルシステムの種類などに関係なく、デバイスに対して入出力を行える。
      #lpic

    3. 匿名希望
      2017/04/21(金) 22:36:25

      そう言えばLinuxにはteeコマンドがあるけど、標準入力を標準出力とファイルの両方にリダイレクトするものだ。これが結構便利で、C++内でも使えるようにios_baseで書いてやった。すごい簡単です。両方出力すればいいだけだから。そして見た目は一箇所に出力してるように見える。

    4. 匿名希望
      2017/04/21(金) 22:36:25

      *.zipファイルがあったらunzipするような手順を作りたいんだけど、コマンドどうすっかな…

    5. 匿名希望
      2017/04/21(金) 22:36:25

      rpmコマンドの-qlオプションにpを付加すると、引数に指定した未インストールパッケージ(拡張子が.rpmのパッケージファイル名。パッケージ名ではないことに注意)がインストール時に展開するファイル一覧を表示できる。
      #lpic

    記事に戻る

関連記事