teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

exec について解説

2018/01/29 05:18

投稿

mit0223
mit0223

スコア3401

answer CHANGED
@@ -41,4 +41,38 @@
41
41
  Domain_name=$(read_ans)
42
42
 
43
43
  echo $Clone_url,$Project_name,$Domain_name
44
- ```
44
+ ```
45
+ ---
46
+ 1行目の ```exec {console}>&1``` はシェルスクリプトでも凝った書き方(あまり見ませんし、周りで多少シェルスクリプトに詳しい人でも知らないことが多い)です。ちょっと長くなりますが、解説してみます。
47
+ 通常、exec は別のコマンドをプロセスをfork せずに実行する場合に使用します。例えば、```exec ls```と書けば ls コマンドが実行されます。しかし、コマンドを指定しなかった場合、シェルは何もしません。例えば、
48
+ ```shell
49
+ exec
50
+ ```
51
+ と一行だけ書いて bash で実行しても何もしません。それで、この何もしないことを利用して、自分自身のプロセスのファイルディスクリプタをオープンしたり、クローズしたりするときなどに使います。例えば、flock というコマンドはファイルディスクリプタの番号を引数に取ってファイルをロックしますが、このファイルディスクリプタの取得にも使えます。以下は /var/hoge.lock というファイルをロックする例です。
52
+ ```shell
53
+ # ファイルを追加書き込みモードでオープンしてそのファイルディスクリプタ番号を $lockfd に保持
54
+ exec {lockfd}>>/var/hoge.lock
55
+ # ロックを取得
56
+ flock $lockfd
57
+ # 独占した処理
58
+ ...
59
+ # ロック開放
60
+ flock -u $lockfd
61
+ # ファイルをクローズ
62
+ exec {lockfd}>&-
63
+ ```
64
+ 最後の exec もファイルをクローズするときにこのように書きます。回答のシェルスクリプトではクローズしてませんが、丁寧に書くのであれば、```exec {console}>&-```を書くと良いでしょう。
65
+ 次に```{console}```についてですが、これはbash に空いているファイルディスクリプタ番号を選んでもらって変数に入れてもらうときの書き方です。実際にファイルディスクリプタ番号に何が入るかというと10以上で最初に開いている番号が割り当てられるので、回答に示したシェルスクリプトでは 10 が入ります。試しに
66
+ ```shell
67
+ exec {console}>&1
68
+ echo $console
69
+ ```
70
+ というのを実行すると 10 が印字されると思います。短いシェルスクリプトであれば、変数を使わずにほぼ開いてることが確定している9というような番号を使うこともあります。回答例のシェルスクリプトでも
71
+ ```shell
72
+ # 標準出力のファイルディスクリプタを9に複製
73
+ exec 9>&1
74
+ # 中略
75
+ echo "It is not yet input." >& 9
76
+ # 後略
77
+ ```
78
+ と書いても動作します。