🐈

TIL : UNIXプログラミング環境 第1章

2025/02/17に公開
3

UNIXプログラミング環境 (1章)

TIL: Today I Learned の1タイトル目にはUNIXプログラミング環境という本を選択しました。

毎日学んだことを1章ずつ記事にしていきます。まぁ備忘録です。

プロフィールにある通り端くれのエンジニアで普段はpython等々を使用して分析など行なっているのですが、サービス開発してみたいという思いから、基礎の基礎から学び直そうとしている所存です。

といってもLinuxコマンドを触ったことがあるので、新たな学びを中心に記載します。網羅的に学びたい方はぜひ↓の書籍を!
UNIXプログラミング環境

1章 初心者のためのUNIX

who

$ who
(個人名)    console       1  9 07:10  
(個人名)    ttys001       2  8 17:39 

whoコマンドを実行した時の2列目、 ttyという文字は "teletype"の意味で、"terminal"と同じ意味!
日本語では端末みたいです。

stty

"set terminal options"の略語コマンド。

入力が2個ずつ表示されたり、Returnキーを押してもカーソルが次の行の最初のカラムに移動しなかったりする現象を治せるコマンド。

具体的な使い方は書かれていなかったが、コマンドをうっすら覚えておけば検索できますね。

tabがおかしくなった時は次のように

$ stty -tabs

文字の削除

PCだとバックスペースを押せば文字を削除できるが、できないシステムもあるとのこと。
それか古いシステムの話なのかな、、、? (有識者求む)

削除文字が用意されていて、それを元に打ち間違いなどを消す。

dateを打ちたかった場合、1行ごと消すには @

$ dadatetaa@  -- @マークがあるので、全て無視される
date     -- 新しい行ができるので、そこに打ち直す。

一文字消したい場合は #
システムによって違う可能性あり。

$ datee#

#を単に記号としてタイプしたい場合は\でエスケープする(macだとoption + ¥でタイプ可能)

面白い演習問題

コマンドの実行結果を予想する演習問題。

$ date\@

date@: not found

$ #date

単純にdateが実行できる

\#date

#が文字列となり、dateがコメントとして反応するため、結果は何も実行されない。

\\#date

二つ目の\が一つ目\によって無視され、#dateが実行されるが、そんなコマンドはないため
#date: not found

1.2 日々の利用 ファイルおよびよく使われるコマンド

ed でエディタが開ける。流石に今の時代に使う機会はなさそう。

$ ed
a # ファイルへ書き始めるためのa
now you type whatever you want  ##本文
. # テキストの追加を終える
w junk # junkというファイルに保存する(write junk) これをしないと変更が失われる。
 # ed junkをすると途中から復帰できる
(何文字書いたか教えてくれる)
q # 終了を意味するコマンド

ls コマンドのオプション

-t

(time)
最新のファイル名から順に表示される

$ ls -t

-l

(long)
詳細なファイル情報とともに表示される

$ ls -l

以下のように返ってくる

-rw-r--r--  1 (個人名) 39  2  9 22:34 junk

-rw-r--r--は権限のまとめ。

権限についてまとめた**

ls -l の結果に出てくる権限は以下のように読み下せる。

一文字目がファイル(-) or ディレクトリ(d)
それ以降3文字ずつ、ユーザの権限、所有者の権限、その他ユーザの権限が続き、計10項目で権限が示されている。

三文字の権限はrwxで表され、持っていない部分が-に置き換わる。

wを持っていない場合、 r-xになり、wしか持っていない場合は、-w-となる。( -w- )< ヘェ~

それぞれの権限の意味は、ファイルの場合とディレクトリの場合で少し違うが、
rはreadで読み取り権限、wはwriteで書き込み権限、xはexecuteで実行権限である。

ファイルの場合

権限名 できること
r ファイルを読み取ることが可能
w ファイルを変更することが可能
x ファイルを実行することが可能

ディレクトリの場合

権限名 できること
r ディレクトリ内のファイルを一覧表示出来る
w ディレクトリ内のファイルを作成、削除出来るか
x ディレクトリ内のファイルにアクセス出来るか。要はそのディレクトリにcdできるか

私は権限について、x > w > r の順で強い考えていたのですが、ディレクトリに関していうと作成、削除できる方が権限が強いイメージを持ちました。

理解度チェック
自身にread権限、所有者グループはw権限とx権限、その他グループはx権限のファイルはどう表記される?(存在しなさそうなファイルですね)

Answer

-r---wx--x

続く39は文字数、2 9と時間は日付で2月9日の実行時間。

最後にファイル名と続く。

catコマンド

ファイルの中身を表示するコマンド。
エディターコマンドより優れている点として、複数ファイルを同時に表示できる。

hoge.txtとfuga.txtにa と bcのみ記載されている場合

