xref: /aosp_15_r20/external/google-styleguide/shell.xml (revision 8c35d5ee8e2913d4bd6623e2b93232b1da0ab719)
1*8c35d5eeSXin Li<?xml version="1.0"?>
2*8c35d5eeSXin Li<?xml-stylesheet type="text/xsl" href="styleguide.xsl"?>
3*8c35d5eeSXin Li<GUIDE title="Shell Style Guide">
4*8c35d5eeSXin Li
5*8c35d5eeSXin Li<p align="right">
6*8c35d5eeSXin Li
7*8c35d5eeSXin LiRevision 1.26
8*8c35d5eeSXin Li</p>
9*8c35d5eeSXin Li
10*8c35d5eeSXin Li
11*8c35d5eeSXin Li<address>
12*8c35d5eeSXin Li  Paul Armstrong<br/>
13*8c35d5eeSXin Li  Too many more to mention<br/>
14*8c35d5eeSXin Li</address>
15*8c35d5eeSXin Li
16*8c35d5eeSXin Li<OVERVIEW>
17*8c35d5eeSXin Li
18*8c35d5eeSXin Li  <CATEGORY title="Background">
19*8c35d5eeSXin Li
20*8c35d5eeSXin Li
21*8c35d5eeSXin Li
22*8c35d5eeSXin Li    <STYLEPOINT title="Which Shell to Use">
23*8c35d5eeSXin Li      <SUMMARY>
24*8c35d5eeSXin Li        <code>Bash</code> is the only shell scripting language permitted for
25*8c35d5eeSXin Li        executables.
26*8c35d5eeSXin Li      </SUMMARY>
27*8c35d5eeSXin Li      <BODY>
28*8c35d5eeSXin Li        <p>
29*8c35d5eeSXin Li          Executables must start with <code>#!/bin/bash</code> and a minimum
30*8c35d5eeSXin Li          number of flags. Use <code>set</code> to set shell options so that
31*8c35d5eeSXin Li          calling your script as <code>bash <i>&lt;script_name&gt;</i></code>
32*8c35d5eeSXin Li          does not break its functionality.
33*8c35d5eeSXin Li        </p>
34*8c35d5eeSXin Li        <p>
35*8c35d5eeSXin Li          Restricting all executable shell scripts to <b>bash</b>
36*8c35d5eeSXin Li          gives us a consistent shell language that's installed on all our
37*8c35d5eeSXin Li          machines.
38*8c35d5eeSXin Li        </p>
39*8c35d5eeSXin Li        <p>
40*8c35d5eeSXin Li          The only exception to this is where you're forced to by whatever
41*8c35d5eeSXin Li          you're coding for. One example of this is Solaris SVR4 packages which
42*8c35d5eeSXin Li          require plain Bourne shell for any scripts.
43*8c35d5eeSXin Li        </p>
44*8c35d5eeSXin Li      </BODY>
45*8c35d5eeSXin Li    </STYLEPOINT>
46*8c35d5eeSXin Li
47*8c35d5eeSXin Li    <STYLEPOINT title="When to use Shell">
48*8c35d5eeSXin Li      <SUMMARY>
49*8c35d5eeSXin Li        Shell should only be used for small utilities or simple wrapper
50*8c35d5eeSXin Li        scripts.
51*8c35d5eeSXin Li      </SUMMARY>
52*8c35d5eeSXin Li      <BODY>
53*8c35d5eeSXin Li        <p>
54*8c35d5eeSXin Li          While shell scripting isn't a development language, it is used for
55*8c35d5eeSXin Li          writing various utility scripts throughout Google.  This
56*8c35d5eeSXin Li          style guide is more a recognition of its use rather than
57*8c35d5eeSXin Li          a suggestion that it be used for widespread deployment.
58*8c35d5eeSXin Li        </p>
59*8c35d5eeSXin Li        <p>
60*8c35d5eeSXin Li          Some guidelines:
61*8c35d5eeSXin Li          <ul>
62*8c35d5eeSXin Li            <li>
63*8c35d5eeSXin Li              If you're mostly calling other utilities and are doing relatively
64*8c35d5eeSXin Li              little data manipulation, shell is an acceptable choice for the
65*8c35d5eeSXin Li              task.
66*8c35d5eeSXin Li            </li>
67*8c35d5eeSXin Li            <li>
68*8c35d5eeSXin Li              If performance matters, use something other than shell.
69*8c35d5eeSXin Li            </li>
70*8c35d5eeSXin Li            <li>
71*8c35d5eeSXin Li              If you find you need to use arrays for anything more than
72*8c35d5eeSXin Li              assignment of <code>${PIPESTATUS}</code>, you should use Python.
73*8c35d5eeSXin Li            </li>
74*8c35d5eeSXin Li            <li>
75*8c35d5eeSXin Li              If you are writing a script that is more than 100 lines long, you
76*8c35d5eeSXin Li              should probably be writing it in Python instead. Bear in mind
77*8c35d5eeSXin Li              that scripts grow. Rewrite your script in another language
78*8c35d5eeSXin Li              early to avoid a time-consuming rewrite at a later date.
79*8c35d5eeSXin Li            </li>
80*8c35d5eeSXin Li          </ul>
81*8c35d5eeSXin Li        </p>
82*8c35d5eeSXin Li      </BODY>
83*8c35d5eeSXin Li    </STYLEPOINT>
84*8c35d5eeSXin Li  </CATEGORY>
85*8c35d5eeSXin Li
86*8c35d5eeSXin Li</OVERVIEW>
87*8c35d5eeSXin Li
88*8c35d5eeSXin Li<CATEGORY title="Shell Files and Interpreter Invocation">
89*8c35d5eeSXin Li
90*8c35d5eeSXin Li  <STYLEPOINT title="File Extensions">
91*8c35d5eeSXin Li    <SUMMARY>
92*8c35d5eeSXin Li      Executables should have no extension (strongly preferred) or a
93*8c35d5eeSXin Li      <code>.sh</code> extension.
94*8c35d5eeSXin Li      Libraries must have a <code>.sh</code> extension and should not be
95*8c35d5eeSXin Li      executable.
96*8c35d5eeSXin Li    </SUMMARY>
97*8c35d5eeSXin Li    <BODY>
98*8c35d5eeSXin Li      <p>
99*8c35d5eeSXin Li        It is not necessary to know what language a program is written in when
100*8c35d5eeSXin Li        executing it and shell doesn't require an extension so we prefer not to
101*8c35d5eeSXin Li        use one for executables.
102*8c35d5eeSXin Li      </p>
103*8c35d5eeSXin Li      <p>
104*8c35d5eeSXin Li        However, for libraries it's important to know what language it is and
105*8c35d5eeSXin Li        sometimes there's a need to have similar libraries in different
106*8c35d5eeSXin Li        languages. This allows library files with identical purposes but
107*8c35d5eeSXin Li        different languages to be identically named except for the
108*8c35d5eeSXin Li        language-specific suffix.
109*8c35d5eeSXin Li      </p>
110*8c35d5eeSXin Li    </BODY>
111*8c35d5eeSXin Li  </STYLEPOINT>
112*8c35d5eeSXin Li
113*8c35d5eeSXin Li  <STYLEPOINT title="SUID/SGID">
114*8c35d5eeSXin Li    <SUMMARY>
115*8c35d5eeSXin Li      SUID and SGID are <em>forbidden</em> on shell scripts.
116*8c35d5eeSXin Li    </SUMMARY>
117*8c35d5eeSXin Li    <BODY>
118*8c35d5eeSXin Li      <p>
119*8c35d5eeSXin Li        There are too many security issues with shell that make it nearly
120*8c35d5eeSXin Li        impossible to secure sufficiently to allow SUID/SGID.  While bash does
121*8c35d5eeSXin Li        make it difficult to run SUID, it's still possible on some platforms
122*8c35d5eeSXin Li        which is why we're being explicit about banning it.
123*8c35d5eeSXin Li      </p>
124*8c35d5eeSXin Li      <p>
125*8c35d5eeSXin Li        Use <code>sudo</code>  to provide elevated access if you need it.
126*8c35d5eeSXin Li      </p>
127*8c35d5eeSXin Li    </BODY>
128*8c35d5eeSXin Li  </STYLEPOINT>
129*8c35d5eeSXin Li
130*8c35d5eeSXin Li</CATEGORY>
131*8c35d5eeSXin Li
132*8c35d5eeSXin Li<CATEGORY title="Environment">
133*8c35d5eeSXin Li
134*8c35d5eeSXin Li  <STYLEPOINT title="STDOUT vs STDERR">
135*8c35d5eeSXin Li    <SUMMARY>
136*8c35d5eeSXin Li      All error messages should go to <code>STDERR</code>.
137*8c35d5eeSXin Li    </SUMMARY>
138*8c35d5eeSXin Li    <BODY>
139*8c35d5eeSXin Li      <p>
140*8c35d5eeSXin Li        This makes it easier
141*8c35d5eeSXin Li        to separate normal status from actual issues.
142*8c35d5eeSXin Li      </p>
143*8c35d5eeSXin Li      <p>
144*8c35d5eeSXin Li        A function to print out error messages along with other status
145*8c35d5eeSXin Li        information is recommended.
146*8c35d5eeSXin Li        <CODE_SNIPPET>
147*8c35d5eeSXin Li          err() {
148*8c35d5eeSXin Li            echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" &gt;&amp;2
149*8c35d5eeSXin Li          }
150*8c35d5eeSXin Li
151*8c35d5eeSXin Li          if ! do_something; then
152*8c35d5eeSXin Li            err "Unable to do_something"
153*8c35d5eeSXin Li            exit "${E_DID_NOTHING}"
154*8c35d5eeSXin Li          fi
155*8c35d5eeSXin Li        </CODE_SNIPPET>
156*8c35d5eeSXin Li      </p>
157*8c35d5eeSXin Li    </BODY>
158*8c35d5eeSXin Li  </STYLEPOINT>
159*8c35d5eeSXin Li
160*8c35d5eeSXin Li</CATEGORY>
161*8c35d5eeSXin Li
162*8c35d5eeSXin Li<CATEGORY title="Comments">
163*8c35d5eeSXin Li
164*8c35d5eeSXin Li  <STYLEPOINT title="File Header">
165*8c35d5eeSXin Li    <SUMMARY>
166*8c35d5eeSXin Li      Start each file with a description of its contents.
167*8c35d5eeSXin Li    </SUMMARY>
168*8c35d5eeSXin Li    <BODY>
169*8c35d5eeSXin Li      <p>
170*8c35d5eeSXin Li        Every file must have a top-level comment including a brief overview of
171*8c35d5eeSXin Li        its contents.
172*8c35d5eeSXin Li        A
173*8c35d5eeSXin Li        copyright notice
174*8c35d5eeSXin Li        and author information are optional.
175*8c35d5eeSXin Li      </p>
176*8c35d5eeSXin Li      <p>
177*8c35d5eeSXin Li        Example:
178*8c35d5eeSXin Li        <CODE_SNIPPET>
179*8c35d5eeSXin Li          #!/bin/bash
180*8c35d5eeSXin Li          #
181*8c35d5eeSXin Li          # Perform hot backups of Oracle databases.
182*8c35d5eeSXin Li        </CODE_SNIPPET>
183*8c35d5eeSXin Li      </p>
184*8c35d5eeSXin Li
185*8c35d5eeSXin Li
186*8c35d5eeSXin Li    </BODY>
187*8c35d5eeSXin Li  </STYLEPOINT>
188*8c35d5eeSXin Li
189*8c35d5eeSXin Li  <STYLEPOINT title="Function Comments">
190*8c35d5eeSXin Li    <SUMMARY>
191*8c35d5eeSXin Li      Any function that is not both obvious and short must be commented. Any
192*8c35d5eeSXin Li      function in a library must be commented regardless of length or
193*8c35d5eeSXin Li      complexity.
194*8c35d5eeSXin Li    </SUMMARY>
195*8c35d5eeSXin Li    <BODY>
196*8c35d5eeSXin Li      <p>
197*8c35d5eeSXin Li        It should be possible for someone else to learn how to use your
198*8c35d5eeSXin Li        program or to use a function in your library by reading the comments
199*8c35d5eeSXin Li        (and self-help, if provided) without reading the code.
200*8c35d5eeSXin Li      </p>
201*8c35d5eeSXin Li      <p>
202*8c35d5eeSXin Li        All function comments should contain:
203*8c35d5eeSXin Li        <ul>
204*8c35d5eeSXin Li          <li>
205*8c35d5eeSXin Li            Description of the function
206*8c35d5eeSXin Li          </li>
207*8c35d5eeSXin Li          <li>
208*8c35d5eeSXin Li            Global variables used and modified
209*8c35d5eeSXin Li          </li>
210*8c35d5eeSXin Li          <li>
211*8c35d5eeSXin Li            Arguments taken
212*8c35d5eeSXin Li          </li>
213*8c35d5eeSXin Li          <li>
214*8c35d5eeSXin Li            Returned values other than the default exit status of the last
215*8c35d5eeSXin Li            command run
216*8c35d5eeSXin Li          </li>
217*8c35d5eeSXin Li        </ul>
218*8c35d5eeSXin Li      </p>
219*8c35d5eeSXin Li      <p>
220*8c35d5eeSXin Li        Example:
221*8c35d5eeSXin Li        <CODE_SNIPPET>
222*8c35d5eeSXin Li          #!/bin/bash
223*8c35d5eeSXin Li          #
224*8c35d5eeSXin Li          # Perform hot backups of Oracle databases.
225*8c35d5eeSXin Li
226*8c35d5eeSXin Li          export PATH='/usr/xpg4/bin:/usr/bin:/opt/csw/bin:/opt/goog/bin'
227*8c35d5eeSXin Li
228*8c35d5eeSXin Li          #######################################
229*8c35d5eeSXin Li          # Cleanup files from the backup dir
230*8c35d5eeSXin Li          # Globals:
231*8c35d5eeSXin Li          #   BACKUP_DIR
232*8c35d5eeSXin Li          #   ORACLE_SID
233*8c35d5eeSXin Li          # Arguments:
234*8c35d5eeSXin Li          #   None
235*8c35d5eeSXin Li          # Returns:
236*8c35d5eeSXin Li          #   None
237*8c35d5eeSXin Li          #######################################
238*8c35d5eeSXin Li          cleanup() {
239*8c35d5eeSXin Li            ...
240*8c35d5eeSXin Li          }
241*8c35d5eeSXin Li        </CODE_SNIPPET>
242*8c35d5eeSXin Li      </p>
243*8c35d5eeSXin Li    </BODY>
244*8c35d5eeSXin Li  </STYLEPOINT>
245*8c35d5eeSXin Li
246*8c35d5eeSXin Li  <STYLEPOINT title="Implementation Comments">
247*8c35d5eeSXin Li    <SUMMARY>
248*8c35d5eeSXin Li      Comment tricky, non-obvious, interesting or important parts of your code.
249*8c35d5eeSXin Li    </SUMMARY>
250*8c35d5eeSXin Li    <BODY>
251*8c35d5eeSXin Li      <p>
252*8c35d5eeSXin Li        This follows general Google coding comment practice. Don't comment
253*8c35d5eeSXin Li        everything.  If there's a complex algorithm or you're doing something
254*8c35d5eeSXin Li        out of the ordinary, put a short comment in.
255*8c35d5eeSXin Li      </p>
256*8c35d5eeSXin Li    </BODY>
257*8c35d5eeSXin Li  </STYLEPOINT>
258*8c35d5eeSXin Li
259*8c35d5eeSXin Li  <STYLEPOINT title="TODO Comments">
260*8c35d5eeSXin Li    <SUMMARY>
261*8c35d5eeSXin Li      Use TODO comments for code that is temporary, a short-term solution, or
262*8c35d5eeSXin Li      good-enough but not perfect.
263*8c35d5eeSXin Li    </SUMMARY>
264*8c35d5eeSXin Li    <BODY>
265*8c35d5eeSXin Li      <p>
266*8c35d5eeSXin Li        This matches the convention in the <a href="cppguide.html?showone=TODO_Comments#TODO_Comments">C++
267*8c35d5eeSXin Li          Guide</a>.
268*8c35d5eeSXin Li      </p>
269*8c35d5eeSXin Li      <p>
270*8c35d5eeSXin Li         TODOs should include the string TODO in all caps, followed by your
271*8c35d5eeSXin Li         username in parentheses. A colon is optional. It's preferable to put a
272*8c35d5eeSXin Li         bug/ticket number next to the TODO item as well.
273*8c35d5eeSXin Li      </p>
274*8c35d5eeSXin Li      <p>
275*8c35d5eeSXin Li        Examples:
276*8c35d5eeSXin Li
277*8c35d5eeSXin Li        <CODE_SNIPPET>
278*8c35d5eeSXin Li          # TODO(mrmonkey): Handle the unlikely edge cases (bug ####)
279*8c35d5eeSXin Li        </CODE_SNIPPET>
280*8c35d5eeSXin Li      </p>
281*8c35d5eeSXin Li    </BODY>
282*8c35d5eeSXin Li  </STYLEPOINT>
283*8c35d5eeSXin Li
284*8c35d5eeSXin Li</CATEGORY>
285*8c35d5eeSXin Li
286*8c35d5eeSXin Li<CATEGORY title="Formatting">
287*8c35d5eeSXin Li  <p>
288*8c35d5eeSXin Li    While you should follow the style that's already there for files that
289*8c35d5eeSXin Li    you're modifying, the following are required for any new code.
290*8c35d5eeSXin Li  </p>
291*8c35d5eeSXin Li
292*8c35d5eeSXin Li  <STYLEPOINT title="Indentation">
293*8c35d5eeSXin Li    <SUMMARY>
294*8c35d5eeSXin Li      Indent 2 spaces. No tabs.
295*8c35d5eeSXin Li    </SUMMARY>
296*8c35d5eeSXin Li    <BODY>
297*8c35d5eeSXin Li      <p>
298*8c35d5eeSXin Li        Use blank lines between blocks to improve readability.  Indentation is
299*8c35d5eeSXin Li        two spaces.  Whatever you do, don't use tabs.  For existing files, stay
300*8c35d5eeSXin Li        faithful to the existing indentation.
301*8c35d5eeSXin Li      </p>
302*8c35d5eeSXin Li    </BODY>
303*8c35d5eeSXin Li  </STYLEPOINT>
304*8c35d5eeSXin Li
305*8c35d5eeSXin Li  <STYLEPOINT title="Line Length and Long Strings">
306*8c35d5eeSXin Li    <SUMMARY>
307*8c35d5eeSXin Li      Maximum line length is 80 characters.
308*8c35d5eeSXin Li    </SUMMARY>
309*8c35d5eeSXin Li    <BODY>
310*8c35d5eeSXin Li      <p>
311*8c35d5eeSXin Li        If you have to write strings that are longer than 80 characters, this
312*8c35d5eeSXin Li        should be done with a here document or an embedded newline if possible.
313*8c35d5eeSXin Li        Literal strings that have to be longer than 80 chars and can't sensibly
314*8c35d5eeSXin Li        be split are ok, but it's strongly preferred to find a way to make it
315*8c35d5eeSXin Li        shorter.
316*8c35d5eeSXin Li      </p>
317*8c35d5eeSXin Li      <p>
318*8c35d5eeSXin Li        <CODE_SNIPPET>
319*8c35d5eeSXin Li          # DO use 'here document's
320*8c35d5eeSXin Li          cat &lt;&lt;END;
321*8c35d5eeSXin Li          I am an exceptionally long
322*8c35d5eeSXin Li          string.
323*8c35d5eeSXin Li          END
324*8c35d5eeSXin Li
325*8c35d5eeSXin Li          # Embedded newlines are ok too
326*8c35d5eeSXin Li          long_string="I am an exceptionally
327*8c35d5eeSXin Li            long string."
328*8c35d5eeSXin Li        </CODE_SNIPPET>
329*8c35d5eeSXin Li      </p>
330*8c35d5eeSXin Li    </BODY>
331*8c35d5eeSXin Li  </STYLEPOINT>
332*8c35d5eeSXin Li
333*8c35d5eeSXin Li  <STYLEPOINT title="Pipelines">
334*8c35d5eeSXin Li    <SUMMARY>
335*8c35d5eeSXin Li      Pipelines should be split one per line if they don't all fit on one line.
336*8c35d5eeSXin Li    </SUMMARY>
337*8c35d5eeSXin Li    <BODY>
338*8c35d5eeSXin Li      <p>
339*8c35d5eeSXin Li        If a pipeline all fits on one line, it should be on one line.
340*8c35d5eeSXin Li      </p>
341*8c35d5eeSXin Li      <p>
342*8c35d5eeSXin Li        If not, it should be split at one pipe segment per line with the pipe
343*8c35d5eeSXin Li        on the newline and a 2 space indent for the next section of the pipe.
344*8c35d5eeSXin Li        This applies to a chain of commands combined using '|' as well as to
345*8c35d5eeSXin Li        logical compounds using '||' and '&amp;&amp;'.
346*8c35d5eeSXin Li        <CODE_SNIPPET>
347*8c35d5eeSXin Li          # All fits on one line
348*8c35d5eeSXin Li          command1 | command2
349*8c35d5eeSXin Li
350*8c35d5eeSXin Li          # Long commands
351*8c35d5eeSXin Li          command1 \
352*8c35d5eeSXin Li            | command2 \
353*8c35d5eeSXin Li            | command3 \
354*8c35d5eeSXin Li            | command4
355*8c35d5eeSXin Li        </CODE_SNIPPET>
356*8c35d5eeSXin Li      </p>
357*8c35d5eeSXin Li    </BODY>
358*8c35d5eeSXin Li  </STYLEPOINT>
359*8c35d5eeSXin Li
360*8c35d5eeSXin Li  <STYLEPOINT title="Loops">
361*8c35d5eeSXin Li    <SUMMARY>
362*8c35d5eeSXin Li      Put <code>; do</code> and <code>; then</code> on the same line as the
363*8c35d5eeSXin Li      <code>while</code>, <code>for</code> or <code>if</code>.
364*8c35d5eeSXin Li    </SUMMARY>
365*8c35d5eeSXin Li    <BODY>
366*8c35d5eeSXin Li      <p>
367*8c35d5eeSXin Li        Loops in shell are a bit different, but we follow the same principles
368*8c35d5eeSXin Li        as with braces when declaring functions. That is: <code>; then</code>
369*8c35d5eeSXin Li        and <code>; do</code> should be on the same line as the if/for/while.
370*8c35d5eeSXin Li        <code>else</code> should be on its own line and closing statements
371*8c35d5eeSXin Li        should be on their own line vertically aligned with the opening
372*8c35d5eeSXin Li        statement.
373*8c35d5eeSXin Li      </p>
374*8c35d5eeSXin Li      <p>
375*8c35d5eeSXin Li        Example:
376*8c35d5eeSXin Li        <CODE_SNIPPET>
377*8c35d5eeSXin Li          for dir in ${dirs_to_cleanup}; do
378*8c35d5eeSXin Li            if [[ -d "${dir}/${ORACLE_SID}" ]]; then
379*8c35d5eeSXin Li              log_date "Cleaning up old files in ${dir}/${ORACLE_SID}"
380*8c35d5eeSXin Li              rm "${dir}/${ORACLE_SID}/"*
381*8c35d5eeSXin Li              if [[ "$?" -ne 0 ]]; then
382*8c35d5eeSXin Li                error_message
383*8c35d5eeSXin Li              fi
384*8c35d5eeSXin Li            else
385*8c35d5eeSXin Li              mkdir -p "${dir}/${ORACLE_SID}"
386*8c35d5eeSXin Li              if [[ "$?" -ne 0 ]]; then
387*8c35d5eeSXin Li                error_message
388*8c35d5eeSXin Li              fi
389*8c35d5eeSXin Li            fi
390*8c35d5eeSXin Li          done
391*8c35d5eeSXin Li        </CODE_SNIPPET>
392*8c35d5eeSXin Li      </p>
393*8c35d5eeSXin Li    </BODY>
394*8c35d5eeSXin Li  </STYLEPOINT>
395*8c35d5eeSXin Li
396*8c35d5eeSXin Li  <STYLEPOINT title="Case statement">
397*8c35d5eeSXin Li    <SUMMARY>
398*8c35d5eeSXin Li      <ul>
399*8c35d5eeSXin Li        <li>
400*8c35d5eeSXin Li          Indent alternatives by 2 spaces.
401*8c35d5eeSXin Li        </li>
402*8c35d5eeSXin Li        <li>
403*8c35d5eeSXin Li          A one-line alternative needs a space after the close parenthesis of
404*8c35d5eeSXin Li          the pattern and before the <code>;;</code>.
405*8c35d5eeSXin Li        </li>
406*8c35d5eeSXin Li        <li>
407*8c35d5eeSXin Li          Long or multi-command alternatives should be split over multiple
408*8c35d5eeSXin Li          lines with the pattern, actions, and <code>;;</code> on separate
409*8c35d5eeSXin Li          lines.
410*8c35d5eeSXin Li        </li>
411*8c35d5eeSXin Li      </ul>
412*8c35d5eeSXin Li    </SUMMARY>
413*8c35d5eeSXin Li    <BODY>
414*8c35d5eeSXin Li      <p>
415*8c35d5eeSXin Li        The matching expressions are indented one level from the 'case' and
416*8c35d5eeSXin Li        'esac'.  Multiline actions are indented another level.  In general,
417*8c35d5eeSXin Li        there is no need to quote match expressions.  Pattern expressions
418*8c35d5eeSXin Li        should not be preceded by an open parenthesis.  Avoid the
419*8c35d5eeSXin Li        <code>;&amp;</code> and <code>;;&amp;</code> notations.
420*8c35d5eeSXin Li      </p>
421*8c35d5eeSXin Li      <CODE_SNIPPET>
422*8c35d5eeSXin Li        case "${expression}" in
423*8c35d5eeSXin Li          a)
424*8c35d5eeSXin Li            variable="..."
425*8c35d5eeSXin Li            some_command "${variable}" "${other_expr}" ...
426*8c35d5eeSXin Li            ;;
427*8c35d5eeSXin Li          absolute)
428*8c35d5eeSXin Li            actions="relative"
429*8c35d5eeSXin Li            another_command "${actions}" "${other_expr}" ...
430*8c35d5eeSXin Li            ;;
431*8c35d5eeSXin Li          *)
432*8c35d5eeSXin Li            error "Unexpected expression '${expression}'"
433*8c35d5eeSXin Li            ;;
434*8c35d5eeSXin Li        esac
435*8c35d5eeSXin Li      </CODE_SNIPPET>
436*8c35d5eeSXin Li      <p>
437*8c35d5eeSXin Li        Simple commands may be put on the same line as the pattern <i>and</i>
438*8c35d5eeSXin Li        <code>;;</code> as long as the expression remains readable.  This is
439*8c35d5eeSXin Li        often appropriate for single-letter option processing.  When the
440*8c35d5eeSXin Li        actions don't fit on a single line, put the pattern on a line on its
441*8c35d5eeSXin Li        own, then the actions, then <code>;;</code> also on a line of its own.
442*8c35d5eeSXin Li        When on the same line as the actions, use a space after the close
443*8c35d5eeSXin Li        parenthesis of the pattern and another before the <code>;;</code>.
444*8c35d5eeSXin Li        </p>
445*8c35d5eeSXin Li      <CODE_SNIPPET>
446*8c35d5eeSXin Li        verbose='false'
447*8c35d5eeSXin Li        aflag=''
448*8c35d5eeSXin Li        bflag=''
449*8c35d5eeSXin Li        files=''
450*8c35d5eeSXin Li        while getopts 'abf:v' flag; do
451*8c35d5eeSXin Li          case "${flag}" in
452*8c35d5eeSXin Li            a) aflag='true' ;;
453*8c35d5eeSXin Li            b) bflag='true' ;;
454*8c35d5eeSXin Li            f) files="${OPTARG}" ;;
455*8c35d5eeSXin Li            v) verbose='true' ;;
456*8c35d5eeSXin Li            *) error "Unexpected option ${flag}" ;;
457*8c35d5eeSXin Li          esac
458*8c35d5eeSXin Li        done
459*8c35d5eeSXin Li      </CODE_SNIPPET>
460*8c35d5eeSXin Li    </BODY>
461*8c35d5eeSXin Li  </STYLEPOINT>
462*8c35d5eeSXin Li
463*8c35d5eeSXin Li  <STYLEPOINT title="Variable expansion">
464*8c35d5eeSXin Li    <SUMMARY>
465*8c35d5eeSXin Li      In order of precedence: Stay consistent with what you find;
466*8c35d5eeSXin Li      quote your variables;
467*8c35d5eeSXin Li      prefer "${var}" over "$var", but see details.
468*8c35d5eeSXin Li    </SUMMARY>
469*8c35d5eeSXin Li    <BODY>
470*8c35d5eeSXin Li      <p>
471*8c35d5eeSXin Li        These are meant to be guidelines, as the topic seems too controversial for
472*8c35d5eeSXin Li        a mandatory regulation.
473*8c35d5eeSXin Li        <br/>
474*8c35d5eeSXin Li        They are listed in order of precedence.
475*8c35d5eeSXin Li      </p>
476*8c35d5eeSXin Li      <ol>
477*8c35d5eeSXin Li        <li>
478*8c35d5eeSXin Li          Stay consistent with what you find for existing code.
479*8c35d5eeSXin Li        </li>
480*8c35d5eeSXin Li        <li>
481*8c35d5eeSXin Li          Quote variables, see <a href="#Quoting">Quoting section below</a>.
482*8c35d5eeSXin Li        </li>
483*8c35d5eeSXin Li        <li>
484*8c35d5eeSXin Li          <p>
485*8c35d5eeSXin Li            Don't brace-quote single character shell
486*8c35d5eeSXin Li            specials / positional parameters, unless strictly necessary
487*8c35d5eeSXin Li            or avoiding deep confusion.
488*8c35d5eeSXin Li            <br/>
489*8c35d5eeSXin Li            Prefer brace-quoting all other variables.
490*8c35d5eeSXin Li            <CODE_SNIPPET>
491*8c35d5eeSXin Li              # Section of <em>recommended</em> cases.
492*8c35d5eeSXin Li
493*8c35d5eeSXin Li              # Preferred style for 'special' variables:
494*8c35d5eeSXin Li              echo "Positional: $1" "$5" "$3"
495*8c35d5eeSXin Li              echo "Specials: !=$!, -=$-, _=$_. ?=$?, #=$# *=$* @=$@ \$=$$ ..."
496*8c35d5eeSXin Li
497*8c35d5eeSXin Li              # Braces necessary:
498*8c35d5eeSXin Li              echo "many parameters: ${10}"
499*8c35d5eeSXin Li
500*8c35d5eeSXin Li              # Braces avoiding confusion:
501*8c35d5eeSXin Li              # Output is "a0b0c0"
502*8c35d5eeSXin Li              set -- a b c
503*8c35d5eeSXin Li              echo "${1}0${2}0${3}0"
504*8c35d5eeSXin Li
505*8c35d5eeSXin Li              # Preferred style for other variables:
506*8c35d5eeSXin Li              echo "PATH=${PATH}, PWD=${PWD}, mine=${some_var}"
507*8c35d5eeSXin Li              while read f; do
508*8c35d5eeSXin Li                echo "file=${f}"
509*8c35d5eeSXin Li              done &lt; &lt;(ls -l /tmp)
510*8c35d5eeSXin Li
511*8c35d5eeSXin Li              # Section of <em>discouraged</em> cases
512*8c35d5eeSXin Li
513*8c35d5eeSXin Li              # Unquoted vars, unbraced vars, brace-quoted single letter
514*8c35d5eeSXin Li              # shell specials.
515*8c35d5eeSXin Li              echo a=$avar "b=$bvar" "PID=${$}" "${1}"
516*8c35d5eeSXin Li
517*8c35d5eeSXin Li              # Confusing use: this is expanded as "${1}0${2}0${3}0",
518*8c35d5eeSXin Li              # not "${10}${20}${30}
519*8c35d5eeSXin Li              set -- a b c
520*8c35d5eeSXin Li              echo "$10$20$30"
521*8c35d5eeSXin Li            </CODE_SNIPPET>
522*8c35d5eeSXin Li          </p>
523*8c35d5eeSXin Li        </li>
524*8c35d5eeSXin Li      </ol>
525*8c35d5eeSXin Li    </BODY>
526*8c35d5eeSXin Li  </STYLEPOINT>
527*8c35d5eeSXin Li
528*8c35d5eeSXin Li  <STYLEPOINT title="Quoting">
529*8c35d5eeSXin Li    <SUMMARY>
530*8c35d5eeSXin Li      <ul>
531*8c35d5eeSXin Li        <li>
532*8c35d5eeSXin Li          Always quote strings containing variables, command substitutions,
533*8c35d5eeSXin Li          spaces or shell meta characters, unless careful unquoted expansion
534*8c35d5eeSXin Li          is required.
535*8c35d5eeSXin Li        </li>
536*8c35d5eeSXin Li        <li>
537*8c35d5eeSXin Li          Prefer quoting strings that are "words"
538*8c35d5eeSXin Li          (as opposed to command options or path names).
539*8c35d5eeSXin Li        </li>
540*8c35d5eeSXin Li        <li>
541*8c35d5eeSXin Li        Never quote <em>literal</em> integers.
542*8c35d5eeSXin Li        </li>
543*8c35d5eeSXin Li        <li>
544*8c35d5eeSXin Li          Be aware of the quoting rules for
545*8c35d5eeSXin Li          <a href="#Test,_%5B_and_%5B%5B">pattern matches in [[</a>.
546*8c35d5eeSXin Li        </li>
547*8c35d5eeSXin Li        <li>
548*8c35d5eeSXin Li          Use "$@" unless you have a specific reason to use $*.
549*8c35d5eeSXin Li        </li>
550*8c35d5eeSXin Li      </ul>
551*8c35d5eeSXin Li    </SUMMARY>
552*8c35d5eeSXin Li    <BODY>
553*8c35d5eeSXin Li      <p>
554*8c35d5eeSXin Li        <CODE_SNIPPET>
555*8c35d5eeSXin Li          # 'Single' quotes indicate that no substitution is desired.
556*8c35d5eeSXin Li          # "Double" quotes indicate that substitution is required/tolerated.
557*8c35d5eeSXin Li
558*8c35d5eeSXin Li          # Simple examples
559*8c35d5eeSXin Li          # "quote command substitutions"
560*8c35d5eeSXin Li          flag="$(some_command and its args "$@" 'quoted separately')"
561*8c35d5eeSXin Li
562*8c35d5eeSXin Li          # "quote variables"
563*8c35d5eeSXin Li          echo "${flag}"
564*8c35d5eeSXin Li
565*8c35d5eeSXin Li          # "never quote literal integers"
566*8c35d5eeSXin Li          value=32
567*8c35d5eeSXin Li          # "quote command substitutions", even when you expect integers
568*8c35d5eeSXin Li          number="$(generate_number)"
569*8c35d5eeSXin Li
570*8c35d5eeSXin Li          # "prefer quoting words", not compulsory
571*8c35d5eeSXin Li          readonly USE_INTEGER='true'
572*8c35d5eeSXin Li
573*8c35d5eeSXin Li          # "quote shell meta characters"
574*8c35d5eeSXin Li          echo 'Hello stranger, and well met. Earn lots of $$$'
575*8c35d5eeSXin Li          echo "Process $$: Done making \$\$\$."
576*8c35d5eeSXin Li
577*8c35d5eeSXin Li          # "command options or path names"
578*8c35d5eeSXin Li          # ($1 is assumed to contain a value here)
579*8c35d5eeSXin Li          grep -li Hugo /dev/null "$1"
580*8c35d5eeSXin Li
581*8c35d5eeSXin Li          # Less simple examples
582*8c35d5eeSXin Li          # "quote variables, unless proven false": ccs might be empty
583*8c35d5eeSXin Li          git send-email --to "${reviewers}" ${ccs:+"--cc" "${ccs}"}
584*8c35d5eeSXin Li
585*8c35d5eeSXin Li          # Positional parameter precautions: $1 might be unset
586*8c35d5eeSXin Li          # Single quotes leave regex as-is.
587*8c35d5eeSXin Li          grep -cP '([Ss]pecial|\|?characters*)$' ${1:+"$1"}
588*8c35d5eeSXin Li
589*8c35d5eeSXin Li          # For passing on arguments,
590*8c35d5eeSXin Li          # "$@" is right almost everytime, and
591*8c35d5eeSXin Li          # $* is wrong almost everytime:
592*8c35d5eeSXin Li          #
593*8c35d5eeSXin Li          # * $* and $@ will split on spaces, clobbering up arguments
594*8c35d5eeSXin Li          #   that contain spaces and dropping empty strings;
595*8c35d5eeSXin Li          # * "$@" will retain arguments as-is, so no args
596*8c35d5eeSXin Li          #   provided will result in no args being passed on;
597*8c35d5eeSXin Li          #   This is in most cases what you want to use for passing
598*8c35d5eeSXin Li          #   on arguments.
599*8c35d5eeSXin Li          # * "$*" expands to one argument, with all args joined
600*8c35d5eeSXin Li          #   by (usually) spaces,
601*8c35d5eeSXin Li          #   so no args provided will result in one empty string
602*8c35d5eeSXin Li          #   being passed on.
603*8c35d5eeSXin Li          # (Consult 'man bash' for the nit-grits ;-)
604*8c35d5eeSXin Li
605*8c35d5eeSXin Li          set -- 1 "2 two" "3 three tres"; echo $# ; set -- "$*"; echo "$#, $@")
606*8c35d5eeSXin Li          set -- 1 "2 two" "3 three tres"; echo $# ; set -- "$@"; echo "$#, $@")
607*8c35d5eeSXin Li        </CODE_SNIPPET>
608*8c35d5eeSXin Li      </p>
609*8c35d5eeSXin Li    </BODY>
610*8c35d5eeSXin Li  </STYLEPOINT>
611*8c35d5eeSXin Li
612*8c35d5eeSXin Li</CATEGORY>
613*8c35d5eeSXin Li
614*8c35d5eeSXin Li<CATEGORY title="Features and Bugs">
615*8c35d5eeSXin Li
616*8c35d5eeSXin Li  <STYLEPOINT title="Command Substitution">
617*8c35d5eeSXin Li    <SUMMARY>
618*8c35d5eeSXin Li      Use <code>$(command)</code> instead of backticks.
619*8c35d5eeSXin Li    </SUMMARY>
620*8c35d5eeSXin Li    <BODY>
621*8c35d5eeSXin Li      <p>
622*8c35d5eeSXin Li        Nested backticks require escaping the inner ones with <code>\</code>.
623*8c35d5eeSXin Li        The <code>$(command)</code> format doesn't change when nested and is
624*8c35d5eeSXin Li        easier to read.
625*8c35d5eeSXin Li      </p>
626*8c35d5eeSXin Li      <p>
627*8c35d5eeSXin Li        Example:
628*8c35d5eeSXin Li        <CODE_SNIPPET>
629*8c35d5eeSXin Li          # This is preferred:
630*8c35d5eeSXin Li          var="$(command "$(command1)")"
631*8c35d5eeSXin Li
632*8c35d5eeSXin Li          # This is not:
633*8c35d5eeSXin Li          var="`command \`command1\``"
634*8c35d5eeSXin Li        </CODE_SNIPPET>
635*8c35d5eeSXin Li      </p>
636*8c35d5eeSXin Li    </BODY>
637*8c35d5eeSXin Li  </STYLEPOINT>
638*8c35d5eeSXin Li
639*8c35d5eeSXin Li  <STYLEPOINT title="Test, [ and [[">
640*8c35d5eeSXin Li    <SUMMARY>
641*8c35d5eeSXin Li      <code>[[ ... ]]</code> is preferred over <code>[</code>,
642*8c35d5eeSXin Li      <code>test</code> and <code>/usr/bin/[</code>.
643*8c35d5eeSXin Li    </SUMMARY>
644*8c35d5eeSXin Li    <BODY>
645*8c35d5eeSXin Li      <p>
646*8c35d5eeSXin Li        <code>[[ ... ]]</code> reduces errors as no pathname expansion or word
647*8c35d5eeSXin Li        splitting takes place between <code>[[</code> and <code>]]</code> and
648*8c35d5eeSXin Li        <code>[[ ... ]]</code> allows for regular expression matching where
649*8c35d5eeSXin Li        <code>[ ... ]</code> does not.
650*8c35d5eeSXin Li        <CODE_SNIPPET>
651*8c35d5eeSXin Li          # This ensures the string on the left is made up of characters in the
652*8c35d5eeSXin Li          # alnum character class followed by the string name.
653*8c35d5eeSXin Li          # Note that the RHS should not be quoted here.
654*8c35d5eeSXin Li          # For the gory details, see
655*8c35d5eeSXin Li          # E14 at https://tiswww.case.edu/php/chet/bash/FAQ
656*8c35d5eeSXin Li          if [[ "filename" =~ ^[[:alnum:]]+name ]]; then
657*8c35d5eeSXin Li            echo "Match"
658*8c35d5eeSXin Li          fi
659*8c35d5eeSXin Li
660*8c35d5eeSXin Li          # This matches the exact pattern "f*" (Does not match in this case)
661*8c35d5eeSXin Li          if [[ "filename" == "f*" ]]; then
662*8c35d5eeSXin Li            echo "Match"
663*8c35d5eeSXin Li          fi
664*8c35d5eeSXin Li
665*8c35d5eeSXin Li          # This gives a "too many arguments" error as f* is expanded to the
666*8c35d5eeSXin Li          # contents of the current directory
667*8c35d5eeSXin Li          if [ "filename" == f* ]; then
668*8c35d5eeSXin Li            echo "Match"
669*8c35d5eeSXin Li          fi
670*8c35d5eeSXin Li        </CODE_SNIPPET>
671*8c35d5eeSXin Li      </p>
672*8c35d5eeSXin Li    </BODY>
673*8c35d5eeSXin Li  </STYLEPOINT>
674*8c35d5eeSXin Li
675*8c35d5eeSXin Li  <STYLEPOINT title="Testing Strings">
676*8c35d5eeSXin Li    <SUMMARY>
677*8c35d5eeSXin Li      Use quotes rather than filler characters where possible.
678*8c35d5eeSXin Li    </SUMMARY>
679*8c35d5eeSXin Li    <BODY>
680*8c35d5eeSXin Li      <p>
681*8c35d5eeSXin Li        Bash is smart enough to deal with an empty string in a test. So, given
682*8c35d5eeSXin Li        that the code is much easier to read, use tests for empty/non-empty
683*8c35d5eeSXin Li        strings or empty strings rather than filler characters.
684*8c35d5eeSXin Li        <CODE_SNIPPET>
685*8c35d5eeSXin Li          # Do this:
686*8c35d5eeSXin Li          if [[ "${my_var}" = "some_string" ]]; then
687*8c35d5eeSXin Li            do_something
688*8c35d5eeSXin Li          fi
689*8c35d5eeSXin Li
690*8c35d5eeSXin Li          # -z (string length is zero) and -n (string length is not zero) are
691*8c35d5eeSXin Li          # preferred over testing for an empty string
692*8c35d5eeSXin Li          if [[ -z "${my_var}" ]]; then
693*8c35d5eeSXin Li            do_something
694*8c35d5eeSXin Li          fi
695*8c35d5eeSXin Li
696*8c35d5eeSXin Li          # This is OK (ensure quotes on the empty side), but not preferred:
697*8c35d5eeSXin Li          if [[ "${my_var}" = "" ]]; then
698*8c35d5eeSXin Li            do_something
699*8c35d5eeSXin Li          fi
700*8c35d5eeSXin Li
701*8c35d5eeSXin Li          # Not this:
702*8c35d5eeSXin Li          if [[ "${my_var}X" = "some_stringX" ]]; then
703*8c35d5eeSXin Li            do_something
704*8c35d5eeSXin Li          fi
705*8c35d5eeSXin Li        </CODE_SNIPPET>
706*8c35d5eeSXin Li      </p>
707*8c35d5eeSXin Li      <p>
708*8c35d5eeSXin Li        To avoid confusion about what you're testing for, explicitly use
709*8c35d5eeSXin Li        <code>-z</code> or <code>-n</code>.
710*8c35d5eeSXin Li        <CODE_SNIPPET>
711*8c35d5eeSXin Li          # Use this
712*8c35d5eeSXin Li          if [[ -n "${my_var}" ]]; then
713*8c35d5eeSXin Li            do_something
714*8c35d5eeSXin Li          fi
715*8c35d5eeSXin Li
716*8c35d5eeSXin Li          # Instead of this as errors can occur if ${my_var} expands to a test
717*8c35d5eeSXin Li          # flag
718*8c35d5eeSXin Li          if [[ "${my_var}" ]]; then
719*8c35d5eeSXin Li            do_something
720*8c35d5eeSXin Li          fi
721*8c35d5eeSXin Li        </CODE_SNIPPET>
722*8c35d5eeSXin Li      </p>
723*8c35d5eeSXin Li    </BODY>
724*8c35d5eeSXin Li  </STYLEPOINT>
725*8c35d5eeSXin Li
726*8c35d5eeSXin Li  <STYLEPOINT title="Wildcard Expansion of Filenames">
727*8c35d5eeSXin Li    <SUMMARY>
728*8c35d5eeSXin Li      Use an explicit path when doing wildcard expansion of filenames.
729*8c35d5eeSXin Li    </SUMMARY>
730*8c35d5eeSXin Li    <BODY>
731*8c35d5eeSXin Li      <p>
732*8c35d5eeSXin Li        As filenames can begin with a <code>-</code>, it's a lot safer to
733*8c35d5eeSXin Li        expand wildcards with <code>./*</code> instead of <code>*</code>.
734*8c35d5eeSXin Li        <CODE_SNIPPET>
735*8c35d5eeSXin Li          # Here's the contents of the directory:
736*8c35d5eeSXin Li          # -f  -r  somedir  somefile
737*8c35d5eeSXin Li
738*8c35d5eeSXin Li          # This deletes almost everything in the directory by force
739*8c35d5eeSXin Li          psa@bilby$ rm -v *
740*8c35d5eeSXin Li          removed directory: `somedir'
741*8c35d5eeSXin Li          removed `somefile'
742*8c35d5eeSXin Li
743*8c35d5eeSXin Li          # As opposed to:
744*8c35d5eeSXin Li          psa@bilby$ rm -v ./*
745*8c35d5eeSXin Li          removed `./-f'
746*8c35d5eeSXin Li          removed `./-r'
747*8c35d5eeSXin Li          rm: cannot remove `./somedir': Is a directory
748*8c35d5eeSXin Li          removed `./somefile'
749*8c35d5eeSXin Li        </CODE_SNIPPET>
750*8c35d5eeSXin Li      </p>
751*8c35d5eeSXin Li    </BODY>
752*8c35d5eeSXin Li  </STYLEPOINT>
753*8c35d5eeSXin Li
754*8c35d5eeSXin Li  <STYLEPOINT title="Eval">
755*8c35d5eeSXin Li    <SUMMARY>
756*8c35d5eeSXin Li      <code>eval</code> should be avoided.
757*8c35d5eeSXin Li    </SUMMARY>
758*8c35d5eeSXin Li    <BODY>
759*8c35d5eeSXin Li      <p>
760*8c35d5eeSXin Li        Eval munges the input when used for assignment to variables and can set
761*8c35d5eeSXin Li        variables without making it possible to check what those variables
762*8c35d5eeSXin Li        were.
763*8c35d5eeSXin Li        <CODE_SNIPPET>
764*8c35d5eeSXin Li          # What does this set?
765*8c35d5eeSXin Li          # Did it succeed? In part or whole?
766*8c35d5eeSXin Li          eval $(set_my_variables)
767*8c35d5eeSXin Li
768*8c35d5eeSXin Li          # What happens if one of the returned values has a space in it?
769*8c35d5eeSXin Li          variable="$(eval some_function)"
770*8c35d5eeSXin Li        </CODE_SNIPPET>
771*8c35d5eeSXin Li      </p>
772*8c35d5eeSXin Li    </BODY>
773*8c35d5eeSXin Li  </STYLEPOINT>
774*8c35d5eeSXin Li
775*8c35d5eeSXin Li  <STYLEPOINT title="Pipes to While">
776*8c35d5eeSXin Li    <SUMMARY>
777*8c35d5eeSXin Li      Use process substitution or for loops in preference to piping to while.
778*8c35d5eeSXin Li      Variables modified in a while loop do not propagate to the parent
779*8c35d5eeSXin Li      because the loop's commands run in a subshell.
780*8c35d5eeSXin Li    </SUMMARY>
781*8c35d5eeSXin Li    <BODY>
782*8c35d5eeSXin Li      <p>
783*8c35d5eeSXin Li        The implicit subshell in a pipe to while can make it difficult to track
784*8c35d5eeSXin Li        down bugs.
785*8c35d5eeSXin Li        <BAD_CODE_SNIPPET>
786*8c35d5eeSXin Li          last_line='NULL'
787*8c35d5eeSXin Li          your_command | while read line; do
788*8c35d5eeSXin Li            last_line="${line}"
789*8c35d5eeSXin Li          done
790*8c35d5eeSXin Li
791*8c35d5eeSXin Li          # This will output 'NULL'
792*8c35d5eeSXin Li          echo "${last_line}"
793*8c35d5eeSXin Li        </BAD_CODE_SNIPPET>
794*8c35d5eeSXin Li      </p>
795*8c35d5eeSXin Li      <p>
796*8c35d5eeSXin Li        Use a for loop if you are confident that the input will not contain
797*8c35d5eeSXin Li        spaces or special characters (usually, this means not user input).
798*8c35d5eeSXin Li        <CODE_SNIPPET>
799*8c35d5eeSXin Li          total=0
800*8c35d5eeSXin Li          # Only do this if there are no spaces in return values.
801*8c35d5eeSXin Li          for value in $(command); do
802*8c35d5eeSXin Li            total+="${value}"
803*8c35d5eeSXin Li          done
804*8c35d5eeSXin Li        </CODE_SNIPPET>
805*8c35d5eeSXin Li      </p>
806*8c35d5eeSXin Li      <p>
807*8c35d5eeSXin Li        Using process substitution allows redirecting output but puts the
808*8c35d5eeSXin Li        commands in an explicit subshell rather than the implicit subshell that
809*8c35d5eeSXin Li        bash creates for the while loop.
810*8c35d5eeSXin Li        <CODE_SNIPPET>
811*8c35d5eeSXin Li          total=0
812*8c35d5eeSXin Li          last_file=
813*8c35d5eeSXin Li          while read count filename; do
814*8c35d5eeSXin Li            total+="${count}"
815*8c35d5eeSXin Li            last_file="${filename}"
816*8c35d5eeSXin Li          done &lt; &lt;(your_command | uniq -c)
817*8c35d5eeSXin Li
818*8c35d5eeSXin Li          # This will output the second field of the last line of output from
819*8c35d5eeSXin Li          # the command.
820*8c35d5eeSXin Li          echo "Total = ${total}"
821*8c35d5eeSXin Li          echo "Last one = ${last_file}"
822*8c35d5eeSXin Li        </CODE_SNIPPET>
823*8c35d5eeSXin Li      </p>
824*8c35d5eeSXin Li      <p>
825*8c35d5eeSXin Li        Use while loops where it is not necessary to pass complex results
826*8c35d5eeSXin Li        to the parent shell - this is typically where some more complex
827*8c35d5eeSXin Li        "parsing" is required. Beware that simple examples are probably
828*8c35d5eeSXin Li        more easily done with a tool such as awk. This may also be useful
829*8c35d5eeSXin Li        where you specifically don't want to change the parent scope variables.
830*8c35d5eeSXin Li        <CODE_SNIPPET>
831*8c35d5eeSXin Li          # Trivial implementation of awk expression:
832*8c35d5eeSXin Li          #   awk '$3 == "nfs" { print $2 " maps to " $1 }' /proc/mounts
833*8c35d5eeSXin Li          cat /proc/mounts | while read src dest type opts rest; do
834*8c35d5eeSXin Li            if [[ ${type} == "nfs" ]]; then
835*8c35d5eeSXin Li              echo "NFS ${dest} maps to ${src}"
836*8c35d5eeSXin Li            fi
837*8c35d5eeSXin Li          done
838*8c35d5eeSXin Li        </CODE_SNIPPET>
839*8c35d5eeSXin Li      </p>
840*8c35d5eeSXin Li    </BODY>
841*8c35d5eeSXin Li  </STYLEPOINT>
842*8c35d5eeSXin Li
843*8c35d5eeSXin Li</CATEGORY>
844*8c35d5eeSXin Li
845*8c35d5eeSXin Li<CATEGORY title="Naming Conventions">
846*8c35d5eeSXin Li
847*8c35d5eeSXin Li  <STYLEPOINT title="Function Names">
848*8c35d5eeSXin Li    <SUMMARY>
849*8c35d5eeSXin Li      Lower-case, with underscores to separate words. Separate libraries
850*8c35d5eeSXin Li      with <code>::</code>. Parentheses are required after the function name.
851*8c35d5eeSXin Li      The keyword <code>function</code> is optional, but must be used
852*8c35d5eeSXin Li      consistently throughout a project.
853*8c35d5eeSXin Li    </SUMMARY>
854*8c35d5eeSXin Li    <BODY>
855*8c35d5eeSXin Li      <p>
856*8c35d5eeSXin Li        If you're writing single functions, use lowercase and separate words
857*8c35d5eeSXin Li        with underscore. If you're writing a package, separate package names
858*8c35d5eeSXin Li        with <code>::</code>. Braces must be on the same line as the function
859*8c35d5eeSXin Li        name (as with other languages at Google) and no space between the
860*8c35d5eeSXin Li        function name and the parenthesis.
861*8c35d5eeSXin Li        <CODE_SNIPPET>
862*8c35d5eeSXin Li          # Single function
863*8c35d5eeSXin Li          my_func() {
864*8c35d5eeSXin Li            ...
865*8c35d5eeSXin Li          }
866*8c35d5eeSXin Li
867*8c35d5eeSXin Li          # Part of a package
868*8c35d5eeSXin Li          mypackage::my_func() {
869*8c35d5eeSXin Li            ...
870*8c35d5eeSXin Li          }
871*8c35d5eeSXin Li        </CODE_SNIPPET>
872*8c35d5eeSXin Li      </p>
873*8c35d5eeSXin Li      <p>
874*8c35d5eeSXin Li        The <code>function</code> keyword is extraneous when "()" is present
875*8c35d5eeSXin Li        after the function name, but enhances quick identification of
876*8c35d5eeSXin Li        functions.
877*8c35d5eeSXin Li      </p>
878*8c35d5eeSXin Li    </BODY>
879*8c35d5eeSXin Li  </STYLEPOINT>
880*8c35d5eeSXin Li
881*8c35d5eeSXin Li  <STYLEPOINT title="Variable Names">
882*8c35d5eeSXin Li    <SUMMARY>
883*8c35d5eeSXin Li      As for function names.
884*8c35d5eeSXin Li    </SUMMARY>
885*8c35d5eeSXin Li    <BODY>
886*8c35d5eeSXin Li      <p>
887*8c35d5eeSXin Li        Variables names for loops should be similarly named for any variable
888*8c35d5eeSXin Li        you're looping through.
889*8c35d5eeSXin Li        <CODE_SNIPPET>
890*8c35d5eeSXin Li          for zone in ${zones}; do
891*8c35d5eeSXin Li            something_with "${zone}"
892*8c35d5eeSXin Li          done
893*8c35d5eeSXin Li        </CODE_SNIPPET>
894*8c35d5eeSXin Li      </p>
895*8c35d5eeSXin Li    </BODY>
896*8c35d5eeSXin Li  </STYLEPOINT>
897*8c35d5eeSXin Li
898*8c35d5eeSXin Li  <STYLEPOINT title="Constants and Environment Variable Names">
899*8c35d5eeSXin Li    <SUMMARY>
900*8c35d5eeSXin Li      All caps, separated with underscores, declared at the top of the file.
901*8c35d5eeSXin Li    </SUMMARY>
902*8c35d5eeSXin Li    <BODY>
903*8c35d5eeSXin Li      <p>
904*8c35d5eeSXin Li        Constants and anything exported to the environment should be
905*8c35d5eeSXin Li        capitalized.
906*8c35d5eeSXin Li        <CODE_SNIPPET>
907*8c35d5eeSXin Li          # Constant
908*8c35d5eeSXin Li          readonly PATH_TO_FILES='/some/path'
909*8c35d5eeSXin Li
910*8c35d5eeSXin Li          # Both constant and environment
911*8c35d5eeSXin Li          declare -xr ORACLE_SID='PROD'
912*8c35d5eeSXin Li        </CODE_SNIPPET>
913*8c35d5eeSXin Li      </p>
914*8c35d5eeSXin Li      <p>
915*8c35d5eeSXin Li        Some things become constant at their first setting (for example, via
916*8c35d5eeSXin Li        getopts). Thus, it's OK to set a constant in getopts or based on a
917*8c35d5eeSXin Li        condition, but it should be made readonly immediately afterwards.
918*8c35d5eeSXin Li        Note that <code>declare</code> doesn't operate on global variables
919*8c35d5eeSXin Li        within functions, so <code>readonly</code> or <code>export</code> is
920*8c35d5eeSXin Li        recommended instead.
921*8c35d5eeSXin Li      </p>
922*8c35d5eeSXin Li      <CODE_SNIPPET>
923*8c35d5eeSXin Li        VERBOSE='false'
924*8c35d5eeSXin Li        while getopts 'v' flag; do
925*8c35d5eeSXin Li          case "${flag}" in
926*8c35d5eeSXin Li            v) VERBOSE='true' ;;
927*8c35d5eeSXin Li          esac
928*8c35d5eeSXin Li        done
929*8c35d5eeSXin Li        readonly VERBOSE
930*8c35d5eeSXin Li      </CODE_SNIPPET>
931*8c35d5eeSXin Li    </BODY>
932*8c35d5eeSXin Li  </STYLEPOINT>
933*8c35d5eeSXin Li
934*8c35d5eeSXin Li  <STYLEPOINT title="Source Filenames">
935*8c35d5eeSXin Li    <SUMMARY>
936*8c35d5eeSXin Li      Lowercase, with underscores to separate words if desired.
937*8c35d5eeSXin Li    </SUMMARY>
938*8c35d5eeSXin Li    <BODY>
939*8c35d5eeSXin Li      <p>
940*8c35d5eeSXin Li        This is for consistency with other code styles in Google:
941*8c35d5eeSXin Li        <code>maketemplate</code> or <code>make_template</code> but not
942*8c35d5eeSXin Li        <code>make-template</code>.
943*8c35d5eeSXin Li      </p>
944*8c35d5eeSXin Li    </BODY>
945*8c35d5eeSXin Li  </STYLEPOINT>
946*8c35d5eeSXin Li
947*8c35d5eeSXin Li  <STYLEPOINT title="Read-only Variables">
948*8c35d5eeSXin Li    <SUMMARY>
949*8c35d5eeSXin Li      Use <code>readonly</code> or <code>declare -r</code> to ensure they're
950*8c35d5eeSXin Li      read only.
951*8c35d5eeSXin Li    </SUMMARY>
952*8c35d5eeSXin Li    <BODY>
953*8c35d5eeSXin Li      <p>
954*8c35d5eeSXin Li        As globals are widely used in shell, it's important to catch errors
955*8c35d5eeSXin Li        when working with them.  When you declare a variable that is
956*8c35d5eeSXin Li        meant to be read-only, make this explicit.
957*8c35d5eeSXin Li        <CODE_SNIPPET>
958*8c35d5eeSXin Li          zip_version="$(dpkg --status zip | grep Version: | cut -d ' ' -f 2)"
959*8c35d5eeSXin Li          if [[ -z "${zip_version}" ]]; then
960*8c35d5eeSXin Li            error_message
961*8c35d5eeSXin Li          else
962*8c35d5eeSXin Li            readonly zip_version
963*8c35d5eeSXin Li          fi
964*8c35d5eeSXin Li        </CODE_SNIPPET>
965*8c35d5eeSXin Li      </p>
966*8c35d5eeSXin Li    </BODY>
967*8c35d5eeSXin Li  </STYLEPOINT>
968*8c35d5eeSXin Li
969*8c35d5eeSXin Li  <STYLEPOINT title="Use Local Variables">
970*8c35d5eeSXin Li    <SUMMARY>
971*8c35d5eeSXin Li      Declare function-specific variables with <code>local</code>. Declaration
972*8c35d5eeSXin Li      and assignment should be on different lines.
973*8c35d5eeSXin Li    </SUMMARY>
974*8c35d5eeSXin Li    <BODY>
975*8c35d5eeSXin Li      <p>
976*8c35d5eeSXin Li        Ensure that local variables are only seen inside a function and its
977*8c35d5eeSXin Li        children by using <code>local</code> when declaring them. This avoids
978*8c35d5eeSXin Li        polluting the global name space and inadvertently setting variables
979*8c35d5eeSXin Li        that may have significance outside the function.
980*8c35d5eeSXin Li      </p>
981*8c35d5eeSXin Li      <p>
982*8c35d5eeSXin Li        Declaration and assignment must be separate statements when
983*8c35d5eeSXin Li        the assignment value is provided by a command substitution; as
984*8c35d5eeSXin Li        the 'local' builtin does not propagate the exit code from the
985*8c35d5eeSXin Li        command substitution.
986*8c35d5eeSXin Li        <CODE_SNIPPET>
987*8c35d5eeSXin Li          my_func2() {
988*8c35d5eeSXin Li            local name="$1"
989*8c35d5eeSXin Li
990*8c35d5eeSXin Li            # Separate lines for declaration and assignment:
991*8c35d5eeSXin Li            local my_var
992*8c35d5eeSXin Li            my_var="$(my_func)" || return
993*8c35d5eeSXin Li
994*8c35d5eeSXin Li            # DO NOT do this: $? contains the exit code of 'local', not my_func
995*8c35d5eeSXin Li            local my_var="$(my_func)"
996*8c35d5eeSXin Li            [[ $? -eq 0 ]] || return
997*8c35d5eeSXin Li
998*8c35d5eeSXin Li            ...
999*8c35d5eeSXin Li          }
1000*8c35d5eeSXin Li        </CODE_SNIPPET>
1001*8c35d5eeSXin Li      </p>
1002*8c35d5eeSXin Li    </BODY>
1003*8c35d5eeSXin Li  </STYLEPOINT>
1004*8c35d5eeSXin Li
1005*8c35d5eeSXin Li  <STYLEPOINT title="Function Location">
1006*8c35d5eeSXin Li    <SUMMARY>
1007*8c35d5eeSXin Li      Put all functions together in the file just below constants. Don't hide
1008*8c35d5eeSXin Li      executable code between functions.
1009*8c35d5eeSXin Li    </SUMMARY>
1010*8c35d5eeSXin Li    <BODY>
1011*8c35d5eeSXin Li      <p>
1012*8c35d5eeSXin Li        If you've got functions, put them all together near the top of the
1013*8c35d5eeSXin Li        file. Only includes, <code>set</code> statements and setting constants
1014*8c35d5eeSXin Li        may be done before declaring functions.
1015*8c35d5eeSXin Li      </p>
1016*8c35d5eeSXin Li      <p>
1017*8c35d5eeSXin Li        Don't hide executable code between functions. Doing so makes the code
1018*8c35d5eeSXin Li        difficult to follow and results in nasty surprises when debugging.
1019*8c35d5eeSXin Li      </p>
1020*8c35d5eeSXin Li    </BODY>
1021*8c35d5eeSXin Li  </STYLEPOINT>
1022*8c35d5eeSXin Li
1023*8c35d5eeSXin Li  <STYLEPOINT title="main">
1024*8c35d5eeSXin Li    <SUMMARY>
1025*8c35d5eeSXin Li      A function called <code>main</code> is required for scripts long enough
1026*8c35d5eeSXin Li      to contain at least one other function.
1027*8c35d5eeSXin Li    </SUMMARY>
1028*8c35d5eeSXin Li    <BODY>
1029*8c35d5eeSXin Li      <p>
1030*8c35d5eeSXin Li        In order to easily find the start of the program, put the main
1031*8c35d5eeSXin Li        program in a function called <code>main</code> as the bottom most
1032*8c35d5eeSXin Li        function. This provides consistency with the rest of the code base as
1033*8c35d5eeSXin Li        well as allowing you to define more variables as <code>local</code>
1034*8c35d5eeSXin Li        (which can't be done if the main code is not a function). The last
1035*8c35d5eeSXin Li        non-comment line in the file should be a call to <code>main</code>:
1036*8c35d5eeSXin Li        <CODE_SNIPPET>
1037*8c35d5eeSXin Li        main "$@"
1038*8c35d5eeSXin Li        </CODE_SNIPPET>
1039*8c35d5eeSXin Li      </p>
1040*8c35d5eeSXin Li      <p>
1041*8c35d5eeSXin Li        Obviously, for short scripts where it's just a linear flow,
1042*8c35d5eeSXin Li        <code>main</code> is overkill and so is not required.
1043*8c35d5eeSXin Li      </p>
1044*8c35d5eeSXin Li    </BODY>
1045*8c35d5eeSXin Li  </STYLEPOINT>
1046*8c35d5eeSXin Li
1047*8c35d5eeSXin Li</CATEGORY>
1048*8c35d5eeSXin Li
1049*8c35d5eeSXin Li<CATEGORY title="Calling Commands">
1050*8c35d5eeSXin Li
1051*8c35d5eeSXin Li  <STYLEPOINT title="Checking Return Values">
1052*8c35d5eeSXin Li    <SUMMARY>
1053*8c35d5eeSXin Li      Always check return values and give informative return values.
1054*8c35d5eeSXin Li    </SUMMARY>
1055*8c35d5eeSXin Li    <BODY>
1056*8c35d5eeSXin Li      <p>
1057*8c35d5eeSXin Li        For unpiped commands, use <code>$?</code> or check directly via an
1058*8c35d5eeSXin Li        <code>if</code> statement to keep it simple.
1059*8c35d5eeSXin Li      </p>
1060*8c35d5eeSXin Li      <p>
1061*8c35d5eeSXin Li        Example:
1062*8c35d5eeSXin Li        <CODE_SNIPPET>
1063*8c35d5eeSXin Li          if ! mv "${file_list}" "${dest_dir}/" ; then
1064*8c35d5eeSXin Li            echo "Unable to move ${file_list} to ${dest_dir}" &gt;&amp;2
1065*8c35d5eeSXin Li            exit "${E_BAD_MOVE}"
1066*8c35d5eeSXin Li          fi
1067*8c35d5eeSXin Li
1068*8c35d5eeSXin Li          # Or
1069*8c35d5eeSXin Li          mv "${file_list}" "${dest_dir}/"
1070*8c35d5eeSXin Li          if [[ "$?" -ne 0 ]]; then
1071*8c35d5eeSXin Li            echo "Unable to move ${file_list} to ${dest_dir}" &gt;&amp;2
1072*8c35d5eeSXin Li            exit "${E_BAD_MOVE}"
1073*8c35d5eeSXin Li          fi
1074*8c35d5eeSXin Li
1075*8c35d5eeSXin Li        </CODE_SNIPPET>
1076*8c35d5eeSXin Li      </p>
1077*8c35d5eeSXin Li      <p>
1078*8c35d5eeSXin Li        Bash also has the <code>PIPESTATUS</code> variable that allows checking
1079*8c35d5eeSXin Li        of the return code from all parts of a pipe. If it's only necessary to
1080*8c35d5eeSXin Li        check success or failure of the whole pipe, then the following is
1081*8c35d5eeSXin Li        acceptable:
1082*8c35d5eeSXin Li        <CODE_SNIPPET>
1083*8c35d5eeSXin Li          tar -cf - ./* | ( cd "${dir}" &amp;&amp; tar -xf - )
1084*8c35d5eeSXin Li          if [[ "${PIPESTATUS[0]}" -ne 0 || "${PIPESTATUS[1]}" -ne 0 ]]; then
1085*8c35d5eeSXin Li            echo "Unable to tar files to ${dir}" &gt;&amp;2
1086*8c35d5eeSXin Li          fi
1087*8c35d5eeSXin Li        </CODE_SNIPPET>
1088*8c35d5eeSXin Li      </p>
1089*8c35d5eeSXin Li      <p>
1090*8c35d5eeSXin Li        However, as <code>PIPESTATUS</code> will be overwritten as soon as you
1091*8c35d5eeSXin Li        do any other command, if you need to act differently on errors based on
1092*8c35d5eeSXin Li        where it happened in the pipe, you'll need to assign
1093*8c35d5eeSXin Li        <code>PIPESTATUS</code> to another variable immediately after running
1094*8c35d5eeSXin Li        the command (don't forget that <code>[</code> is a command and will
1095*8c35d5eeSXin Li        wipe out <code>PIPESTATUS</code>).
1096*8c35d5eeSXin Li        <CODE_SNIPPET>
1097*8c35d5eeSXin Li          tar -cf - ./* | ( cd "${DIR}" &amp;&amp; tar -xf - )
1098*8c35d5eeSXin Li          return_codes=(${PIPESTATUS[*]})
1099*8c35d5eeSXin Li          if [[ "${return_codes[0]}" -ne 0 ]]; then
1100*8c35d5eeSXin Li            do_something
1101*8c35d5eeSXin Li          fi
1102*8c35d5eeSXin Li          if [[ "${return_codes[1]}" -ne 0 ]]; then
1103*8c35d5eeSXin Li            do_something_else
1104*8c35d5eeSXin Li          fi
1105*8c35d5eeSXin Li        </CODE_SNIPPET>
1106*8c35d5eeSXin Li      </p>
1107*8c35d5eeSXin Li    </BODY>
1108*8c35d5eeSXin Li  </STYLEPOINT>
1109*8c35d5eeSXin Li
1110*8c35d5eeSXin Li  <STYLEPOINT title="Builtin Commands vs. External Commands">
1111*8c35d5eeSXin Li    <SUMMARY>
1112*8c35d5eeSXin Li      Given the choice between invoking a shell builtin and invoking a separate
1113*8c35d5eeSXin Li      process, choose the builtin.
1114*8c35d5eeSXin Li    </SUMMARY>
1115*8c35d5eeSXin Li    <BODY>
1116*8c35d5eeSXin Li      <p>
1117*8c35d5eeSXin Li        We prefer the use of builtins such as the <em>Parameter Expansion</em>
1118*8c35d5eeSXin Li        functions in <code>bash(1)</code> as it's more robust and portable
1119*8c35d5eeSXin Li        (especially when compared to things like sed).
1120*8c35d5eeSXin Li      </p>
1121*8c35d5eeSXin Li      <p>
1122*8c35d5eeSXin Li        Example:
1123*8c35d5eeSXin Li        <CODE_SNIPPET>
1124*8c35d5eeSXin Li          # Prefer this:
1125*8c35d5eeSXin Li          addition=$((${X} + ${Y}))
1126*8c35d5eeSXin Li          substitution="${string/#foo/bar}"
1127*8c35d5eeSXin Li
1128*8c35d5eeSXin Li          # Instead of this:
1129*8c35d5eeSXin Li          addition="$(expr ${X} + ${Y})"
1130*8c35d5eeSXin Li          substitution="$(echo "${string}" | sed -e 's/^foo/bar/')"
1131*8c35d5eeSXin Li        </CODE_SNIPPET>
1132*8c35d5eeSXin Li      </p>
1133*8c35d5eeSXin Li    </BODY>
1134*8c35d5eeSXin Li  </STYLEPOINT>
1135*8c35d5eeSXin Li
1136*8c35d5eeSXin Li</CATEGORY>
1137*8c35d5eeSXin Li
1138*8c35d5eeSXin Li<CATEGORY title="Conclusion">
1139*8c35d5eeSXin Li  <p>
1140*8c35d5eeSXin Li    Use common sense and <em>BE CONSISTENT</em>.
1141*8c35d5eeSXin Li  </p>
1142*8c35d5eeSXin Li  <p>
1143*8c35d5eeSXin Li    Please take a few minutes to read the Parting Words section at the bottom
1144*8c35d5eeSXin Li    of the <a href="cppguide.html">C++ Guide</a>.
1145*8c35d5eeSXin Li  </p>
1146*8c35d5eeSXin Li</CATEGORY>
1147*8c35d5eeSXin Li
1148*8c35d5eeSXin Li<p align="right">
1149*8c35d5eeSXin LiRevision 1.26
1150*8c35d5eeSXin Li</p>
1151*8c35d5eeSXin Li
1152*8c35d5eeSXin Li</GUIDE>
1153