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><script_name></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')]: $@" >&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 <<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 '&&'. 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>;&</code> and <code>;;&</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 < <(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 < <(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}" >&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}" >&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}" && 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}" >&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}" && 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