$ cat hoge.txt fuga.txt
a
bc

となる。

grepと組み合わせれば少し便利そう。

prコマンド

catと同様のことが行えるが、catよりもリッチで、多段組での表示やファイルごとの表示が可能である。

$ pr hoge.txt fuga.txt
hoge.txt (変更日)
a

(余白60行)
fuga.txt (変更日)
bc

並行で表示するにはオプションで -mをつける。
これいいかも

$pr -m hoge.txt fuga.txt
hoge.txt (変更日) fuga.txt (変更日)
a                   bc


(余白60行ほど)

多段組みをする場合、何段にするか数値をオプションで与える。

pr -3 hoge.txt fuga.txt

1ファイルが3段組になって、表示された下に、次のファイルが3段組で表示できる。

mv

移動するコマンド、フォルダを移動しなければリネームに使える

$ mv hoge.txt mv_test.txt
$ ls
mv_test.txt

cp コマンドとrmコマンド

基本だけなのでさらっと。

$ cp (コピーされるファイル名) (コピー後のファイル名)
rm (削除するファイル)

wcコマンド

ファイル内の文字数や行数を返すコマンド

$ wc (ファイル名)
8 46 283 (ファイル名) 

8行、46単語、283文字を意味する。

grepコマンド

頻出の重要コマンド
grep (ファイル名) (単語)
でファイルの中から単語の含まれる行を探す。

オプション -v
一致する単語のない行を探す。

sortコマンド

ファイルの行ごとにアルファベット順で並べる。

オプション一覧

オプション 機能
-r アルファベット降順 (z -> a)
-n 数値昇順
-nr 数値降順
-f 大文字と小文字を区別しない
+(数値) (数値) + 1番目のフィールドからソート開始

tailコマンド

ファイルの最後の10行を表示する。

-(数値)で行数を指定可能

$ tail -3 hoge.txt
a

cmpコマンド

中身が似たファイルの比較が行えるコマンド。
ただどの行数の何文字目が違うか教えてくれるだけである。

GPTに適当なポエムと、よく似たポエムを出力させ、比較してみました。
$ cat poem 
Morning of February 10th

The cold wind brushes my cheeks, On a winter morning, February 10th. Footsteps echo in the quiet town, A new day begins.

White breath dissolves into the sky, Light of hope shines through. Life sprouts from the frozen ground, Eagerly awaiting the arrival of spring.

Warmth lights up in my heart, Bonds with cherished ones. February 10th, this moment, The door to the future opens.

$cat new_poem
February 10th's Dawn

A crisp breeze whispers through the air, On a winter's dawn, February 10th. Silent streets awaken with gentle steps, A fresh day unfurls its wings.

Frosty breath mingles with the morning light, Hope's first rays pierce the sky. From the frozen earth, new life emerges, Anticipating spring's gentle embrace.

In my heart, a warmth ignites, Connections with loved ones grow strong. February 10th, this fleeting moment, Opens the gateway to tomorrow.

$ cmp poem new_poem
poem new_poem differ: char 58,line 2

違いのある行のみを教えてくれる。

diffコマンド

cmpよりさらに詳細な違いを可視化してくれるコマンド。

cmp同様にpoemを比較してみた。
$ cat poem
(省略,cmpのものと同じです)
$ diff poem new_poem
1c1
< Morning of February 10th
---
> February 10th's Dawn
3c3
< The cold wind brushes my cheeks, On a winter morning, February 10th. Footsteps echo in the quiet town, A new day begins.
---
> A crisp breeze whispers through the air, On a winter's dawn, February 10th. Silent streets awaken with gentle steps, A fresh day unfurls its wings.
5c5
< White breath dissolves into the sky, Light of hope shines through. Life sprouts from the frozen ground, Eagerly awaiting the arrival of spring.
---
> Frosty breath mingles with the morning light, Hope's first rays pierce the sky. From the frozen earth, new life emerges, Anticipating spring's gentle embrace.
7c7
< Warmth lights up in my heart, Bonds with cherished ones. February 10th, this moment, The door to the future opens.
---
> In my heart, a warmth ignites, Connections with loved ones grow strong. February 10th, this fleeting moment, Opens the gateway to tomorrow.

1c1や5c5と書かれているが、これは第一ファイルの1行めが第二ファイルの1行目に変わったに違いないという意味を持つ。以降は

< 第一ファイルの該当行
---
> 第二ファイルの該当行

と続いている。

1.3 ファイル操作

基礎的すぎたので、飛ばす。

cdやpwdなどの解説でした

1.4 シェル

そもそもシェルとは、「コマンド・インタープリタ」のことで、カーネルではない。
カーネルに命令を伝える役割を果たし、ユーザとカーネルの仲立ちをしている。

