takeaway

Because shell scripting syntax is flexible and shell scripting developers are familiar with different programming languages, it is easy to write different styles of code. It’s fine if you’re using it alone, but if you’re working on the same project, different code styles can cause a lot of trouble. So it is necessary to agree on a code style.

The code style conventions in this article are my personal suggestions and can be adjusted to suit your needs or preferences. The code style conventions in this article also apply to bash to some extent.

Note that it is necessary for people with rich shell programming experience to formulate and maintain code style conventions, otherwise it is easy to fail to implement or become a mere formality and fail to solve practical problems. Code style conventions need to not only dictate how code should be written, but also explain why it should be written that way, otherwise it’s easy to be unpopularised.

The indentation

  • Use 4 Spaces for indentation.

The reason:

  1. Use Spaces instead of tabs. Because it’s on the terminalcat less diffSome commands are not configurable (and even if they were, it would be a hassle to get all the machine configurations synchronized). If you set the TAB to 4 or 2 Spaces in the editor, the TAB andcat lessCommand display methods are inconsistent, resulting in a lot of trouble.
  2. Eight Spaces is too long, a few indentations will result in lines that are too long, and a shell script should not be too long.
  3. Two Spaces, if you indent it a lot, it looks like a lot of work. In addition, if you accidentally write more code or missing a space, in some scenarios, without looking at the logic, it is impossible to determine whether there is one more or one less, which is more likely to lead to the wrong modification by others, or the more the code is changed, the more chaotic.
  4. The problem that 4 Spaces can cause too many indent levels to be too long is solved by modifying the logic to reduce indent levels or folding methods rather than reducing the number of indent Spaces.

Maximum number of characters per line of code

  • For non-special scenarios, each line of code contains a maximum of 100 characters.

The reason:

  1. The code is too long to read easilydiffTools like this are not convenient for code analysis, so you need to agree on the maximum number of characters.
  2. The classic 80-character convention was a standard that was limited by the output devices of the time, but today’s screens are mostly widescreen and the terminal emulators are adjustable (instead of fixed 80×24). There is no need to adapt to the old standard and waste screen space. And if you use an 80-character convention, it’s easy to have to fold lines, which can lead to a loss of readability.
  3. If a line is more than 100 characters long, it usually indicates too much logic and needs to be split or folded.
  4. Some special scenarios, such as displaying an ASCII character picture, require a line of more than 100 characters, so the convention that each line must be less than 100 characters cannot be strictly enforced. If line splitting or folding inevitably leads to code readability, then readability is a priority.

Fold line

  • Add a space and at the end of the previous line\Fold the line, indent the line one layer (4 Spaces).
  • If you indent a block of text, you can use either an aligned indent or a fixed indent of 4 Spaces.
  • If it is inaa && bb || cc,[[]]or(())The folding line,&& ||Put it at the beginning of the next line.

The reason:

  1. Indentation and normal indentation are both intended to represent progressive code, and there is no need to treat them differently (such as two layers of indentation).
  2. If you want to look good, use aligned indentation instead of fixed indentation. So because everyone’s aesthetic is different, it’s easy to have different indentation methods, resulting in unnecessary trouble. But it’s special for text blocks, because alignment indentation is usually not controversial.
  3. &&||It logically belongs to the second half of the statement, even in natural language, for exampleTomorrow I'll go to the park or go shopping, if you need to break it into two clauses, then yesTomorrow I'll go to the park or go shoppingRather thanTomorrow I'll go to the park or I'll go shopping. The same is true for code. And the&&||It’s easier to align at the beginning of the line and looks more comfortable.

