ファイルの読み取り、権限管理、AWK テキスト処理
コース内容#
目次#
- cd:作業ディレクトリの切り替え
- パラメータ省略:自分のホームに戻る、[PS] C 言語は省略パラメータをサポートしていないが、マクロで実現可能
- パラメータ~:自分のホームに戻る、[~ ユーザー名] の形式でそのユーザー名のホームを指定可能
- パラメータ -:前回のディレクトリに戻る、2 つの長いパスの相互切り替えに適している
- pwd
- -L 論理作業ディレクトリ
- -P 物理作業ディレクトリ【実際】
- 主にソフトリンクに現れる
- ln -s [接続するファイル] [ソフトリンクの位置 / または ソフトリンクの位置 / ソフトリンク名]
- 両者は同じ物理空間にあり、物理ディレクトリは一致する
- 【削除】ソフトリンク test がフォルダを指している場合
- [rm test] はこのリンクファイルのみ削除
- [rm -r test/] はリンクされたフォルダ内のすべての内容を削除、危険!
- この操作は test / がディレクトリではないと警告するが、test / 内はすでにきれい
- リンクがファイルであれば、元の内容には影響しない
- [PS] ハードリンクはディレクトリには使用できない
- mkdir
- -p 親ディレクトリを自動的に作成、多層ディレクトリを作成したいとき
- -m 権限を設定
- 例:mkdir -p -m 700 ./test/abc/x
- rmdir:rm で代替可能
- 絶対パス:ルートディレクトリ / から始まる
- 相対パス:現在のディレクトリ。または上層ディレクトリ.. から始まる
ファイルとディレクトリの管理#
- ls:ファイルとディレクトリ情報を表示
- cp:コピー
- -i ファイルが存在する場合、確認
- -r 再帰的
- -a = -pdr
- p ファイル属性を含めてコピー
- d リンクファイルをコピーし、その指向をコピーしない
- r 再帰的
- -u ソースファイルがターゲットファイルより新しい場合のみコピー、大容量バックアップに適している
- -s ソフトリンクとしてコピー;-l ハードリンクとしてコピー
- cp/mv 複数のファイルの場合、最後のものは必ずディレクトリでなければならない
- ⭐cp の実装ロジック
- ファイルを開く → ファイルを読む → ファイルを書く
- 【もし cp がパイプの場合】
- もう一方からデータを送信する必要があり、データを読み取って書き込む
- cp 後、コピー結果はパイプデータを保存する通常のファイルになる
- rm:削除
- -i インタラクティブモード、確認を求める
- -r 再帰的
- -f 強制
- mv:移動
- 本質的には cp + rm
- -i、-f、-u、cp と類似
- basename:ファイル名を取得;dirname:ディレクトリ名を取得
- ファイルの有無を判断しない
- basename /home/xxx/abc → abc
- dirname /home/xxx/abc → /home/xxx
- 一般的にシェルスクリプトで使用
- rename:cp、mv で代替可能
ファイル内容の確認#
- cat:順方向に連続読み取り [逆方向:tac]
- -A = -vET
- -v 一般には見えない記号を表示
- -E 改行記号を $ として表示 [vim での list、 nolist と同様]
- -T TAB を ^I として表示
- [PS] \0...stray エラーがある場合(他のコードをコピーしたとき)、-A を使って特殊文字を確認できる
- -b 行番号を表示;-n 空行も含めて行番号を表示
- -A = -vET
- nl:行番号を出力してファイルを表示
- オプション [オプションパラメータ]👈順序に注意
- -b [a/t] 行番号指定の方式 → 対応 [cat -n/cat -b]
- -n [ln/rn/rz] 行番号の表示方法
- -w [num] 行番号が占める桁数
- 一般的に特殊テキストに使用
- more、less、head、tail
- more と less の違い
- more は下にしかスクロールできず、検索にハイライトがない
- less はより柔軟で、上下にスクロールでき、検索にハイライトがある
- 21 - 40 行を取得:man ls | head -n 40 | tail -n -20 【尾を取り、頭を切り、sed でも実現可能】
- more と less の違い
- od バイナリ形式でファイル内容を表示、一時的には使用しない、具体的な操作はコース速記を参照
ファイルの時間変更と新規作成#
- 三つの時間
- mtime [modify]:変更時間【デフォルト表示】
- ctime [change]:権限変更時間
- atime [access]:アクセス時間(記録コストが高い)
- [PS] Mac には Linux と互換性のないより多くの時間タイプがある
- touch ファイル
- 主に時間を変更するために使用
- 存在しない場合、自動的に作成される
- 特殊な使い方は少ない、詳細はコース速記を参照
- [PS] ファイルの時間を戻すことができ、人に気づかれないようにすることができる
ファイルの隠し属性#
chattr [+/- オプション] で変更可能
- A:atime を変更しない [効率とディスク寿命を向上]
- S:同期書き込み
- IO の同期を指し、電源断で保存されないのを避ける [電源断後、メモリ内のデータは直接消失]
- a:データを追加することしかできない [ログ]
- 変更や削除はできず、sudo でも同様
- vim では変更できないが、変更 [sudo なし] で a 属性のないバックアップファイルが生成される
- i:削除、変更、リンクの作成ができない [デフォルトはハードリンク]、つまり【固定化】
- s:ファイル削除時、ディスクから直接削除
- 通常、ファイルを削除すると、ファイルと対応するディスク位置の関係が解除されるだけで、内容は実際にはディスクに残っている、C 言語の free () に似ている
- s 属性を追加すると、ファイルを削除する際にディスク内のデータがすべて 0 に置き換えられ、実際に書き込みが行われる
- ここでは一般的に機械式ハードディスクを指し、SSD はまた別の話
- 【lsattr】でファイルの隠し属性を確認
- [PS] ソフトリンクには隠し属性がないようだ
ファイルの特殊権限#
権限 | 権限プレースホルダー | 作用対象 | 効果 |
---|---|---|---|
set_uid | s | バイナリプログラムファイル、スクリプトではない | このプログラムを実行する際にプログラム所有者の権限を取得 |
set_gid | s | バイナリプログラムファイル、ディレクトリ | このディレクトリ内では、有効グループがディレクトリの所属グループになる |
sticky bit | t | ディレクトリ | このディレクトリ内では、ユーザーは自分が作成した内容のみを削除できる |
chmod [u/g/ 空 |+/-|s/t] で変更可能
- set_uid
- ⭐chmod u+s、所属ユーザー権限に対して
- 所属ユーザー権限の x の位置:存在する場合は s に、存在しない場合は S に変わる
- 例:他のユーザーが passwd コマンドでパスワードを変更
- 他のユーザーはパスワードを保存するファイル /etc/shadow に対して権限がない
- しかし passwd コマンドには s 権限があるため、他の実行権限を持つユーザーが実行するとプログラム所有者の権限を取得し、パスワードファイル /etc/shadow を変更できる
- set_gid
- ⭐chmod g+s、所属グループ権限に対して
- 所属グループ権限の x の位置:存在する場合は s に、存在しない場合は S に変わる
- このディレクトリ内で行うことはすべて【ディレクトリ所属グループ】の身分で行われる
- 一般的にはディレクトリに作用する
- バイナリプログラムファイルに対しては set_uid に似ているが、得られるのは【所属グループ】の権限
- 協力作業を便利にし、グループ単位でディレクトリ内のすべてのユーザーを管理
- sticky bit
- ⭐chmod +t、参考粘着ビット—— ウィキペディア
- 他のユーザー権限の x の位置:存在する場合は t に、存在しない場合は T に変わる
- 例:/tmp ディレクトリおよびその下のいくつかのディレクトリ
コマンドとファイルの検索#
- which:実行可能ファイルを探す
- PATH パス内を検索
- zsh では ls は ls --color=tty のエイリアスであり、第二のコマンドの ls によって複数のパスと誤認される
- which のオプションを確認し、which -p ls で ls の【パス検索】のみを行うことができる
- コマンド置換符の使用を学ぶ
- whereis:より多くのタイプのファイルを探し、特定のタイプを指定できる
- -b バイナリファイルのみを検索
- -m man マニュアル内のファイルのみを検索
- -s ソースファイルのみを検索
- -u その他のファイルを検索
- locate:あいまい検索
- -i 大文字と小文字を無視
- データベースに基づいており、リアルタイムで更新されない、[sudo] updatedb で即座に更新可能
find:高度な検索⭐#
【時間】
- -mtime、-ctime、-atime [単位は日]
- <--__+n___|__n__|__-n__|:
n日前 [nを含まない] | n日前の1日内 | n日内 [nを含む]
- 分単位で確認するには man マニュアルを参照:-mmin、-cmin、-amin
- <--__+n___|__n__|__-n__|:
- ⭐ファイルを作成すると、そのファイルと現在のディレクトリの mtime が変更される
- 各ディレクトリにはファイル表があり、そこにファイル名と inode が記録されている
- ディレクトリにファイルが追加されると、そのファイル表にもファイル名と inode が追加される
- したがって、現在のディレクトリの mtime も変わる
- ❗ ただし、ファイルを変更するだけの場合、理解しやすく、現在のディレクトリの mtime は変わらない
- -newer file ファイル時間を時間ノードとして使用
【ユーザー、ユーザーグループ】
- -user 指定したユーザー名
- ユーザー hz が 10 分以内にアクティブなプロセス ID 【PID】を探す
- プロセスファイルは /proc にあり、すべて仮想で、ファイル [ディレクトリ] のサイズは 0
- 応用:プロセスを殺す
- [PS] プロセス ID と inode は異なるもので、inode を殺すことはできない
- -uid、-gid、-group、nouser、nogroup の使用は - user と同様
【ファイル、ファイル権限】
- -name ファイル名を一致させる
- (... -o ...) 論理和、括弧は \ でエスケープし、両端に空白があることに注意
- xargs—— パラメータ置換、前に移動してコマンド置換符を使用する必要はない
- -size [+ 大きい - 小さい]
- 空のファイルを探すことができ、クリーンアップに使用するが、特殊なファイル [.py など] に注意
- -type
- 7 種類のファイルタイプ:f b c d l s p
- -perm 775/-775
- 後者は前者を含み、すなわち - 775 は 775、776、777 を含む
- -exec find に内蔵の実行ツール
- 書かれた c、cpp、sh コード行数を統計
- -exec— コマンドの開始
- {} —— find の結果
- ; —— コマンドの終了
➕AWK テキストデータ処理#
awk [-Ffv] 'BEGIN { commands } pattern { commands } END { commands } file'
-
よく使うオプション
- -F fs:区切り文字 fs を指定、文字または正規表現で、デフォルトはスペース
- -v var=value:外部変数 var を awk に渡す
- -f scriptfile:スクリプトファイル scriptfile から awk コマンドを読み込む
-
BEGIN {}:一度実行を開始
-
pattern {}:重点⭐
- awk が読み取る各行は一度実行される
- pattern 文が提供されていない場合、デフォルトで {print} が実行される
-
END {}:最後に一度実行
-
[PS]
- ファイル file からデータを読み取ることも、パイプ "|" でデータを渡すこともできる
- commands は C 言語の printf () のようなさまざまな言語の print 関数をサポート
-
例:最近のログインの総時間を統計
- まずデータを前処理
- awk を使用して必要な時間データを取得
- awk を使用して計算
- よく使う組み込み変数:$n、NF、NR
-
[PS]
- 参考文献 ——AWK プログラミング言語
- 強制的に暗記する必要はなく、その機能を知っていればよい
- 専門性が高く、実際には言語であり、独自の文法構造を持つ
- 多くの変種がある
追加知識#
- /var 下の run ディレクトリ:ls -al run/、ls -ald run/、ls -ald run
- 三者の結果は異なり、ls -ald run は ls -al run でも使用可能
- スラッシュ / の存在に注意
- PATH 変数はプロセス内にあり、SSH を切断して再接続すると、PATH 変数は元に戻る
- 厳密にはメモリ内にある
- パイプファイル [mkfifo で作成された] とパイプ [コマンド内の | ] の違い
- 本質的には違いはなく、一進一出、入力がなければブロックが発生する
- しかし、| は暗黙的にプロセスを作成し、データを処理して元のプロセスに戻す
- ⭐Linux におけるテキスト処理の基本単位:行
- cat、tac、scanf、printf
- 【ハードリンク】
- 一つのファイルに別名が追加され、別名を削除してもファイルには影響しない
- ハードリンクのある a、b ファイルに対して
- ls -i で inode [ファイルノード番号] を確認
- a、b の 2 つのファイルの inode が同じで、ファイル接続数が 2 であることがわかる
- chmod -R ...:再帰的に、ディレクトリとその下のすべてのファイルの権限を変更
- 圧縮の解凍:gzip/gunzip、tar -c 圧縮 /-x 解凍 /-v 冗長情報表示 /-z gzip 操作による
- tar は.gz ファイルを解凍できず、gunzip を使用する必要がある
- ⭐作成されたディレクトリのデフォルトサイズは 4096 Byte = 4K
- ディスクのブロックに対応し、ファイル表を保存している
- ❗ディレクトリサイズは 0 にはならず、/proc 下のサイズが 0 のディレクトリは仮想ファイルシステムに属し、実際のディレクトリではない
考察点#
- C のソースファイルがコンパイルされた a.out を使用して./a.out を実行する際、ここでの./ は何を意味するのか
- 特別な意味はなく、【現在のパス】を指し、相対パスで実行されている
- 絶対パスで実行することもできる
- ❓直接 a.out は?
- a.out はコマンドと見なされ、command not found のエラーが発生する
- デフォルトの文字に対して、システムはコマンドを実行することを前提としており、内蔵コマンドを探すか PATH パス内を探す
- コマンドとして扱われ、ファイルではなく、コマンドがより一般的であるため
- 出力リダイレクトの詳細
- 方法①:順番に出力される
- 方法②:同時に送信され、データが乱れる
- &1 = 1 号ファイル
- さらに、方法①には順序の要求がある
- このように、2 号ファイルは 1 号ファイルに出力されなかった
- ここでの順序には注意が必要で、xxx.log ファイルを先に開く必要がある!
- find でファイルが見つからない場合、再度 ls を実行すると錯覚を引き起こすことがある
- ls 空、つまり ls 現在のディレクトリ
ヒント#
- 【rm の危険な操作を避ける】
- スクリプトを定期的に [contab] 実行してコードを Github、Gitee にアップロード
- rm を mv にラップし、自分で定義したごみ箱にし、3 日を超えたファイルを定期的にクリーンアップするスクリプトを書く
- 【小技】シェルで少しのコードを入力し、上下キーを押すと以前に入力した一致するコードをマッチさせることができる
- [その他] 感嘆符!で始まる
- !mk 最近の履歴の中で一致するコマンドを直接入力
- !9812 history の 9812 行目を直接入力
- [その他] 感嘆符!で始まる
- 一般的に - r、-R は再帰を示し、自分で試すことができ、小文字が占有されている場合は大文字を使用する
- link はデフォルトでハードリンクを指す
- man マニュアルでパラメータを検索する際、"/-z," の後にカンマを追加すると、マッチ数が少なくなる
- $() はコマンド置換符 `` として使用できる