aboutsummaryrefslogtreecommitdiff
path: root/shell-script.html
blob: ef76935d438b2337c9c631ba17c1ea7e8b428cd3 (plain) (blame)
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
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
    <head>
	<meta charset="utf-8" />
	<meta name="generator" content="pandoc" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
			<meta name="dcterms.date" content="2018-09-21" />
			<title>Style Guide</title>
	<style type="text/css">
	 code{white-space: pre-wrap;}
	 span.smallcaps{font-variant: small-caps;}
	 span.underline{text-decoration: underline;}
	 div.column{display: inline-block; vertical-align: top; width: 50%;}
	 	</style>
		<style type="text/css">
	 a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; position: absolute; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; }
pre.numberSource a.sourceLine:empty
  { position: absolute; }
pre.numberSource a.sourceLine::before
  { content: attr(data-line-number);
    position: absolute; left: -5em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
	</style>
		<link rel="stylesheet" href="assets/lib/bootstrap/bootstrap.min.css">
	<link rel="stylesheet" href="assets/lib/fontawesome/css/font-awesome.min.css">
	<link rel="stylesheet" href="assets/stylesheets/main.css">
			    </head>
    <body>
			<header class="container">
	    <div style="text-align: center;">
		<h1>Style Guide</h1>
				<p class="subtitle">Software Engineering at Driver</p>
				<nav class="my-4">
		    <a class="btn btn-light" href="css.html">
			<img src="assets/images/css.svg" width="16px" class="img-fluid">
			CSS
		    </a>
		    <a class="btn btn-light" href="git.html">
			<img src="assets/images/git.png" width="16px" class="img-fluid">
			Git
		    </a>
		    <a class="btn btn-light" href="html.html">
			<img src="assets/images/html5.svg" width="16px" class="img-fluid">
			HTML
		    </a>
		    <a class="btn btn-light" href="javascript.html">
			<img src="assets/images/javascript.png" width="16px" class="img-fluid">
			JavaScript
		    </a>
		    <a class="btn btn-light" href="scala.html">
			<img src="assets/images/scala.png" width="16px" class="img-fluid">
			Scala
		    </a>
		    <a class="btn btn-light" href="shell-script.html">
			<img src="assets/images/bash.svg" width="16px" class="img-fluid">
			Shell Script
		    </a>
		</nav>
	    </div>
	    	</header>
		<div class="container">
	    This guide recommends stylistic and architectural best
	    practices, designed to make your code easier for others to
	    understand. It offers <em>guidelines</em> not <em>rules</em>,
	    and there are situations in which the advice offered
	    should be actively ignored.
	    <hr>
	</div>
	<main class="container">
	    <h2 id="shell-script">Shell Script</h2>
<ul>
<li><p>Run the <a href="https://github.com/koalaman/shellcheck">ShellCheck</a> linter on all scripts.</p></li>
<li><p>Follow Google’s <a href="https://google.github.io/styleguide/shell.xml">Shell Style Guide</a>; most notably, the below points.</p></li>
<li><p>Use only Bourne Again SHell (Bash).</p>
<p>It’s acceptable to use features available only in Bash 4 and later. As of this writing, that version was released almost 10 years ago, and developers on any platforms which do not ship the latest version out-of-the box are expected to upgrade.</p></li>
<li><p>Prefer no file name extension for executables, and “.sh” extensions for libraries (scripts that are meant to be “sourced” in other scripts).</p>
<p>Rationale: an OS can run any executable file, regardless of its content, and as such, it isn’t helpful to know that an executable is in fact a shell script. However, it is essential to know that an included library is indeed a shell script.</p></li>
<li><p>Use long names for command-line options rather than short ones. E.g. use <code>ls --all</code> instead of <code>ls -a</code>.</p>
<p>Rationale: long names trade off clarity at the expense of brevity. They make it easier for an unfamiliar reader to grasp the meaning of an argument, but require the author to write more characters. Hence they are recommended in all places that are read more often than written.</p></li>
<li><p>Use lower_snake_case for all local environment variables, and UPPER_SNAKE_CASE for exported variables.</p></li>
<li><p>Prefer parsing command line options rather than relying on environment variables for configuration.</p></li>
<li><p>Print status messages to stderr, not stdout.</p>
<p>Rationale: stdout is often parsed by other utilities (for example in a pipeline) and should hence only contain a program’s output, if any.</p></li>
<li><p>Don’t make any assumptions about the working directory from which a script is invoked. Specifically, don’t require that the script be invoked within the same directory it is located.</p>
<p>Rationale: scripts should be treated like any other executable and should support indirection via symlinks. Requiring a specific working directory for a program to function is a needless restriction.</p>
<p>Note that this guide specifically applies to the <em>working directory</em> of the caller. The script itself may make assumptions about <em>its location</em> and the location of resources. The following snippet is an example mechanism to determine the directory of a script.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="co"># Base directory that this script is located at.</span></a>
<a class="sourceLine" id="cb1-2" data-line-number="2"><span class="va">dir=</span><span class="st">&quot;</span><span class="va">$(</span> <span class="bu">cd</span> <span class="st">&quot;</span><span class="va">$(</span> <span class="fu">dirname</span> <span class="st">&quot;</span><span class="va">${BASH_SOURCE[0]}</span><span class="st">&quot;</span> <span class="va">)</span><span class="st">&quot;</span> <span class="op">&gt;</span>/dev/null <span class="kw">&amp;&amp;</span> <span class="bu">pwd</span> <span class="va">)</span><span class="st">&quot;</span></a></code></pre></div></li>
</ul>
	</main>
	<footer class="small mt-6 mb-1">
	    	    <span class="date">2018-09-21</span>
	    	    	    | <a href="https://github.com/drivergroup/best-practices/blob/master/guides/shell-script.md" style="display: inline-block;"><i class="fa fa-github"></i> Edit on GitHub</a>
	    	</footer>
	    </body>
</html>