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