最近改めてコンパイラなどの勉強をしており、その過程で知った「こりゃ知らんかったわ~」というシェルのコマンドや特殊変数、オプションなどを書き留めておきます。
中には恥ずかしながら「それ知らんかったんかい!」というのも含まれていますが、備忘録として残しておきます。
※Amazon Linux上のbashで確認
特殊変数 $?
直前のコマンドの終了ステータスを保持する変数。
$ echo 'Hello'; echo $?
Hello
0
$ cat nofile.txt; echo $?
cat: nofile.txt: そのようなファイルやディレクトリはありません
1
true, falseコマンド
true
コマンドは必ず終了ステータス0(成功)を返すコマンド、false
コマンドは必ず1(エラー)を返すコマンド。
$ true; echo $?
0
$ false; echo $?
1
あまり使いどころがないように思えますが、手元のMacでcat /etc/passwd
をすると、
sshd:*:75:75:sshd Privilege separation:/var/empty:/usr/bin/false
のようにログインシェルにfalse
コマンドが指定されており、
これはsshd
ユーザでログインしようとするとfalse
コマンドが実行されて結果ログインできない、というような使われ方をしています。
fileコマンド
ファイルの中身を良しなに解釈してくれて、情報を表示してくれるコマンド(説明が雑)。
$ file /bin/bash
/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.35, BuildID[sha1]=6d4bc8a9x214f83cdea6a8xfe639d4d560984cad, stripped
$ file hoge.txt
hoge.txt: UTF-8 Unicode text, with very long lines
unameコマンド
システムの情報を表示するコマンド。
オプションなしだとOSの名前だけ表示、-a
を指定すると全情報表示となります。
$ uname
Linux
$ uname -a
Linux ip-10-0-1-159 4.1.7-15.23.amzn1.x86_64 #1 SMP Mon Sep 14 23:20:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
hexdumpコマンド
ファイルの中身を16進数や8進数などの形式で表示してくれます。デフォルトは2バイト刻みの16進数4桁で表示されます。これでバイナリファイルも怖くない(?)
$ hexdump /bin/cat
0000000 457f 464c 0102 0001 0000 0000 0000 0000
...
000bb70 0001 0000 0000 0000 0000 0000 0000 0000
000bb80
objdumpコマンド
オブジェクトファイルを逆アセンブルしてくれるコマンド。
$ objdump -d /bin/cat
/bin/cat: ファイル形式 elf64-x86-64
セクション .init の逆アセンブル:
0000000000401540 <.init>:
401540: 48 83 ec 08 sub $0x8,%rsp
401544: 48 8b 05 9d 9a 20 00 mov 0x209a9d(%rip),%rax # 60afe8 <__sprintf_chk@plt+0x209618>
40154b: 48 85 c0 test %rax,%rax
40154e: 74 05 je 401555 <__uflow@plt-0x1b>
401550: e8 9b 02 00 00 callq 4017f0 <__gmon_start__@plt>
401555: 48 83 c4 08 add $0x8,%rsp
401559: c3 retq
セクション .plt の逆アセンブル:
...
readelfコマンド
ELFファイルの情報を表示してくれるコマンド。
wikipediaによるとELFとは
コンパイラが生成するオブジェクト、および、ライブラリとリンクされた実行ファイルのファイルフォーマット
とのことです。
オブジェクトファイルのシンボル一覧を表示するのに使う模様。
$ readelf -h /bin/cat
ELF ヘッダ:
マジック: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
クラス: ELF64
データ: 2 の補数、リトルエンディアン
バージョン: 1 (current)
OS/ABI: UNIX - System V
ABI バージョン: 0
型: EXEC (実行可能ファイル)
マシン: Advanced Micro Devices X86-64
バージョン: 0x1
エントリポイントアドレス: 0x4025f4
プログラムの開始ヘッダ: 64 (バイト)
セクションヘッダ始点: 46144 (バイト)
フラグ: 0x0
このヘッダのサイズ: 64 (バイト)
プログラムヘッダサイズ: 56 (バイト)
プログラムヘッダ数: 8
セクションヘッダ: 64 (バイト)
セクションヘッダサイズ: 29
セクションヘッダ文字列表索引: 28
サブシェル
()
でコマンドを囲うと、呼び出し元のシェルに影響を与えずに環境変数などの変更ができます。
$ HOGE=hoge
$ echo $HOGE
hoge
$ (HOGE=fuga; echo $HOGE); echo $HOGE
fuga # サブシェル内のHOGE
hoge # 親シェルのHOGE
おわりに
GNU開発ツールは偉大。