blob: 79f39f903ed4ee645d7b8d22d58d77be061c03e7 [file] [log] [blame]
mark@chromium.org7cf216c2013-02-15 20:56:05 +00001<?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
mark@chromium.org7b245632013-09-25 21:16:00 +00007Revision 1.26
mark@chromium.org7cf216c2013-02-15 20:56:05 +00008</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
Alexander F Rødseth7ebdcc42016-05-19 23:04:17 +020020
mark@chromium.org7cf216c2013-02-15 20:56:05 +000021
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.
Alexander F Rødseth7ebdcc42016-05-19 23:04:17 +0200172 A
mark@chromium.org7cf216c2013-02-15 20:56:05 +0000173 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
Alexander F Rødseth7ebdcc42016-05-19 23:04:17 +0200185
mark@chromium.org7cf216c2013-02-15 20:56:05 +0000186 </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>
Philip Kirkbridee3d0f562017-05-26 15:45:00 -0400266 This matches the convention in the <a href="cppguide.html?showone=TODO_Comments#TODO_Comments">C++
mark@chromium.org7cf216c2013-02-15 20:56:05 +0000267 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:
Alexander F Rødseth7ebdcc42016-05-19 23:04:17 +0200276
mark@chromium.org7cf216c2013-02-15 20:56:05 +0000277 <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
mark@chromium.org7b245632013-09-25 21:16:00 +0000396 <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
mark@chromium.org7cf216c2013-02-15 20:56:05 +0000463 <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
Ackermann Yuriy79692902016-04-01 21:41:34 +1300655 # E14 at https://tiswww.case.edu/php/chet/bash/FAQ
mark@chromium.org7cf216c2013-02-15 20:56:05 +0000656 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
mark@chromium.org7b245632013-09-25 21:16:00 +0000926 v) VERBOSE='true' ;;
mark@chromium.org7cf216c2013-02-15 20:56:05 +0000927 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
Alexander F Rødseth7ebdcc42016-05-19 23:04:17 +02001144 of the <a href="cppguide.html">C++ Guide</a>.
mark@chromium.org7cf216c2013-02-15 20:56:05 +00001145 </p>
1146</CATEGORY>
1147
1148<p align="right">
mark@chromium.org7b245632013-09-25 21:16:00 +00001149Revision 1.26
mark@chromium.org7cf216c2013-02-15 20:56:05 +00001150</p>
1151
1152</GUIDE>