天天看點

通過Git WebHooks+腳本實作自動更新釋出代碼之Shell腳本(二)

  此shell腳本目前設計成在本地執行,目前不适合分布式執行的情況。也就是說,此腳本最好與項目在同一個機器上,這個缺陷已經标注在腳本中了,參見腳本中的多個todo。

  腳本完成的工作:

檢查配置檔案合規性

備份與恢複

增删改檔案

執行指令

失敗復原

  除上述完成的功能外,因為不同的項目其用到的指令或所需要執行的操作以及檢查成功與否大有不同,是以其他的功能需要可以繼續往上添加,需要的可以自行修改此腳本。此腳本僅作參考之用,歡迎提出改進意見、批評指正。

  腳本如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

<code>#!/usr/bin/env bash</code>

<code># public header</code>

<code># =============================================================================================================================</code>

<code># check that we are root ... so non-root users stop here</code>

<code>[  `</code><code>id</code> <code>-u` -</code><code>eq</code>  <code>"0"</code> <code>] ||  </code><code>exit</code> <code>4</code>

<code># resolve links - $0 may be a symbolic link</code>

<code>prg=</code><code>"$0"</code>

<code>while</code> <code>[ -h </code><code>"$prg"</code> <code>]; </code><code>do</code>

<code>  </code><code>ls</code><code>=`</code><code>ls</code> <code>-ld </code><code>"$prg"</code><code>`</code>

<code>  </code><code>link=`</code><code>expr</code> <code>"$ls"</code> <code>: </code><code>'.*-&gt; \(.*\)$'</code><code>`</code>

<code>  </code><code>if</code> <code>expr</code> <code>"$link"</code> <code>: </code><code>'/.*'</code> <code>&gt; </code><code>/dev/null</code><code>; </code><code>then</code>

<code>    </code><code>prg=</code><code>"$link"</code>

<code>  </code><code>else</code>

<code>    </code><code>prg=`</code><code>dirname</code> <code>"$prg"</code><code>`/</code><code>"$link"</code>

<code>  </code><code>fi</code>

<code>done</code>

<code># get standard environment variables</code>

<code>prgdir=`</code><code>dirname</code> <code>"$prg"</code><code>`</code>

<code># echo color function</code>

<code>function</code> <code>cecho {</code>

<code>    </code><code># usage:</code>

<code>    </code><code># cecho -red sometext     #error, failed</code>

<code>    </code><code># cecho -green sometext   # success</code>

<code>    </code><code># cecho -yellow sometext  # warning</code>

<code>    </code><code># cecho -blue sometext    # debug</code>

<code>    </code><code># cecho -white sometext   # info</code>

<code>    </code><code># cecho -n                # new line</code>

<code>    </code><code># end</code>

<code>    </code><code>while</code> <code>[ </code><code>"$1"</code> <code>]; </code><code>do</code>

<code>        </code><code>case</code> <code>"$1"</code> <code>in</code>

<code>            </code><code>-normal)        color=</code><code>"\033[00m"</code> <code>;;</code>

<code># -black)         color="\033[30;01m" ;;</code>

<code>-red)           color=</code><code>"\033[31;01m"</code> <code>;;</code>

<code>-green)         color=</code><code>"\033[32;01m"</code> <code>;;</code>

<code>-yellow)        color=</code><code>"\033[33;01m"</code> <code>;;</code>

<code>-blue)          color=</code><code>"\033[34;01m"</code> <code>;;</code>

<code># -magenta)       color="\033[35;01m" ;;</code>

<code># -cyan)          color="\033[36;01m" ;;</code>

<code>-white)         color=</code><code>"\033[37;01m"</code> <code>;;</code>

<code>-n)             one_line=1;   </code><code>shift</code> <code>; </code><code>continue</code> <code>;;</code>

<code>*)              </code><code>echo</code> <code>-n </code><code>"$1"</code><code>; </code><code>shift</code> <code>; </code><code>continue</code> <code>;;</code>

<code>esac</code>

<code>shift</code>

<code>echo</code> <code>-en </code><code>"$color"</code>

<code>echo</code> <code>-en </code><code>"$1"</code>