The blank space

  • Logically unnecessary consecutive Spaces are not allowed in scenarios outside of indentation and alignment.
  • + && |There is a space around the isomeric operator.
  • ! ~There is no space between an equal unary operator and an object.
  • ( )(()) {}No space inside,[[]]Add a space inside because of syntax requirements.
  • ;No space before, a space after.
  • When defining a function (and when(())), the function name and(No Spaces are added between.
  • if whileAdd a space between the following keyword and the keyword.
  • if [[ ]] {And so on,{And add a space between the preceding content.
  • Variables and[]Without Spaces, use[]When I take an array or hash table,[]There is no space inside.
  • > <There is no space between the redirection symbol and the file or file descriptor.

The reason:

  1. Adding white space in moderation makes your code clearer and easier to read.
  2. These conventions basically belong to the conventions of code styles in many programming languages and conform to the aesthetic taste of most people.

A blank line

  • In non-special scenarios, no more than two consecutive blank lines are allowed.
  • #! /bin/zshAdd a blank line after it.
  • if whileAdd a blank line after the statement block.
  • Define a function followed by a blank line.
  • Add one or two blank lines between two lines (or two pieces) of code that are logically weak, depending on how strong the relationship is (at your discretion).

The reason:

  1. Adding white space in moderation allows code logic to be separated by empty lines, improving readability.
  2. Because there are so many factors involved in adding blank lines, it’s hard to specify, and it’s up to the developer to decide.

parentheses

  • This parameter is not used in conditional scenarios[]with[[]]Instead.
  • In numerical computation scenarios, use$(())Rather than$[].

The reason:

  1. In the judgment condition scenario,[]The function of[[]]Rich, and the use of the two differences, mixed use is easy to cause problems.
  2. In numerical comparison or calculation scenarios,$[]The function of$(())Rich, mixed use can be problematic.
  3. []If functions are inconsistent in various places, avoid unnecessary scenarios.

constant

  • String constants can be quoted without or without special symbols.
  • When numeric values are used, they are not enclosed in quotation marks.

The reason:

  1. If any string constant is quoted at both ends, it tends to saturate the code with quotation marks, affecting readability. If you delete quotation marks by mistake, it is difficult to locate errors.
  2. Unlike many other programming languages, shell scripts have a lot of logic for handling strings, and enclosing every string constant in quotes adds a lot of extra work.

variable

  • with$varWhen taking a variable value, do not enclose double quotation marks unless you need to convert a non-string variable to a string.
  • In optional scenarios, you do not need to add${var}Braces in.
  • Variables must be explicitly specified as local variables before they are usedlocalDefinition) or global variables (withtypeset -gDefinition).
  • Use local variables wherever they are availablelocalDefinition).
  • Words in variable names can be underlined or humped, and all lowercase letters can be used without compromising readability, but must be consistent in the same file.

The reason:

  1. Unlike bash, ZSH is in use$varWhen reading the contents of a variable, there are no logical errors because the variable does not exist, the value is empty, and the variable contains special symbols, so there is no need to put double quotation marks around the variable.
  2. with$varReading variables is a common use in many programming languages, while${var}Almost unique to the shell, and more cumbersome to type, there is no need to generalize this usage. And when you write code, you can recognize the error in conflating variable names because you don’t have to increase the parentheses, regardless of the external input, and you don’t need to type a lot of extra braces to avoid problems that don’t exist.
  3. If you do not specify whether a variable is global or local, and the default is global, it is sometimes difficult to simply determine whether a variable is used as a global or local variable, which can cause a lot of trouble for script maintainers.
  4. If global variables are used where local variables can be used, it is more likely that global variables have the same name and influence each other to cause errors. Such errors are difficult to detect (because they don’t generate syntax errors, they tend to be suspicious of the code logic, rather than checking for global variable names), and often waste a lot of time for developers or testers.
  5. Developers of different programming languages have different preferences for variable names, so it is not appropriate to specify a uniform style.

quotes

  • You can add double or single quotation marks around a string constant, but the style must be the same in the same file.

The reason:

  1. Double quotation marks and single quotation marks have different functions, so mixing them is inevitable.
  2. In scenarios where both double and single quotation marks apply, using one quotation mark makes code cleaner and easier to read.
  3. Developers with different programming language backgrounds have different preferences for single and double quotation marks. Therefore, it is not advisable to specify the default quotation marks.

function

  • You can usename()orfunction name()Define functions, but keep the style consistent within the same file.

The reason:

  1. If the agreement is used uniformlyname()By defining functions, you’re not in the habit of accommodating developers of programming languages like JavaScript, andfunctionKeywords help code search.
  2. If the agreement is used uniformlyfunction name()To define a function, an additional 9 characters are required, but the meaning is limited, and the input is larger than the output.

Script line number

  • For non-special scenarios, a script file cannot exceed 1000 lines.

The reason:

  1. Because of the nature of shell scripts, a single script file that is too long can cause problems (such as global variables affecting each other). 1000 lines of code is sufficient for most scenarios.
  2. If you are writing a script that needs to be distributed, such as an installation script, it is much easier to distribute a single file than multiple files (which require extra work such as packaging and unpacking), which may require writing long scripts. Therefore, it is not advisable to impose the maximum number of lines for a script file.

Statement style

  • Condition, loop, select, and so on, you can use the style in this series of tutorials, or you can use the POSIX shell style, but the same style for the same file.

The reason:

  1. The style of Chinese statements in this series is simple and easy to understand, and is similar to that of C, Java, JavaScript, and other languages.
  2. Developers migrating from Bash are used to USING POSIX shell style statements, which requires some consideration.

Examples of statement style in this tutorial series:

if[[...]] {}elif((...). ) {}else{}case $i{ (a) ... ;; (*)... ;; }Copy the code

POSIX Shell statement style examples:

if[[...]].then
elif((...). );then
else
fi

case $i in(a) ... ;; (*)... ;;esacCopy the code

conclusion

This article describes my suggested ZSH code style for appropriate reference.

Full article address: github.com/goreliu/zsh…

Pay to solve Windows, Linux, Shell, C, C++, AHK, Python, JavaScript, Lua and other fields related problems, flexible pricing, welcome to consult, wechat LY50247.