回答編集履歴
4
2020/02/24 19:56 ソースコードの再アップに伴いコメントも記載修正。
test
CHANGED
@@ -22,30 +22,50 @@
|
|
22
22
|
|
23
23
|
|
24
24
|
|
25
|
-
otn様より頂いた記法がシンプルかつ確実でしたので、使用させて頂きました。
|
25
|
+
~~otn様より頂いた記法がシンプルかつ確実でしたので、使用させて頂きました。~~
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
-
個人的な思いとしては
|
29
|
+
~~個人的な思いとしては
|
30
30
|
|
31
31
|
・エラーならとりあえずcatchして独自エラーを吐き、処理をメインに戻す。
|
32
32
|
|
33
|
-
・継続させたい場合もあるので、終了処理はメイン処理の中で判断して記載する。
|
33
|
+
・継続させたい場合もあるので、終了処理はメイン処理の中で判断して記載する。~~
|
34
|
-
|
34
|
+
|
35
|
-
・なるべくメインシェルには共通関数導入による記法制限をかけたくない。
|
35
|
+
~~・なるべくメインシェルには共通関数導入による記法制限をかけたくない。
|
36
36
|
|
37
37
|
というところがありまして、出来れば「set -E」はつけたくない思いがありました。
|
38
38
|
|
39
|
-
|
39
|
+
~~
|
40
|
-
|
40
|
+
|
41
|
-
エラーでも継続させたい場合は「||」で繋げて独自エラー関数を呼び出すような仕組みにしてみました。(これが制約となってしまいましたが・・・)
|
41
|
+
~~エラーでも継続させたい場合は「||」で繋げて独自エラー関数を呼び出すような仕組みにしてみました。(これが制約となってしまいましたが・・・)
|
42
|
+
|
42
|
-
|
43
|
+
~~
|
44
|
+
|
45
|
+
|
46
|
+
|
43
|
-
|
47
|
+
2020/02/24 19:56 : 記載修正、シェル再アップ
|
48
|
+
|
49
|
+
otn様とやりとりを重ねた結果、当初と実装手法がことなりましたので最終版をアップしました。
|
44
50
|
|
45
51
|
とても助かりました!ありがとうございました!
|
46
52
|
|
47
53
|
|
48
54
|
|
55
|
+
・「set -E」でサブシェル内の処理までERRトラップが行われる。
|
56
|
+
|
57
|
+
※「set -e」とは異なり、エラー終了はされない。
|
58
|
+
|
59
|
+
・上記注釈記載により「||」による実装制約は解消。ただし、コマンドエラーの結果はcatch()で処理するようにしているため、実装処理では一律$RCでステータスコードを取る制約とする。
|
60
|
+
|
61
|
+
・サブシェルでERRトラップした場合、親シェルでもう一度ERRトラップが走ってしまい、余計なメッセージが出力されてしまう為、catch()内で「サブシェル→親シェル」に戻ったかを判定する処理を実装。(サブシェルでセットした変数の値は親シェルに引き継がれない為、ファイルで管理)
|
62
|
+
|
63
|
+
・パイプラインのエラーに対応する為、「set -o pipefail」を追加。
|
64
|
+
|
65
|
+
・シェルを共通関数「cmn_func.sh」と実装シェル「main_shell.sh」に分離。
|
66
|
+
|
67
|
+
|
68
|
+
|
49
69
|
**■ cmn_func.sh**
|
50
70
|
|
51
71
|
```ここに言語を入力
|
3
2020/02/24 19:45 サブシェル対応およびpipelineを想定した現時点のソースに再修正致しました。
test
CHANGED
@@ -52,35 +52,79 @@
|
|
52
52
|
|
53
53
|
#!/bin/bash
|
54
54
|
|
55
|
-
set -E
|
55
|
+
set -E -o pipefail
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
#### 初期化処理
|
60
|
+
|
61
|
+
RC=0
|
62
|
+
|
63
|
+
echo 0 > SUBSHELL
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
#### 処理開始メッセージ
|
68
|
+
|
69
|
+
Msg="============ Script(${BASH_SOURCE[1]}) be in started. =>=>=>=>"
|
70
|
+
|
71
|
+
echo -e ${Msg}
|
56
72
|
|
57
73
|
|
58
74
|
|
59
75
|
#### 各種トラップおよび独自メッセージ定義
|
60
76
|
|
61
|
-
trap 'catch
|
77
|
+
trap 'catch "${BASH_COMMAND}"' ERR
|
62
78
|
|
63
79
|
function catch(){
|
64
80
|
|
65
81
|
RC=(${PIPESTATUS[@]})
|
66
82
|
|
83
|
+
|
84
|
+
|
85
|
+
## サブシェル対応(現時点が親シェルの場合、サブシェルから復帰しているか確認)
|
86
|
+
|
87
|
+
if [ $BASH_SUBSHELL -eq 0 -a `cat SUBSHELL` -ne 0 ] ; then
|
88
|
+
|
89
|
+
echo $BASH_SUBSHELL > SUBSHELL
|
90
|
+
|
67
|
-
|
91
|
+
return 0
|
92
|
+
|
68
|
-
|
93
|
+
fi
|
94
|
+
|
95
|
+
|
96
|
+
|
69
|
-
A_SrcCode=$
|
97
|
+
A_SrcCode=$1
|
98
|
+
|
99
|
+
L_LineNo=$BASH_LINENO
|
70
100
|
|
71
101
|
L_ExecCMD=`eval "echo $A_SrcCode"`
|
72
102
|
|
103
|
+
Msg=
|
104
|
+
|
73
|
-
Msg=">>>> Script Error Occurred! ($0):
|
105
|
+
Msg+=">>>> Script Error Occurred! ($0:$$): \n"
|
74
|
-
|
106
|
+
|
75
|
-
|
107
|
+
Msg+="SorceFile: ${BASH_SOURCE[1]} \n"
|
76
|
-
|
108
|
+
|
77
|
-
|
109
|
+
Msg+="LineNo(${FUNCNAME[1]}): $L_LineNo \n"
|
110
|
+
|
78
|
-
|
111
|
+
if [ ${#RC[@]} -eq 1 ] ; then
|
112
|
+
|
79
|
-
|
113
|
+
Msg+="Sorce_Code: $A_SrcCode \n"
|
80
|
-
|
114
|
+
|
81
|
-
|
115
|
+
Msg+="Execute_CMD: $L_ExecCMD \n"
|
116
|
+
|
82
|
-
|
117
|
+
else
|
118
|
+
|
119
|
+
Msg+="Sorce_Code: $A_SrcCode ( Pipeline be in used. Please check one lines. ) \n"
|
120
|
+
|
121
|
+
Msg+="Execute_CMD: $L_ExecCMD ( Pipeline be in used. Please check one lines. ) \n"
|
122
|
+
|
123
|
+
fi
|
124
|
+
|
125
|
+
Msg+="Sub_Shell: $BASH_SUBSHELL \n"
|
126
|
+
|
83
|
-
|
127
|
+
Msg+="Exited with status: ${RC[@]}."
|
84
128
|
|
85
129
|
echo -e ${Msg}
|
86
130
|
|
@@ -88,21 +132,35 @@
|
|
88
132
|
|
89
133
|
|
90
134
|
|
135
|
+
## サブシェル対応(判定処理の為に、現在のサブシェル状態をファイルへ書き込み)
|
136
|
+
|
137
|
+
if [ $BASH_SUBSHELL -ne 0 ] ; then
|
138
|
+
|
139
|
+
echo $BASH_SUBSHELL > SUBSHELL
|
140
|
+
|
141
|
+
fi
|
142
|
+
|
143
|
+
|
144
|
+
|
91
145
|
}
|
92
146
|
|
93
147
|
|
94
148
|
|
149
|
+
#### 終了処理
|
150
|
+
|
95
|
-
trap
|
151
|
+
trap finary EXIT
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
152
|
+
|
100
|
-
|
101
|
-
function
|
153
|
+
function finary(){
|
154
|
+
|
102
|
-
|
155
|
+
Msg=
|
156
|
+
|
103
|
-
|
157
|
+
Msg="=>=>=>=>=>=> Script(${BASH_SOURCE[1]}) finished. ============="
|
104
|
-
|
158
|
+
|
105
|
-
echo $
|
159
|
+
echo -e ${Msg}
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
rm SUBSHELL
|
106
164
|
|
107
165
|
}
|
108
166
|
|
@@ -128,61 +186,65 @@
|
|
128
186
|
|
129
187
|
## 事前処理
|
130
188
|
|
131
|
-
echo pre
|
189
|
+
echo -e "pre \n"
|
132
190
|
|
133
191
|
A_dir=$1
|
134
192
|
|
135
193
|
|
136
194
|
|
137
|
-
##
|
138
|
-
|
139
|
-
ls $A_dir ; cd $A_dir
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
#
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
## エラー
|
160
|
-
|
161
|
-
#tar
|
162
|
-
|
163
|
-
#
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
#
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
195
|
+
## サブシェルコマンド
|
196
|
+
|
197
|
+
(ls -d $A_dir ; cd $A_dir)
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
## 判定を入れて例外処理や終了処理を入れる(サブシェル)
|
202
|
+
|
203
|
+
if [ $RC -ne 0 ] ; then
|
204
|
+
|
205
|
+
echo -e "サブシェル版例外処理\n"
|
206
|
+
|
207
|
+
# exit 10
|
208
|
+
|
209
|
+
fi
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
## 親シェルコマンド
|
214
|
+
|
215
|
+
ls -d $A_dir ; cd $A_dir
|
216
|
+
|
217
|
+
#ls -d ${A_dir} | xargs -I {} echo "Current Directory is {}." # パイプラインエラーテスト X | 0
|
218
|
+
|
219
|
+
#echo "test" | xargs ls -d # パイプラインエラーテスト 0 | X
|
220
|
+
|
221
|
+
#ls -d ${A_dir} | xargs cd # パイプラインエラーテスト X | X
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
## 判定を入れて例外処理や終了処理を入れる(親シェル)
|
226
|
+
|
227
|
+
total=0
|
228
|
+
|
229
|
+
for val in ${RC[@]} ; do
|
230
|
+
|
231
|
+
total=$((val + total))
|
232
|
+
|
233
|
+
done
|
234
|
+
|
235
|
+
RC=$total
|
236
|
+
|
237
|
+
if [ $RC -ne 0 ] ; then
|
238
|
+
|
239
|
+
echo -e "親シェル版例外処理\n"
|
240
|
+
|
241
|
+
# exit 10
|
242
|
+
|
243
|
+
fi
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
echo -e "post \n"
|
186
248
|
|
187
249
|
|
188
250
|
|
2
2020/02/23 21:11 otn様より頂いた質問に回答する為、現時点のソースに再修正致しました。
test
CHANGED
@@ -46,6 +46,8 @@
|
|
46
46
|
|
47
47
|
|
48
48
|
|
49
|
+
**■ cmn_func.sh**
|
50
|
+
|
49
51
|
```ここに言語を入力
|
50
52
|
|
51
53
|
#!/bin/bash
|
@@ -60,13 +62,35 @@
|
|
60
62
|
|
61
63
|
function catch(){
|
62
64
|
|
65
|
+
RC=(${PIPESTATUS[@]})
|
66
|
+
|
63
67
|
A_LineNo=$1
|
64
68
|
|
65
69
|
A_SrcCode=$2
|
66
70
|
|
71
|
+
L_ExecCMD=`eval "echo $A_SrcCode"`
|
72
|
+
|
67
|
-
|
73
|
+
Msg=">>>> Script Error Occurred! ($0): \n\
|
74
|
+
|
75
|
+
SorceFile: ${BASH_SOURCE[1]} \n\
|
76
|
+
|
77
|
+
LineNo(${FUNCNAME[1]}): $A_LineNo \n\
|
78
|
+
|
79
|
+
Sorce_Code: $A_SrcCode \n\
|
80
|
+
|
81
|
+
Execute_CMD: $L_ExecCMD \n\
|
82
|
+
|
83
|
+
Exited with status: ${RC[@]}."
|
84
|
+
|
85
|
+
echo -e ${Msg}
|
86
|
+
|
87
|
+
echo
|
88
|
+
|
89
|
+
|
68
90
|
|
69
91
|
}
|
92
|
+
|
93
|
+
|
70
94
|
|
71
95
|
trap 'echo FINALLY' EXIT
|
72
96
|
|
@@ -74,17 +98,35 @@
|
|
74
98
|
|
75
99
|
#### エラー時も続行させる際の独自メッセージ定義
|
76
100
|
|
77
|
-
function
|
101
|
+
function Warn(){
|
78
102
|
|
79
|
-
|
103
|
+
RC=(${PIPESTATUS[@]})
|
80
104
|
|
81
105
|
echo $1
|
82
106
|
|
83
107
|
}
|
84
108
|
|
109
|
+
```
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
**■ main_shell.sh**
|
114
|
+
|
115
|
+
```ここに言語を入力
|
116
|
+
|
117
|
+
#!/bin/bssh
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
#### 共通関数読み込み
|
122
|
+
|
123
|
+
. ./cmn_func.sh
|
124
|
+
|
85
125
|
|
86
126
|
|
87
127
|
#### メイン
|
128
|
+
|
129
|
+
## 事前処理
|
88
130
|
|
89
131
|
echo pre
|
90
132
|
|
@@ -96,6 +138,8 @@
|
|
96
138
|
|
97
139
|
ls $A_dir ; cd $A_dir
|
98
140
|
|
141
|
+
#tar cvf - -C $A_dir | tar xvf $A_dir
|
142
|
+
|
99
143
|
|
100
144
|
|
101
145
|
## エラーで落とす場合はコマンド記載のみ(サブシェル版)
|
@@ -104,17 +148,35 @@
|
|
104
148
|
|
105
149
|
|
106
150
|
|
107
|
-
## エラー時も継続させる場合は「||」で繋げて
|
151
|
+
## エラー時も継続させる場合は「||」で繋げてWarn関数を呼び出す
|
108
152
|
|
109
|
-
#ls $A_dir ||
|
153
|
+
#ls $A_dir || Warn "続行"
|
110
154
|
|
111
|
-
#cd $A_dir ||
|
155
|
+
#cd $A_dir || Warn "続行"
|
112
156
|
|
113
157
|
|
114
158
|
|
115
|
-
## エラー時も継続させる場合
|
159
|
+
## エラー時も継続させる場合の判定処理
|
116
160
|
|
161
|
+
#tar cvf - -C $A_dir | tar xvf $A_dir || Warn "続行"
|
162
|
+
|
163
|
+
#if [ ${RC[0]} -ne 0 ] ; then
|
164
|
+
|
165
|
+
# echo "リターンコードに応じた例外処理"
|
166
|
+
|
167
|
+
#fi
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
## エラー時も継続させる場合は「||」で繋げてWarn関数を呼び出す(サブシェル版)
|
172
|
+
|
117
|
-
#(ls $A_dir ; cd $A_dir) ||
|
173
|
+
#(ls $A_dir ; cd $A_dir) || Warn "続行"
|
174
|
+
|
175
|
+
#if [ ${RC} -ne 0 ] ; then
|
176
|
+
|
177
|
+
# echo "リターンコードに応じた例外処理"
|
178
|
+
|
179
|
+
#fi
|
118
180
|
|
119
181
|
|
120
182
|
|
1
otn様より頂いた回答を元にソースを再修正致しました。
test
CHANGED
@@ -1,126 +1,122 @@
|
|
1
|
-
上記修正の上、色々と検証した結果、変数のスコープが問題のようでした。
|
1
|
+
~~上記修正の上、色々と検証した結果、変数のスコープが問題のようでした。~~
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
-
・サブシェル実行時には以下の通りとなります
|
5
|
+
~~・サブシェル実行時には以下の通りとなります~~
|
6
6
|
|
7
|
-
A_SrcCode='cd $A_dir'
|
7
|
+
~~A_SrcCode='cd $A_dir'~~
|
8
8
|
|
9
9
|
|
10
10
|
|
11
|
-
・しかし、親に処理が戻るとサブシェルが設定した値は破棄される為、前回実行したコマンドの結果が残っています。
|
11
|
+
~~・しかし、親に処理が戻るとサブシェルが設定した値は破棄される為、前回実行したコマンドの結果が残っています。~~
|
12
12
|
|
13
|
-
A_SrcCode='echo 'no sach directory.'
|
13
|
+
~~A_SrcCode='echo 'no sach directory.'~~
|
14
14
|
|
15
15
|
|
16
16
|
|
17
17
|
|
18
18
|
|
19
|
-
仕方がないので一旦ファイルに変数の値を吐き出してゴニョゴニョすることとしました。
|
19
|
+
~~仕方がないので一旦ファイルに変数の値を吐き出してゴニョゴニョすることとしました。~~
|
20
20
|
|
21
|
-
より良い方法があればご教示頂けると幸いです。
|
21
|
+
~~より良い方法があればご教示頂けると幸いです。~~
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
otn様より頂いた記法がシンプルかつ確実でしたので、使用させて頂きました。
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
個人的な思いとしては
|
30
|
+
|
31
|
+
・エラーならとりあえずcatchして独自エラーを吐き、処理をメインに戻す。
|
32
|
+
|
33
|
+
・継続させたい場合もあるので、終了処理はメイン処理の中で判断して記載する。
|
34
|
+
|
35
|
+
・なるべくメインシェルには共通関数導入による記法制限をかけたくない。
|
36
|
+
|
37
|
+
というところがありまして、出来れば「set -E」はつけたくない思いがありました。
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
エラーでも継続させたい場合は「||」で繋げて独自エラー関数を呼び出すような仕組みにしてみました。(これが制約となってしまいましたが・・・)
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
とても助かりました!ありがとうございました!
|
22
46
|
|
23
47
|
|
24
48
|
|
25
49
|
```ここに言語を入力
|
26
50
|
|
27
|
-
#!/bin/bs
|
51
|
+
#!/bin/bash
|
52
|
+
|
53
|
+
set -ET
|
28
54
|
|
29
55
|
|
30
56
|
|
57
|
+
#### 各種トラップおよび独自メッセージ定義
|
58
|
+
|
59
|
+
trap 'catch $LINENO "${BASH_COMMAND}" ; kill $$' ERR
|
60
|
+
|
61
|
+
function catch(){
|
62
|
+
|
31
|
-
|
63
|
+
A_LineNo=$1
|
64
|
+
|
65
|
+
A_SrcCode=$2
|
66
|
+
|
67
|
+
echo "Error line:$A_LineNo sorce_code:\"$A_SrcCode\" exited with status $?."
|
68
|
+
|
69
|
+
}
|
70
|
+
|
71
|
+
trap 'echo FINALLY' EXIT
|
32
72
|
|
33
73
|
|
34
74
|
|
35
|
-
####
|
75
|
+
#### エラー時も続行させる際の独自メッセージ定義
|
36
76
|
|
37
|
-
|
77
|
+
function LogMsg(){
|
38
78
|
|
39
|
-
|
79
|
+
true
|
40
80
|
|
41
|
-
:>SrcCode
|
42
|
-
|
43
|
-
echo 0 > SubShell
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
#### 各種トラップ
|
48
|
-
|
49
|
-
trap catch ERR
|
50
|
-
|
51
|
-
trap finally EXIT
|
52
|
-
|
53
|
-
function catch() {
|
54
|
-
|
55
|
-
errcode=$?
|
56
|
-
|
57
|
-
A_LineNo=`cat LineNo`
|
58
|
-
|
59
|
-
A_SrcCode=`cat SrcCode`
|
60
|
-
|
61
|
-
echo "error line:$A_LineNo sorce_code:\"$A_SrcCode\" exited with status $errcode."
|
62
|
-
|
63
|
-
exit 8
|
64
|
-
|
65
|
-
}
|
66
|
-
|
67
|
-
function finally() {
|
68
|
-
|
69
|
-
|
81
|
+
echo $1
|
70
82
|
|
71
83
|
}
|
72
84
|
|
73
85
|
|
74
86
|
|
75
|
-
|
87
|
+
#### メイン
|
76
88
|
|
77
|
-
|
89
|
+
echo pre
|
78
90
|
|
79
|
-
if [ $? -ne 0 ] ; then return ; fi
|
80
|
-
|
81
|
-
if [ ${FUNCNAME[1]} == "catch" ] ; then return ; fi
|
82
|
-
|
83
|
-
if [ `cat SubShell` -ne 0 -a $BASH_SUBSHELL -eq 0 ] ; then
|
84
|
-
|
85
|
-
echo $BASH_SUBSHELL > flg
|
86
|
-
|
87
|
-
|
91
|
+
A_dir=$1
|
88
|
-
|
89
|
-
fi
|
90
92
|
|
91
93
|
|
92
94
|
|
93
|
-
|
95
|
+
## エラーで落とす場合はコマンド記載のみ
|
94
96
|
|
95
|
-
A_SrcCode=$2
|
96
|
-
|
97
|
-
|
97
|
+
ls $A_dir ; cd $A_dir
|
98
|
-
|
99
|
-
echo "${A_SrcCode}" > SrcCode
|
100
|
-
|
101
|
-
echo ${BASH_SUBSHELL} > SubShell
|
102
|
-
|
103
|
-
}
|
104
98
|
|
105
99
|
|
106
100
|
|
107
|
-
##
|
101
|
+
## エラーで落とす場合はコマンド記載のみ(サブシェル版)
|
108
102
|
|
109
|
-
|
103
|
+
#(ls $A_dir ; cd $A_dir)
|
110
104
|
|
111
105
|
|
112
106
|
|
113
|
-
|
107
|
+
## エラー時も継続させる場合は「||」で繋げてLogMsg関数を呼び出す
|
114
108
|
|
115
|
-
|
109
|
+
#ls $A_dir || LogMsg "続行"
|
116
110
|
|
117
|
-
|
111
|
+
#cd $A_dir || LogMsg "続行"
|
118
|
-
|
119
|
-
fi
|
120
112
|
|
121
113
|
|
122
114
|
|
115
|
+
## エラー時も継続させる場合は「||」で繋げてLogMsg関数を呼び出す(サブシェル版)
|
116
|
+
|
123
|
-
cd $A_dir
|
117
|
+
#(ls $A_dir ; cd $A_dir) || LogMsg "続行"
|
118
|
+
|
119
|
+
|
124
120
|
|
125
121
|
|
126
122
|
|