UNIXやLinuxのコマンドに関する世界観(応用1.ユーザープログラム)です。
自分の書いたブログ「神々とともに生きる詩人」2021/01/27より。
プロセスは、シェルと呼ばれるプロンプトからコマンドで実行することが多いが、この時&をつけることで、バックグラウンドで実行できる。
また、パイプとリダイレクトを用いることで、あるコマンドの出力を別のコマンドに渡したり、標準入出力をファイルと変換することができ、特にgrep, find, xargs, sed, awkあるいはUNIXのさまざまなフィルターコマンドは、このパイプとリダイレクトを用いて、「複数のコマンドを組み合わせてひとつの作業をする」ことが一般的である。
grep、sed、awk、find、Bashのさまざまな機能も参照のこと。
「シェル芸」とは、BashやUNIXのフィルタコマンドの機能を使って、一行のコマンドで効果的な処理を実行すること。
以下はシステムにある100MB以上のファイルやフォルダをソートして一覧表示する。
$ sudo du -x -m -d 5 / | awk '$1 >= 100 { print }' | sort -n -r | less
以下のページが参考になります。
シェル芸をもっと知りたい、シェル芸を使いこなしたいあなたのために、ツイッターに専用のbotがあります。
UNIXのフィルタコマンドを使ったシェル芸の例については以下のようなサイトを参照のこと。
以下の「Bash-Oneliner」では、Bashを使ったワンライナーのテクニックが数多く紹介されており、シンプルな解説が付属しているため参考になります。
2023.01.09編集
文字列のパターンによるマッチングと置換に使う、正規表現について。
僕はWindowsのxyzzyと言うテキストエディタから使うことが多いですが、Linux(特にsedやPerl)でも使うことが出来ます。
基本的な正規表現については、正規表現の世界観にまとめています。
catは、ファイルやストリームを表示する。
$ cat hoge.txt Assy Zaidou Schwarz
2024.02.08編集
echoは、文字列や変数の値を表示する。
$ echo $PATH /usr/local/bin:/usr/bin:/bin
2024.02.08編集
trは、テキストファイル内の文字を置換する。trコマンドは、複数の置換をまとめて記述できるのが特徴で、たとえばa-zをA-Zにすることができる(全ての小文字が大文字に置換される)。これに対して、sedのようなストリームエディタでは、正規表現を用いたパターンマッチングの置換ができる。
cutは、各行から指定した範囲を切り出すコマンド。テキストファイル内で特定の列を取り出す。空白によって分けられた文章を分割したりすることもできる。
pasteは、複数ファイルの行をマージする。テキストファイルを列方向に結合する。
$ cat hoge1.txt 1 2 3 $ cat hoge2.txt Assy Zaidou Schwarz $ paste hoge1.txt hoge2.txt 1 Assy 2 Zaidou 3 Schwarz
結合する文字を変えたい場合は-dオプションを使う(デフォルトではタブ)。
2024.02.08編集
テキストをソート(並べ替え)してくれる。
sortはパイプで使われることが多く、またviなどで使うととても強力である。headコマンドで先頭の行だけを取り出すこともできる。
$ cat hoge.txt Assy Zaidou Schwarz $ sort hoge.txt Assy Schwarz Zaidou
viも参照のこと。
2024.02.08編集
重複した行をひとつにまとめてくれる。
sortやwcと同様に、パイプで使うことが多い。
使えるオプションは-c。重複した行の出現回数をカウントしてくれる。sortとともに使うと以下のようになる。
$ cat hogelist.txt Assy Schwarz Assy Zaidou $ sort hogelist.txt | uniq -c 2 Assy 1 Schwarz 1 Zaidou
2024.02.08編集
2つの入力ファイルから共通するフィールド(項目)を結合する。
たとえば、
$ cat names.txt 1 Assy 2 Schwarz $ cat scores.txt 1 150 2 250 $ join names.txt scores.txt 1 Assy 150 2 Schwarz 250
となる。SQLにおけるJOINと同様のものであると考えればいいかも。
文字数や行数を数えてくれる。特に行数を数えてスクリプト処理を通して出力したりするのに使える。
$ cat hoge.txt Assy Zaidou Schwarz $ cat hoge.txt | wc -l 3
2024.02.08編集
headはテキストファイルの先頭部分、tailはテキストファイルの末尾の部分を表示する。パイプを使って、ストリームの最初の方や最後の方だけを表示する時に使うことが多い(たとえば、ソートして上から10行表示する)。
$ tail -n 30 /var/log/syslog
あるいは、nlコマンドとの併用で、
$ nl hoge.txt | tail -n 10
2024.02.08編集
splitはバイト単位・行単位で、csplitは任意の文字列でファイルを分割することの出来るコマンド。
Linux diffとpatch・テキスト処理を参照のこと。
ファイルを内容の詳細まで比較したり、その変更(パッチ)を適用できるコマンド。
Linux diffとpatch・テキスト処理を参照のこと。
revは各行の文字を逆に並べ替える。そのままtacに送ればファイルの行末から表示できる。
$ cat hoge.txt | rev | tac
seqは連続した数値の列や、一定間隔おきの数値の列を作成するコマンド。パイプと組み合わせて使うことが多く、シェル芸に活用できる。
$ seq 3 1 2 3
後日注記:-fオプションを指定すると、フォーマットとして数値と一緒に表示する文字列や数値の表示形式などを指定できる。書式はprintfと同じで、整数を意味する%gで数値の入る場所を指定できる。
$ seq -f "%g.html" 3 1.html 2.html 3.html
2023.08.23編集
nlは行番号をつける。僕は昔joinコマンドと一緒に使うことでHTMLの整形に使ったことがあるが、そのような場合はpasteコマンドを使っても良い。
$ cat hoge.txt Assy Zaidou Schwarz $ nl hoge.txt 1 Assy 2 Zaidou 3 Schwarz
2024.02.08編集
foldは指定した幅で改行する。幅は-wで指定する。-sオプションをつけると、単語の途中で改行せず、空白のある位置で改行してくれる。
$ fold -w 60 -s hoge.txt
prは印刷用に整形してくれるコマンド。日付と時刻、ファイル名、ページ番号などをつけてくれる。
デフォルトでは、ヘッダ5行とフッタ3行を含めて1ページ66行となる。
$ pr hoge.txt
そのままプリンターに送りたいなら以下のようにする。
$ pr hoge.txt | lpr
Linuxプリンターも参照のこと。
2024.02.08編集
以下はその他のテキスト操作コマンド。
コマンド | 説明 |
---|---|
truncate | ファイルサイズの切り詰めを行うコマンド。 |
nkf/iconv | 文字コード処理を行うコマンド。 |
col | 改行コード処理を行うコマンド。 |
column | 表に整形するコマンド。 |
colrm | 桁の削除を行うコマンド。 |
expand | タブからスペースへの変換を行うコマンド。 |
unexpand | スペースからタブへの変換を行うコマンド。 |
shuf | ランダムに並べ替えを行うコマンド。 |
このほか、
コマンド | 説明 |
---|---|
tailf | リアルタイムに変化するログの追跡。 |
strings | 表示可能な文字の表示。 |
write/wall | 他のユーザにメッセージを送信。 |
などのコマンドがある。
詳しくは、以下の書籍を参照のこと。
2023.05.18編集
2024.08.24編集
2024.10.06編集
コマンドが大量の出力を吐く場合など、ストリームをスクロールして表示させたい時は、パイプでless(ページャ)に送るのが有用だ。
$ find /usr/src/linux | less
viは無駄に使える。もっと簡単なテキストエディタが欲しい時は、nanoを使うと良い。
viでは、:!commandでUNIXコマンドを実行できる。:1,10!sortなどとすれば、1~10行目をソートすることもできる。
viについてはviの世界観にまとめています。
viでは、先に書いたようにsortコマンドをコードブロックの中で実行できるが、このように、viでUNIXコマンドを実行することで、UNIXコマンドははじめて真価を発揮する。
lprはBSD系、lpはSystemV系の印刷コマンド。CUPSを設定した上で、どちらかのコマンドを使って印刷が行える。
Linuxプリンターも参照のこと。
シンタックスハイライトをしてくれるツール。
ctagsは、vimなどと一緒に使うことで、C言語の関数定義情報が入ったtagsファイルを作成し、tagsに基づいて関数定義がどこのファイルに入っているかを検出し、指定の関数定義を探し出すことができる。
ctagsを参照のこと。
コンパイルやインストールを一括で実行する。
makeを参照のこと。
scriptコマンドは、scriptを実行してからexitを実行するまでの端末の操作(全てのキータイプと出力)を記録する。
ファイル名を指定した場合はそのファイルに、指定しなかった場合はデフォルトではtypescriptというファイルに記録される。
teeコマンドは、パイプでコマンド出力の「写しを取る」。パイプで与えられた入力を出力しながらファイルに記録する。
DNF/Yum/Aptなどで、「どんなパッケージを(依存関係などを含めて)インストールしたかメモしたい」などといった状況で使える。
後日注記:scriptとteeは、UNIXの入出力やパイプの考え方を用いた、とても面白いコマンド。後述するexpectとともに使うと効果的である。
繰り返しコマンドを実行して出力結果を再描画する。
コマンドを繰り返し実行して、表示される出力結果を画面に再表示し続ける。オプションは「-n 秒数」で再表示する間隔を秒数で指定できる。デフォルトは2秒。
$ wget --background https://www.hogehoge.com/hoge.tar.gz $ watch -n 3 ls -l hoge.tar.gz (3秒ごとにhoge.tar.gzのファイルサイズの状況を表示し続ける)
(「[改訂第3版]Linuxコマンドポケットリファレンス」を参考に執筆・編集して引用しました。)
パイプによる処理の進歩状況を表示する。
パイプを単に使う場合、巨大なファイルを処理する際などに進歩状況を表示することができない。pvを間に通すことで、進歩状況を表示できる。
$ pv hoge.tar.gz | tar xzf - (進歩状況がプログレスバーで表示される)
(「[改訂第3版]Linuxコマンドポケットリファレンス」を参考に執筆・編集して引用しました。)
env/printenvは環境変数を表示・指定する。exportは環境変数と定義を有効にする。
プログラムとの対話やキーボード入力を自動化して実行する。
後日注記:expectは、すべての質問に自動的に答えてくれる、シェルスクリプトやサーバーなどでのコマンドライン操作を行う際に便利なコマンド。expectを使わなくても、一部のパッケージ管理系のコマンドでは、すべての質問に自動的にイエスと答えてくれる-yオプションがあることがある。
停止するまで「y」あるいは任意の文字列を表示する。
tarは複数のファイルを圧縮して1つのファイルにアーカイブすることができる。
Linux アーカイブ・同期・デバイス処理を参照のこと。
ディレクトリ間のファイルの同期を行う。
Linux アーカイブ・同期・デバイス処理を参照のこと。
gitは使える。
最近、僕もgitを使うようになりました。ローカルだけで使うのであっても、差分を見事に管理してくれます。また、GitHubを使うことで、別の場所で変更・編集したファイルを同期することも簡単です。僕はホームページのファイルの同期に使っています。
詳細はGitの世界観にあります。
ファイルを復元できないように削除する。重要な情報が書かれたファイルを削除するために使う。作業状況を表示するためには-vオプション。
$ shred -v hoge.txt
-zオプションを使うと、shred処理を隠すため、最後にゼロクリアする(nullデータで上書きする)。
fileコマンドを使うと、ファイルのファイル形式を確認できる。
$ file hoge.txt hoge.txt: ASCII text
odは、バイナリファイルなどを読む際に便利なコマンド。ファイルを8進数、16進数などにダンプして表示できる。
UNIXコマンド(応用2.プロセス)を参照のこと。
UNIXコマンド(応用3.ドキュメント)を参照のこと。
grep, find, sed, awkを参照のこと。
コマンドを知りたいだけなら詳しいWebサイトを見るのが良いとは思いますが、Linuxの仕組みを知りたいなら、一度LFS(日本語版)かGentoo Linuxをやるのが僕はおすすめです。
Cool, but obscure Unix tools | Hacker Newsにツール一覧があります。こんな感じで、Linuxには時代遅れな「古代のツール」がわんさかとつまっています。
Emacsの世界観を参照のこと。
viの世界観を参照のこと。
正規表現の世界観を参照のこと。
coreutilsのgitで基本的なコマンドのコードを読むことが出来ます。
端末を参照のこと。
LinuxのAPIについてはLinux システムコール・APIの世界観を参照のこと。具体的な関数が分かると、コマンドのソースコードの理解もしやすいです。
UNIXのコマンドで多用される仕組みとして、パイプがある。これは、「あるコマンドの出力を、別のコマンドの入力として、出力した内容をさらに加工する」ということができる。
僕は、これがGUIのワープロと良く似ていると思う。GUIのワープロでは、ひとつのドキュメントをさまざまな機能で加工し、目的の出力を得るが、これはパイプでストリームデータを加工し続け、磨きをかけていくのと同じだからである。
そう、僕はUNIXとGUIは共存できると思う。特にUNIXはプレーンテキストデータを好むが、viなどでUNIXコマンドを使うこともできる。
Rustで作られたLinuxコマンドが最近注目を浴びている。カラフルでオシャレ。
Rustも参照のこと。
UNIXのコマンドの特徴として、GUIのワープロよりも、パイプやシェルスクリプトを使った再利用や連携、自動化がしやすいということが言える。
確かに、GUIのワープロのほうがインタラクティブで、画面を見ながら操作できるが、たくさんのことを処理しなければならない時、マウスやキーボードを使っていちいち手動で行う必要がある。
UNIXのコマンドラインを使ったフィルタープログラムなら、一行で「シェル芸」を書くことで、自動的かつ連携してコマンドを再利用できる。
昔から、UNIXのコマンドラインはそのように賢い。特に、viでエディタから利用すれば、まるで「全能のテキストエディタ」のようになんでも簡単に実行することができる。
Linux From Scratch。参考になります。
git
man-pages
Emacs電子書棚さんのマニュアルはGNU関連のツールの使い方を知る上で非常に参考になります。
書籍