<code>echo</code> <code>-en </code><code>"\033[00m"</code>

<code>if</code> <code>[ ! $one_line ]; </code><code>then</code>

<code>        </code><code>echo</code>

<code>fi</code>

<code>}</code>

<code># end echo color function</code>

<code># echo color function, smarter</code>

<code>function</code> <code>echo_r () {</code>

<code>    </code><code>#error, failed</code>

<code>    </code><code>[ $</code><code># -ne 1 ] &amp;&amp; return 0</code>

<code>    </code><code>echo</code> <code>-e </code><code>"\033[31m$1\033[0m"</code>

<code>function</code> <code>echo_g () {</code>

<code>    </code><code># success</code>

<code>    </code><code>echo</code> <code>-e </code><code>"\033[32m$1\033[0m"</code>

<code>function</code> <code>echo_y () {</code>

<code>    </code><code># warning</code>

<code>    </code><code>echo</code> <code>-e </code><code>"\033[33m$1\033[0m"</code>

<code>function</code> <code>echo_b () {\</code>

<code>    </code><code># debug</code>

<code>    </code><code>echo</code> <code>-e </code><code>"\033[34m$1\033[0m"</code>

<code># end echo color function, smarter</code>

<code>workdir=$prgdir</code>

<code># end public header</code>

<code># begin customization for special case</code>

<code># project directory to waiting for update</code>

<code>config_project_dir=example_projects</code>

<code># resources directory which contain config file and update files</code>

<code>config_resources_dir=example_resources</code>

<code>config_config_file=$config_resources_dir</code><code>/config_update</code><code>.conf</code>

<code>config_backup_dir=example_backup_dir</code>

<code># log options</code>

<code>config_this_logfile=$workdir/.update_backup.log</code>

<code># end</code>

<code>function</code> <code>check_dependencies(){</code>

<code>    </code><code>echo_b </code><code>"checking dependencies for update procedure. "</code>

<code>    </code><code>if</code> <code>[ -z $config_project_dir ]; </code><code>then</code>

<code>        </code><code>echo_r </code><code>"error: config_project_dir is undefined! "</code>

<code>        </code><code>exit</code> <code>1</code>

<code>    </code><code>fi</code>

<code>    </code><code>if</code> <code>[ ! -d $config_resources_dir ]; </code><code>then</code>

<code>        </code><code>echo_r </code><code>"error: config_resources_dir is undefined! "</code>

<code>    </code><code>if</code> <code>[ -z $config_config_file ]; </code><code>then</code>

<code>        </code><code>echo_r </code><code>"error: config_config_file is undefined! "</code>

<code>    </code><code>left_disk_space=`</code><code>df</code> <code>$config_backup_dir | </code><code>tail</code> <code>-n1 | </code><code>awk</code> <code>'{print $(nf -2)}'</code><code>`</code>

<code>    </code><code># set 2097152 to project directory size</code>

<code>    </code><code>if</code> <code>[ -z $config_project_dir -o ! -d $config_project_dir ]; </code><code>then</code>

<code>        </code><code>project_file_space_usage=$(</code><code>du</code> <code>-s </code><code>/root</code> <code>| </code><code>awk</code> <code>'{print $1}'</code><code>)</code>

<code>        </code><code>required_size=$(</code><code>expr</code> <code>$project_file_space_usage \* 2)</code>

<code>    </code><code>if</code> <code>[[ $left_disk_space -lt $required_size ]]; </code><code>then</code>

<code>        </code><code>echo_r </code><code>"disk space of $config_backup_dir is smaller than $required_size. "</code>

<code>    </code><code>echo_g </code><code>"all required dependencies check pass! "</code>

<code>function</code> <code>test_self(){</code>

<code>    </code><code># how to use this function:</code>

<code>    </code><code># first execute "$0 test_self", then execute "$0 update"</code>

<code>    </code><code>echo_b </code><code>"test purpose begin. "</code>

<code>    </code><code># clean old test example</code>

<code>    </code><code>echo_b </code><code>"clean old test example. "</code>

<code>    </code><code>[ -d $workdir</code><code>/example_projects</code> <code>] &amp;&amp; </code><code>rm</code> <code>-rf $workdir</code><code>/example_projects</code>

<code>    </code><code>[ -d $workdir</code><code>/example_resources</code> <code>] &amp;&amp; </code><code>rm</code> <code>-rf $workdir</code><code>/example_resources</code>

<code>    </code><code>[ -d $workdir</code><code>/example_backup_dir</code> <code>] &amp;&amp; </code><code>rm</code> <code>-rf $workdir</code><code>/example_backup_dir</code>

<code>    </code><code># make an example project directory</code>

<code>        </code><code>echo_b </code><code>"making an example project directory. "</code>

<code>        </code><code>mkdir</code> <code>$workdir</code><code>/example_projects</code>

<code>        </code><code>config_project_dir=example_projects</code>

<code>        </code><code># padding example_projects directory</code>

<code>        </code><code>touch</code> <code>$config_project_dir</code><code>/example_filename</code>

<code>        </code><code>mkdir</code> <code>$config_project_dir</code><code>/example_directory</code>

<code>    </code><code># make an example resources directory</code>

<code>    </code><code>if</code> <code>[ -z $config_resources_dir -o ! -d $config_resources_dir ]; </code><code>then</code>

<code>        </code><code>echo_b </code><code>"making an example resources directory. "</code>

<code>        </code><code>mkdir</code>  <code>$workdir</code><code>/example_resources</code>

<code>        </code><code>config_resources_dir=$workdir</code><code>/example_resources</code>

<code>    </code><code># make an example config_update.conf</code>

<code>    </code><code>if</code> <code>[ -z $config_config_file -o ! -f $config_config_file ]; </code><code>then</code>

<code>        </code><code>echo_b </code><code>"making an example config_update.conf file. "</code>

<code>        </code><code>touch</code> <code>$config_resources_dir</code><code>/config_update</code><code>.conf</code>

<code>        </code><code>config_config_file=$config_resources_dir</code><code>/config_update</code><code>.conf</code>

<code>    </code><code># padding config_update.conf file</code>

<code>    </code><code>cat</code> <code>&gt;$config_config_file &lt;&lt;eof</code>

<code>file</code>    <code>filename1          add</code>

<code>file</code>    <code>filename2          remove</code>

<code>file</code>    <code>filename3          update</code>

<code>file</code>    <code>filename4          add</code>

<code>config  cleancachea             </code><code>enable</code>

<code>config  cleancacheb             disable</code>

<code>config  restartservicea         </code><code>enable</code>

<code>config  restartserviceb         disable</code>

<code>target  192.168.1.241           </code><code>ssh</code>

<code>target  192.168.1.242           </code><code>ssh</code>

<code>eof</code>

<code>    </code><code>files=`</code><code>awk</code> <code>-f </code><code>'[ ]+'</code> <code>'/^file/ { print $2 }'</code> <code>$config_config_file`</code>

<code>    </code><code>echo_b </code><code>"making an example files(patches) refer to $config_config_file. "</code>

<code>    </code><code>for</code> <code>names </code><code>in</code> <code>$files; </code><code>do</code>

<code>        </code><code>[ ! -f $config_resources_dir/$names ] &amp;&amp; </code><code>touch</code> <code>$config_resources_dir/$names</code>

<code>    </code><code>done</code>

<code>    </code><code># todo</code>

<code>    </code><code># test network and ssh for remote call</code>

<code>    </code><code># make an example backup directory</code>

<code>    </code><code>if</code> <code>[ -z $config_backup_dir -o ! -d $config_backup_dir ]; </code><code>then</code>

<code>        </code><code>echo_b </code><code>"making an example backup directory"</code>

<code>        </code><code>mkdir</code> <code>$workdir</code><code>/example_backup_dir</code>

<code>        </code><code>config_backup_dir=$workdir</code><code>/example_backup_dir</code>

<code>    </code><code>echo_g </code><code>"test purpose is finished and successfully! "</code>

<code>#function parse_config_file(){</code>

<code>#    # unbanned action</code>

<code>#    files=`awk -f '[ ]+' '/^file/ { print $2 }' $config_config_file`</code>

<code>#    configs=`awk -f '[ ]+' '/^config/ { print $2 }' $config_config_file`</code>

<code>#}</code>

<code>function</code> <code>do_cp(){</code>

<code>    </code><code>source=$1</code>

<code>#    echo "var: $source"</code>

<code>#    echo "result: $(dirname $source | grep ^\/ | awk '{print substr($1,1,1)}' )"</code>

<code>#    exit 0</code>

<code>    </code><code>if</code> <code>test</code> <code>"$(dirname $source | grep ^\/ | awk '{print substr($1,1,1)}')"</code> <code>== </code><code>""</code><code>; </code><code>then</code>

<code>        </code><code>echo_b </code><code>"execute copy action. "</code>

<code>        </code><code>dest=$config_project_dir/$source</code>

<code>        </code><code>\</code><code>cp</code> <code>$source $dest</code>

<code>    </code><code>else</code>

<code>        </code><code>echo_y </code><code>"self test purpose found! but we can do this action! "</code>

<code>        </code><code>[ ! -d $config_project_dir/$(</code><code>dirname</code> <code>$source) ] &amp;&amp; </code><code>mkdir</code> <code>-p $config_project_dir/$(</code><code>dirname</code> <code>$source)</code>

<code>        </code><code>\</code><code>cp</code> <code>$source $config_project_dir/$(</code><code>dirname</code> <code>$source)</code>

<code>function</code> <code>do_remove(){</code>

<code>    </code><code>file=$1</code>

<code>    </code><code>if</code> <code>test</code> <code>"$(dirname $source | awk -f '/' '{print $1}')"</code> <code>== </code><code>""</code><code>; </code><code>then</code>

<code>        </code><code>rm</code> <code>-rf $config_project_dir/$file</code>

<code>        </code><code>echo_y </code><code>"self test purpose found! this can not do remove action on self test purpose, skipping..."</code>

<code>        </code><code>return</code>

<code># todo</code>

<code># for remote call</code>

<code>#function do_remote_cp(){}</code>

<code>#function fo_remote_remove(){}</code>

<code>function</code> <code>file_operation(){</code>

<code>    </code><code>echo_b </code><code>"begin files operations"</code>

<code>        </code><code>if</code> <code>grep</code> <code>$names $config_config_file | </code><code>grep</code> <code>add &gt;</code><code>/dev/null</code> <code>2&gt;&amp;1 ; </code><code>then</code>

<code>            </code><code># do_cp</code>

<code>            </code><code>do_cp $names</code>

<code>        </code><code>elif</code> <code>grep</code> <code>$names $config_config_file | </code><code>grep</code> <code>update &gt;</code><code>/dev/null</code> <code>2&gt;&amp;1 ;</code><code>then</code>

<code>        </code><code>elif</code> <code>grep</code> <code>$names $config_config_file | </code><code>grep</code> <code>remove &gt;</code><code>/dev/null</code> <code>2&gt;&amp;1 ;</code><code>then</code>

<code>            </code><code># do_remove</code>

<code>            </code><code>do_remove $names</code>

<code>        </code><code>else</code>

<code>            </code><code>exit</code> <code>1</code>

<code>        </code><code>fi</code>

<code>    </code><code>echo_g </code><code>"files operations finished successfully! "</code>

<code># no example here, please refer to your real production environment</code>

<code>#function do_clean_cache(){}</code>

<code>#function do_restart_service(){}</code>

<code>function</code> <code>service_operation(){</code>

<code>    </code><code>echo_b </code><code>"begin services operations"</code>

<code>    </code><code>configs=`</code><code>awk</code> <code>-f </code><code>'[ ]+'</code> <code>'/^config/ { print $2 }'</code> <code>$config_config_file`</code>

<code>    </code><code>for</code> <code>names </code><code>in</code> <code>$configs; </code><code>do</code>

<code>        </code><code>if</code> <code>grep</code> <code>$names $config_config_file | </code><code>grep</code> <code>cleancache | </code><code>grep</code> <code>enable</code> <code>&gt;</code><code>/dev/null</code> <code>2&gt;&amp;1 ; </code><code>then</code>

<code>            </code><code># do_clean_cache</code>

<code>            </code><code>echo</code> <code>do_clean_cache $names</code>

<code>        </code><code>elif</code> <code>grep</code> <code>$names $config_config_file | </code><code>grep</code> <code>cleancache | </code><code>grep</code> <code>disable &gt;</code><code>/dev/null</code> <code>2&gt;&amp;1 ; </code><code>then</code>

<code>            </code><code># echo a warning</code>

<code>            </code><code>echo_y </code><code>"warning: disable action is not recommended, $names skipped."</code>

<code>        </code><code>elif</code> <code>grep</code> <code>$names $config_config_file | </code><code>grep</code> <code>restartservice | </code><code>grep</code> <code>enable</code> <code>&gt;</code><code>/dev/null</code> <code>2&gt;&amp;1 ; </code><code>then</code>

<code>            </code><code># do_restart_service</code>

<code>            </code><code>echo</code> <code>do_restart_service $names</code>

<code>        </code><code>elif</code> <code>grep</code> <code>$names $config_config_file | </code><code>grep</code> <code>restartservice | </code><code>grep</code> <code>disable &gt;</code><code>/dev/null</code> <code>2&gt;&amp;1 ; </code><code>then</code>

<code>            </code><code>echo</code> <code>$names</code>

<code>            </code><code>echo_r </code><code>"error: wrong config file $config_config_file, please check it. "</code>

<code>    </code><code>echo_g </code><code>"services operations finished successfully! "</code>

<code>function</code> <code>check_remote_server_status(){</code>

<code>    </code><code># for remote call</code>

<code>    </code><code>echo</code>

<code>function</code> <code>backup(){</code>

<code>    </code><code>echo_b </code><code>"backup files before update"</code>

<code>#    backup_filename=backup_$(date +%f_%h_%m_%s).tgz</code>

<code>    </code><code>backup_filename=backup_$(</code><code>date</code> <code>+%y_%m_%d_%h_%m_%s).tgz</code>

<code>    </code><code>tar</code> <code>--create --</code><code>gzip</code> <code>--absolute-names --</code><code>file</code><code>=$config_backup_dir/$backup_filename $config_project_dir</code>

<code>    </code><code>if</code> <code>[ $? -</code><code>eq</code> <code>0 ]; </code><code>then</code>

<code>        </code><code>echo_g </code><code>"backup files before update finished and successfully! "</code>

<code>        </code><code>echo</code> <code>"restore_least_file=$config_backup_dir/$backup_filename"</code> <code>&gt; $config_this_logfile</code>

<code>        </code><code>echo_r </code><code>"error: backup files before update failed! please alter to administrator. "</code>

<code>function</code> <code>restore(){</code>

<code>    </code><code>echo_b </code><code>"restore files for rollback"</code>

<code>    </code><code>if</code> <code>[ -f $config_this_logfile ]; </code><code>then</code>

<code>        </code><code>. $config_this_logfile</code>

<code>    </code><code>restore_least_file=${restore_least_file:-1}</code>

<code>    </code><code>if</code> <code>[ -s $restore_least_file ]; </code><code>then</code>

<code>        </code><code>tar</code> <code>-c $config_project_dir/.. -zxf $restore_least_file</code>

<code>        </code><code>if</code> <code>[ $? -</code><code>eq</code> <code>0 ]; </code><code>then</code>

<code>            </code><code>echo_g </code><code>"restore files finished and successfully! "</code>

<code>            </code><code>echo_r </code><code>"restore files failed! please alter to administrator. "</code>

<code>        </code><code>echo_r </code><code>"can not find backup files in $config_backup_dir, backup once indeed? "</code>

<code># function remote_backup(){}</code>

<code># function remote_restore(){}</code>

<code>function</code> <code>rollback(){</code>

<code>    </code><code>echo_b </code><code>"rollback after update failed"</code>

<code>    </code><code>$0 restore</code>

<code>    </code><code>echo_g </code><code>"rollback finished and successfully! "</code>

<code>function</code> <code>update_status(){</code>

<code>    </code><code># no example here, please refer to your real production environment</code>

<code>    </code><code># check if update success or failure</code>

<code>    </code><code>echo</code> <code>update_status</code>

<code>    </code><code># if failure, do rollback action</code>

<code>        </code><code># service_operation</code>

<code>function</code> <code>update(){</code>

<code>    </code><code># thinking carefully with all exit status, which is not good for automatic update </code>

<code>    </code><code>check_dependencies</code>

<code>    </code><code>backup</code>

<code>    </code><code>file_operation</code>

<code>    </code><code>service_operation</code>

<code>    </code><code>update_status</code>

<code>function</code> <code>destroy() {</code>

<code>    </code><code># echo a warning message</code>

<code>    </code><code>echo_y </code><code>"warning: this action will destroy all this project, and this is unrecoverable! "</code>

<code>    </code><code>answer=</code><code>"n"</code>

<code>    </code><code>echo_y </code><code>"do you want to destroy this project? "</code>

<code>    </code><code>read</code> <code>-p </code><code>"(default no,if you want please input: y ,if not please press the enter button):"</code> <code>answer</code>

<code>    </code><code>case</code> <code>"$answer"</code> <code>in</code>

<code>        </code><code>y|y|yes|yes|</code><code>yes</code><code>|yes|yes|yes|yes )</code>

<code>        </code><code># delete all file expect for this script self</code>

<code>        </code><code># find: warning: unix filenames usually don't contain slashes (though pathnames do).  that means that '-name `./deploy.sh'' will probably evaluate to false all the time on this system.  you might find the '-wholename' test more useful, or perhaps '-samefile'.  alternatively, if you are using gnu grep, you could use 'find ... -print0 | grep -fzz `./deploy.sh''.</code>

<code>            </code><code># echo $workdir/</code>

<code>            </code><code>#find -l $workdir -type f ! -name "$(basename $0)" -exec ls --color=auto -al {} \;</code>

<code>            </code><code># find -l . -type f ! -name "deploy.sh" -exec ls --color=auto -al {} \;</code>

<code>            </code><code># find -l . -type d -exec ls --color=auto -al {} \;</code>

<code>            </code><code># find -l ./ -maxdepth 1 ! -name "deploy.sh" ! -wholename "./"</code>

<code>        </code><code># ls | grep -v "fielname" |xargs rm -rf</code>

<code>        </code><code>find</code> <code>-l $workdir -maxdepth 1 ! -name </code><code>"$(basename $0)"</code> <code>! -wholename </code><code>"$workdir"</code>  <code>-</code><code>exec</code> <code>rm</code> <code>-rf {} \;</code>

<code>        </code><code>if</code> <code>[ $? -</code><code>eq</code> <code>0 ];</code><code>then</code>

<code>            </code><code>echo_g </code><code>"destory this project successfully! now will exit with status 0. "</code>

<code>            </code><code>exit</code> <code>0</code>

<code>            </code><code>echo_r </code><code>"error: something go wrong! please check or alter to admin user! "</code>

<code>        </code><code>;;</code>

<code>        </code><code>n|n|no|no|no|no)</code>

<code>        </code><code>echo_g </code><code>"destroy action is cancel"</code>

<code>        </code><code>exit</code> <code>0</code>

<code>        </code><code>*)</code>

<code>        </code><code>echo_r </code><code>"are you kidding me? you are a bad kid! "</code>

<code>    </code><code>esac</code>

<code>case</code> <code>$1 </code><code>in</code>

<code>    </code><code>update)</code>

<code>        </code><code>update</code>

<code>    </code><code>backup)</code>

<code>        </code><code>backup</code>

<code>    </code><code>restore)</code>

<code>        </code><code>restore</code>

<code>    </code><code>rollback)</code>

<code>        </code><code>rollback</code>

<code>    </code><code>destroy)</code>

<code>        </code><code>destroy</code>

<code>    </code><code>help|*)</code>

<code>        </code><code>echo</code> <code>"usage: $0 {update|backup|restore|rollback|destroy} with $0 itself"</code>

<code># this is not essential with 'case .. esac' handled no args excutions</code>

<code># replace "exit 0" with ":"</code>

<code>#exit 0</code>

<code>:</code>

tag: 自動更新shell腳本,自動化部署腳本,shell部署腳本,腳本實作自動更新和復原,自動化部署shell腳本執行個體

--end--