Bash . . Notes, Version
Total Page:16
File Type:pdf, Size:1020Kb
2.2 Quoting and literals 4. ${#var} returns length of the string. Inside single quotes '' nothing is interpreted: 5. ${var:offset:length} skips first offset they preserve literal values of characters enclosed characters from var and truncates the output Bash 5.1.0 notes, version 0.2.209 within them. A single (strong) quote may not appear to given length. :length may be skipped. between single quotes, even when escaped, but it Negative values separated with extra space may appear between double (weak) quotes "". Remigiusz Suwalski are accepted. ey work quite similarly, with an exception that the 6. uses a default value, if shell expands any variables that appear within them ${var:-value} var August 19, 2021 is empty or unset. (pathname expansion, process substitution and word splitting are disabled, everything else works!). ${var:=value} does the same, but performs an assignment as well. Bash, a command line interface for interacting with It is a very important concept: without them Bash the operating system, was created in the 1980s. splits lines into words at whitespace characters – ${var:+value} uses an alternative value if 1 (Google) shell style guide tabs and spaces. See also: IFS variable and $'...' var isn’t empty or unset! and $"..." (both are Bash extensions, to be done). e following notes are meant to be summary of a 2.4.4 Command substitution style guide written by Paul Armstrong and too many Avoid backticks `code` at all cost! To execute commands in a subshell and then pass more to mention (revision 1.26). 2.3 Variables their stdout (but not stderr!), use $( commands) . Bash is the only shell scripting language permitted Variable names are case sensitive. ey can contain (To group them without new shell, use { cmds }.) for executables. Bash should only be used for simple digits and underscores as well, but a name starting 2.4.5 Arithmetic expansion wrapper scripts or small utilities. with a digit is not allowed. Example: e arithmetic expression $(( ...)) is evaluated Executables should have no extension, libraries var="kind" and expands to the result. Bash guarantees that the must have a .sh extension and should not be echo ${var}ness # kindness output will be a one-word integer. Exit code is zero executable. SUID and SGID are forbidden on shell () output is nonzero. scripts. Special variables: 2.4.6 Process substitution All error messages should go to STDERR, a function 1. $0: name of the script itself. is kind of substitution: and to print out error messages along with other status 2. $1, $2, ...: the first, second, etc. argument. <( ... ) >( ... ) (not specified by POSIX!), where input or output of a information is recommended: shift removes first argument and advances rest of them forward. command appears as a temporary file, is performed err () { 3. $* and $@ denote all positional parameters simultaneously with the following: arithmetic and echo "[$(date +%Y-%m-%d\%T) ]: $@" >&2 ($*: as a single word, $@: as separate strings). parameter expansions, command substitution. } 4. $#: the number of positional parameters. 2.4.7 Word splitting 5. $?: exit status of last executed command. Comments. Start each file with a description of its 2.4.8 File name expansion contents. Any function that is in a library or not both 6. $$: the process ID of the shell. obvious and short, must be commented. Comment 7. $!: the process ID of last executed command. Glob patterns (composed of normal characters and , , ) are not regular expressions! Bash tricky, interesting or important parts of code. Use 2.4 Expansions * ? [...] TODO comments for temporary or good enough but supports extended globs too (X(list) where X is not perfect code and short-term solutions. Eight expansions happen ater splitting command one from ?*+@!). into tokens, in the order that they are expanded. e following are required for any new code: 2.5 Streams 2.4.1 Brace expansion ere are always three default files open: 1. Indent 2 spaces, no tabs. Brace expansion is used when we need to generate 2. Maximum line length is 80 characters. all possible string combinations. Both of the 1. stdin (the keyboard, file descriptor 0), 3. Long pipelines should be split one per line. commands produce the same output: 2. stdout (the screen, file descriptor 1) and 4. Indent case alternatives by 2 spaces. 3. stderr (error messages, file descriptor 2). 5. Always quote strings containing variables, echo {I,really,love,dots}. spaces, command substitutions or shell meta echo I. really. love. dots. ese streams can be redirected: characters, unless unquoted expansion is Warning: it does not expand the variables ($var), 1. cmd > file redirects to a file (overwrites), required. which is done later, but supports ranges (sequences) 2. cmd >> file appends instead, Use quotes rather than filler characters if possible. of characters: 3. m>n (m>&n) redirects a file descriptor to a file Use an explicit path when doing wildcard expansion (or another file descriptor), echo {a..t} 4. redirects stdout and stderr to a file, of filenames. Avoid eval. Use process substitution &>file abcdefghijklmnopqrst or for loops in preference to piping to while. Finally, 5. | (pipe) serves as a command chaining tool. [[ ... ]] is preferred over [ and test. and (maybe zero paded or with an increment rate) Here document is a section of a source code file that integers, assuming the Bash version is 4 or newer: Naming conventions. Function and variable names is treated as if it were a separate file: should be lower case, with underscore to separate echo{01..10..1}. cat <<EOF > /path/to/your/file words. Constants and environment variable names 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. Line to be written in your file. should be all caps, declared at the top of the file. Use 2.4.2 Tilde expansion EOF readonly or declare -r to ensure they’re read only. Declare function specific variables with ere is a tilde expansion as well. e expression Using 'EOF' instead prevents variable expansion. local. A function called main is required for scripts ~[user] expands to the home directory of the 2.6 Control flow statements long enough to contain at least one other function. current (or given) user. e one-line constructs and work not like and, 2.4.3 Parameter expansion && || Other useful resources If you want to understand or (^, _), but the if – then – else statement. Nonzero Bash better, consider one of the following webpages: 1. ${var^}, ${var,}, ${var~} convert first exit status denotes (usually) a failure. 1. character to upper, lower or reverse case http://wiki.bash-hackers.org 2.6.1 Loops 2. http://mywiki.wooledge.org/BashGuide (every, when caret/comma/tilde are doubled). while read myline; do Avoid guides by TLDP!!! is has an impact on every array element. echo "It says ${myline}" 2. , remove ${var#pattern} ${var%pattern} done < some_file 2 Programming in Bash the pattern from the beginning, end of variable (greedy when hash, percent sign are 2.1 Shebang for var in "the first" "the second"; do doubled). Application: extracting parts of a e shebang ( ) at the head of a script indicates an echo "${var}" #! filename. interpreter for execution, as in #!/bin/bash. Lines done starting with a # (with the exception of shebang) are 3. ${var/pattern/string} performs a single for((i=1; i <= 10; i++ )); do comments and thus won’t be executed. Even better (when first slash is doubled: full) search and echo "i = ${i}." is #!/usr/bin/env bash (overflow-16365130). replace operation. done # C-style 1 2.6.2 Conditionals compopt: . ???? See also ack, an optimized for programmers tool Here at least one statement must be specified inside continue: . ???? like grep, at https://beyondgrep.com/ or learn every block, but one can use a single colon (:) as a declare: . ???? Perl. null statement to avoid rewriting the code. dirs: . .???? 4.1 grep – pattern search enginge disown: . ???? if condition; then echo: displays a line of text: e ed command g/re/p was used to globally commands e enables interpretation of backslash escapes, search a regular expression and print. does not output the trailing newline. elif second_condition; then n ??? grep prints lines matching a pattern: some_commands enable: . ???? E interprets pattern as an extended regexp, else eval: . .???? F does not recognize regexps, other_commands exec: . ???? P interprets pattern as a Perl regexp, fi exit: . .???? export: . ???? c prints a count of matching lines instead, select word in "Bash" "Haskell" "Python" false: . ???? m exits ater finding ... matches, do fc: ....................................???? o prints only matched parts of lines, echo "Your language is $word". fg: . ???? n prints line numbers as well, done getopts: . ???? r reads all files under each directory. hash: . ???? ere is also a case instruction: help: . ???? uses a “regexp” pattern, history: . .???? e case $language in obtains patterns from a file, jobs: . ???? f bash) ignores case disctinctions, kill: . ???? i echo "Bourne Again Shell!" inverts the sense of matching, let: . ???? v ;; selects only lines with whole words matches, local: . ???? w python|haskell) x selects matches exactly matching whole line. echo "Python or Haskell!" logout: . ???? mapfile: . ???? ;; prints ... lines of trailing content, popd: . .???? A *) prints ... lines of leading content, printf: . ???? B echo "Unknown language!" C prints ... lines of both contents. ;; # optional pushd: . ???? esac pwd: prints name of current directory. 4.2 sed – stream editor read: . ???? ??? sed filters and transforms text: 2.6.3 Single versus double square brackets readarray: . ???? -e adds a script to the commands to be executed, e [ command is defined by POSIX, ] prevents its readonly: . ???? -i edits files in place. With sufix supplied, further arguments from being used. Double return: . ???? makes backup (sed -i[suffix] ...), brackets, the [[ command, are a Bash extension set: . .???? -n suppresses auto- printing of pattern space, that changes the way text ist being parsed: shit: .