この利点は大きく三つ

  • ファイル名の短縮
    • プログラムを引数として、名前を1つのパターン位支持すると、その群を指定したことになる
  • 入出力の切り替え
    • 任意のプログラムの出力を端末の代わりにファイルに変更できる
    • 入力をファイルからおbeloの合うこともできる
  • 環境のパーソナル化
    • 自身専用のコマンドを定義できる

*の機能

ch1 ch1.1 ch1.2 ch1.3 ... のようなファイルがあったとき、

全てを出力するにはどうすれば良いか。 *を使うのである

$ pr ch*

こうすればchの後に任意の文字列が続くファイル全てを意味することになる。(カレントディレクトリ内)

ch1が先頭にあるものを指定したければ、

$ wc ch1.*

このようにpr専用のコマンドではなく、おおよそのコマンドで使用可能である。

様々な正規表現シェルパターン

[] で文字指定ができる。

$ pr ch[1234]*

こうするとch の後に 1,2,3,4が続き、そのあとは任意文字列のファイルを指定して出力できる。
つまりこの場合 ch5.1やch6は出力されないが、ch4やch3.11などは出力される。

範囲指定も可能

$ pr ch[1-37-9]*

1-2と7-9を出力できる。

英字も可能

$ pr temp[a-z]

tempa ~ tempzまでを出力する。

? は1文字だけ指定

$ ls ?

一文字のファイル名を表示

入出力の切り替え

<> の記号で入出力を切り替えられる。

出力

> で出力先を指定できる。

$ ls >filelist
$ cat f1 f2 f3 >>tmp

>> の場合、追記モードとなり、> の場合はファイルを上書きする。

どちらもファイルがない場合は作成してくれる。

入力

逆向きの記号(<)で入力できる。

$ sort <temp

tempファイルの並び替えが行える。

応用

特定の誰かがLinuxシステムにログインしているかみたい場合は、

$ who >temp
$ grep mary <temp

whoの実行結果をtempに保存し、grepコマンドへtempファイルを入力する。

パイプ

前項の最後の部分は、実行結果をファイルに出力し、ファイルを入力していたが、これはパイプ | で可能になので、不要なファイルを作成せずに済む。

$ who | grep mary

セミコロン

実行結果を渡したいわけではないが、二つ以上のコマンドを実行させたい場合は、 ;で区切る。

$ date; who

バックグラウンド実行

実行時間が長いコマンドを実行している間に別の作業をしたい場合があるときは、&を最後につけると別の作用ができる。

$ wc ch* >wc.out &
4647

返ってきた結果は wcの結果ではなく プロセスidが返ってきている。

プロセスidを指定することで、そのコマンドを止めたり、結果を確認したりできる。

コマンドを止めたい場合は、

$ kill 4647

プロセスIDは記録しておかなくても、ps コマンドで確認できる

$ ps -ag

-ag とは現在実行中の全てのプロセスを表示する。

ただ端末をOFFにしてしまうと &で実行したプロセスも止まってしまう。

端末がOFFになっても実行させておきたい場合は、 nohupコマンドを使う(no hungupコマンド)

$ nohup *command* &

実行結果は全て nohup.outに保存される。

資源をたくさん使ってしまうコマンドを使う場合は、優先度を下げて実行させることもできる。他のユーザへの配慮が可能なのだ。

$ nice *command* &

時間指定

$ at 3am *command*

930amや2130などで時間を指定できる。

この場合、動かしたいスクリプトをファイルに書いておくのが良いと思いました。

$ at 12:00 <lunch_time_run
$ cat lunch_time_run
whatever
you'd like to run commands
at lunch time 

のようにですね。

締め

章単位だと記事が長くなりすぎると反省しています。
次から節単位で一本にします。

TILをとりあえずは進めていきますが、いつかはいいねをいっぱいもらえる、いい感じの学びがある記事を書きたいです。

千里の道も一歩から

Discussion

ko1nksmko1nksm

PCだとバックスペースを押せば文字を削除できるが、できないシステムもあるとのこと。
それか古いシステムの話なのかな、、、?(有識者求む)

昔のシステムの話です。
実行例の日時にある1983年当時の話です。

現在の @ マークや # に文字を削除するという意味はありません。
昔のビデオ端末ではないテレタイプは紙に文字を印字しており、入力した文字を消去できませんでした。
その時代の削除方法です。したがって「面白い演習問題」の内容は現在には当てはまりません。

$ pr ch[1234]*

これは正規表現ではなく、シェルパターンです。

端くれエンジニア端くれエンジニア

コメントありがとうございます!

昔のシステムの話です。

歴史を学ぶ意味も込めて書籍は古くても気にしていませんでしたが、やはり現行と違うと学ぶのが少し難しいと感じている次第です。

これは正規表現ではなく、シェルパターンです。

一緒くたに考えてしまっていました、訂正ありがとうございます!