Size: 12318
Comment:
|
Size: 12415
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 66: | Line 66: |
||<:>`=~` || Check string against extended regex || `[[ $a =~ ^[a-zA-Z0-9][a-zA-Z0-9-_]*$ ]]`|| |
Description
This is a reference for bash scripting. For more general instructions take a look here.
Operators
Usage
Bash operators are mainly used in if statements, to check against a variable or a hard coded object. Example:
File Test Operators
Operator |
Checks for |
Returns |
(-a) |
File exits DEPRECATED |
True if it exits, otherwise false |
-b |
File is a block device |
True if the file is a block device, otherwise false |
-c |
File is a character device |
True if it is a character device, otherwise false |
-d |
File is a directory |
True if it is a directory, otherwise false |
-e |
File exits |
True if it exits, otherwise false |
-ef |
Files are hard links to the same file |
True if files before and after operator are hard links to the same file, otherwise false |
-f |
File is regular file |
True if regular, false if directory, device file, or non existant |
-g |
Set-group-id (sgid) flag set on directory1 |
True if flag is set, otherwise false |
-G |
Group-id of file is equal to the current user's |
True group-id is equal to the user's, otherwise false |
-h |
File is a symbolic link |
True if file is a symbolic link, otherwise false |
-k |
Sticky bit set2 |
True if bit is set, otherwise false |
-L |
File is a symbolic link |
True if file is a symbolic link, otherwise false |
-N |
File is modified since last read |
True file is modified since last read, otherwise false |
-nt |
File is newer than other file |
True if file preceding operator is newer than file behind the operator, otherwise false |
-ot |
File is older than other file |
True if file preceding operator is older than file behind the operator, otherwise false |
-O |
Current user is owner of file |
True if user is owner, otherwise false |
-p |
File is a pipe |
True if file is a pipe, otherwise false |
-r |
File has read permission (for the user running the test) |
True if it has read access, otherwise false |
-s |
File Size |
True if file > 0, otherwise false |
-S |
File is a socket |
True if file is a socket, otherwise false |
-t |
File (descriptor) is associated with a terminal device3 |
True if file is associated with a terminal device, otherwise false |
-u |
Set-user-id (suid) flag set on file4 |
True if flag is set, otherwise false |
-w |
File has write permission (for the user running the test) |
True if it has write access, otherwise false |
-x |
File has execute permission (for the user running the test) |
True if it has execute access, otherwise false |
! |
NOT, reverses the tests above |
True if condition absent, otherwise reverse of condition |
Integer Comparison Operators
Operator |
C-style variant |
Meaning |
Usage |
Usage C-Style |
-eq |
none |
Is equal to |
if [ "$a" -eq "$b" ] |
- |
-ne |
none |
Is not equal to |
if [ "$a" -ne "$b" ] |
- |
-gt |
> |
Is greater than |
if [ "$a" -gt "$b" ] |
(("$a" > "$b")) |
-ge |
>= |
Is greater or equal to |
if [ "$a" -ge "$b" ] |
(("$a" >= "$b")) |
-lt |
< |
Is less than |
if [ "$a" -lt "$b" ] |
(("$a" < "$b")) |
-le |
<= |
Is less than or equal to |
if [ "$a" -le "$b" ] |
(("$a" <= "$b")) |
String Comparison Operators
Operator |
Meaning |
Usage |
= |
Is equal to |
if [ "$a" = "$b" ] |
== |
Is equal to5 |
if [ "$a" == "$b" ] |
!= |
Is not equal to |
if [ "$a" != "$b" ] |
=~ |
Check string against extended regex |
[[ $a =~ ^[a-zA-Z0-9][a-zA-Z0-9-_]*$ ]] |
< |
Is less than, in ASCII alphabetical order |
if [ "$a" \< "$b" ] or if [[ "$a" < "$b" ]] |
> |
Is greater than, in ASCII alphabetical order |
if [ "$a" \> "$b" ] or if [[ "$a" > "$b" ]] |
-z |
string is null(zero length) |
if [ -z "$String" ] |
-n |
string is not null |
if [ -n "$String" ] (always use quotes) |
Arithmetic Operators
Operator |
Name |
Funtion |
+ |
Plus |
3 + 6 = 6 |
- |
Minus |
6 - 3 = 3 |
* |
Multiply |
3 * 3 = 9 |
/ |
Divide |
9 / 3 = 3 |
** |
Exponent |
3 ** 2 = 9 |
% |
Modulo |
24 % 4 = 4 |
Each arithmetic operator can be followed with an equals sign(=), which writes the output of the operation into the first variable. An example:
Logical Comparison Operators
Operator |
Name |
Funtion |
&& |
AND |
"true" && "false" = false |
|| |
OR |
"true" || "false" = true |
! |
NOT |
! "true" = false |
Usage:
Compound Comparison Operators
Bitwise Comparison Operators
Operator |
Name |
Funtion |
& |
AND |
1010 & 1100 = 1000 |
| |
OR |
1010 | 1100 = 1110 |
^ |
XOR |
1010 ^ 1100 = 0110 |
~ |
NOT/Complement |
~1010 = 0101 |
<< |
Left Shift |
1100 << 1 = 1000 |
>> |
Right Shift |
1100 >> 1 = 0110 |
Bitwise operators are usually not used in if statements, but for number manipulation. An example:
Each bitwise operator can be followed with an equals sign(=), which writes the output of the operation into the first variable. An example:
Syntax
Functions
A function in bash can be defined in 2 ways:
or
The () are there just for decoration, not to define arguments. Don't put anything between these. Arguments can be accessed using $1 etc. Arguments passed from the commandline can't be accessed directly from within a function. You should pass these when calling the function, or expose them in a global variable.
Calling
Calling functions is done by calling [result = ]function_name 'argument1' 'argument2'. Don't use parentheses for passing arguments.
Parameter Substitution and Expansion
String Operations
Loops
For loop
Iterate over all passed files
While loop
Loop until condition is true
Special variables
Positional variables
Positional variables can be used within functions or scripts, enumerating arguments passed to them.
Using ${@} or ${@} all positional arguments can be returned, as iterable or as expanded array. The difference is that ${@} expands the variables like this ${1} ${2}.. and ${@} uses ${1}c${2}.. where c is the first character set in IFS.
Script source dir
Sometimes you need the directory in which the script itself is located, for example if you need to copy/make files in that directory. There are a lot of ways to get this directory, however, not all methods still work when the script is called via a symlink. The following line should work in most cases:
A test to check this method can be found here
Executing commands
With executing commands, I mean running a program/command from within a bash script. For example:
Piping output
Piping to /dev/null
When a command should not display any output to the commandline, it is possible to pipe both STDOUT and STRERR to /dev/null
Snippets
Useful pieces of code
Yes/No prompt
1 #!/bin/bash
2 read -p "Do you wish to be evil? (Y/n) " use_systemd
3 [ -z "$use_systemd" ] && use_systemd='yes' # if no input, assume yes
4 case ${use_systemd:0:1} in
5 y|Y|1 ) # Yes
6 echo "Try https://www.google.com";;
7 * ) # No (anything else)
8 echo "Better go to https://duckduckgo.com";;
9 esac
Check if running with sudo
Commandline parameter parser (getopts)
1 #!/bin/bash
2 function help () {
3 echo "Usage: $0 [OPTIONS] <file>"
4 echo "Description of what this command does"
5 echo " -a what option a does"
6 echo " -b what option b does"
7 echo " -c what input c does"
8 echo " -h display this output"
9 exit 1
10 }
11
12 while getopts ':abc:h' opt ; do
13 case "$opt" in
14 a) a_var='true';;
15 b) b_var='true';;
16 c) c_var="${OPTARG}";;
17 h) help ;;
18 :)
19 echo "$0: Must supply an argument to -$OPTARG." >&2
20 exit 1
21 ;;
22 ?)
23 echo "Invalid option: -${OPTARG}."
24 exit 2
25 ;;
26 esac
27 done
28
29 file=${@:$OPTIND:1}
30 output_file=${@:($OPTIND +1):1}
${@:$OPTIND:1} gets the first argument after the options parsed by getopts
${@:($OPTIND +1):1} gets the second, ${@:($OPTIND +2):1} the third etc.
Footnotes
If a directory has the sgid flag set, then a file created within that directory belongs to the group that owns the directory, not necessarily to the group of the user who created the file. This may be useful for a directory shared by a workgroup. (1)
Commonly known as the sticky bit, the save-text-mode flag is a special type of file permission. If a file has this flag set, that file will be kept in cache memory, for quicker access. [3] If set on a directory, it restricts write permission. Setting the sticky bit adds a t to the permissions on the file or directory listing. This restricts altering or deleting specific files in that directory to the owner of those files. (2)
This test option may be used to check whether the stdin [ -t 0 ] or stdout [ -t 1 ] in a given script is a terminal. (3)
A binary owned by root with set-user-id flag set runs with root privileges, even when an ordinary user invokes it. (4)
The == comparison operator behaves differently within a double-brackets test than within single brackets. See this documentation (5)
Apparently && and || "short-circuit" while -a and -o do not. See the bottom of this page (6 7)