回答編集履歴

1

exec について解説

2018/01/29 05:18

投稿

mit0223
mit0223

スコア3401

test CHANGED
@@ -85,3 +85,71 @@
85
85
  echo $Clone_url,$Project_name,$Domain_name
86
86
 
87
87
  ```
88
+
89
+ ---
90
+
91
+ 1行目の ```exec {console}>&1``` はシェルスクリプトでも凝った書き方(あまり見ませんし、周りで多少シェルスクリプトに詳しい人でも知らないことが多い)です。ちょっと長くなりますが、解説してみます。
92
+
93
+ 通常、exec は別のコマンドをプロセスをfork せずに実行する場合に使用します。例えば、```exec ls```と書けば ls コマンドが実行されます。しかし、コマンドを指定しなかった場合、シェルは何もしません。例えば、
94
+
95
+ ```shell
96
+
97
+ exec
98
+
99
+ ```
100
+
101
+ と一行だけ書いて bash で実行しても何もしません。それで、この何もしないことを利用して、自分自身のプロセスのファイルディスクリプタをオープンしたり、クローズしたりするときなどに使います。例えば、flock というコマンドはファイルディスクリプタの番号を引数に取ってファイルをロックしますが、このファイルディスクリプタの取得にも使えます。以下は /var/hoge.lock というファイルをロックする例です。
102
+
103
+ ```shell
104
+
105
+ # ファイルを追加書き込みモードでオープンしてそのファイルディスクリプタ番号を $lockfd に保持
106
+
107
+ exec {lockfd}>>/var/hoge.lock
108
+
109
+ # ロックを取得
110
+
111
+ flock $lockfd
112
+
113
+ # 独占した処理
114
+
115
+ ...
116
+
117
+ # ロック開放
118
+
119
+ flock -u $lockfd
120
+
121
+ # ファイルをクローズ
122
+
123
+ exec {lockfd}>&-
124
+
125
+ ```
126
+
127
+ 最後の exec もファイルをクローズするときにこのように書きます。回答のシェルスクリプトではクローズしてませんが、丁寧に書くのであれば、```exec {console}>&-```を書くと良いでしょう。
128
+
129
+ 次に```{console}```についてですが、これはbash に空いているファイルディスクリプタ番号を選んでもらって変数に入れてもらうときの書き方です。実際にファイルディスクリプタ番号に何が入るかというと10以上で最初に開いている番号が割り当てられるので、回答に示したシェルスクリプトでは 10 が入ります。試しに
130
+
131
+ ```shell
132
+
133
+ exec {console}>&1
134
+
135
+ echo $console
136
+
137
+ ```
138
+
139
+ というのを実行すると 10 が印字されると思います。短いシェルスクリプトであれば、変数を使わずにほぼ開いてることが確定している9というような番号を使うこともあります。回答例のシェルスクリプトでも
140
+
141
+ ```shell
142
+
143
+ # 標準出力のファイルディスクリプタを9に複製
144
+
145
+ exec 9>&1
146
+
147
+ # 中略
148
+
149
+ echo "It is not yet input." >& 9
150
+
151
+ # 後略
152
+
153
+ ```
154
+
155
+ と書いても動作します。