SCRIPTS | |
---|---|
true | returns a successful (zero) return code |
false | returns an unsuccessful (non-zero) return code |
test <condition> | [ <condition> ] | [[ <condition> ]] | evaluates a specified condition and based on its result it returns a successful or unsuccessful exit status; to test the existence of specific files the following options are used with a file name as an argument: -e any file, -f regular file, -b block device, -c character device, -d directory, -h symbolic link, -s file with non-zero size, -r file with read permissions, -w file with write permissions, -x executable file, -u file with an SUID bit, -g file with an SGID bit, -k file with a sticky bit, -p named pipe, <file1> -nt <file2> file1 is newer than file2, <file1> -ot <file2> file1 is older than file2; to test integers the following operators are used: -eq is equal, -ne is not equal, -lt less than, -le less than or equal, -gt greater than, -ge greater than or equal; to test strings: = is equal, != is not equal, -z <string> the length of string is zero, -n <string> the length of string is non-zero; extended testing is provided by operators: -a logical AND (both expressions are true), -o logical OR (at least one expression is true), ! logical NOT (expression is false); [[ ]] provide more advanced expression testing such as <string> = / == <pattern> (the string contains a pattern), <string> != <pattern> (the string does not contain a pattern), <string> =~ <pattern> (the string matches a regular expression), ! <string> =~ <pattern> (the string does not match a regular expression), <string1> < <string2> or <string1> > <string2> (string1 is lexicographically before or after string2) and compound expressions like && to evaluate the second expression if the first is true, || to evaluate the second expression if the first is false and () to group expressions$ test -f *.txt | $ [ -f *.txt ] (return code is 0 if only one file with the ".txt" extension exists) $ [[ -n $(find . -name "*.txt") ]] (return code is 0 if at least one file with the ".txt" extension exists) $ [ ! -d PROD ] (return code is 0 if the directory does not exist) $ [[ abc == *c ]] (return code is 0 if the string "abc" contains a pattern "*c") $ [[ "abc" =~ .*c ]] (return code is 0 if the string "abc" matches a regular expression ".*c") $ [[ a < z ]] (return code is 0 if the string "a" is lexicographically before a string "z") $ [[ $(awk -F ":" '/^root/ {print $4}' /etc/passwd) -eq 0 ]] (return code is 0 if the root user's GID is 0) $ [ $? -ne 0 ] && echo $? (prints the return code of the previous command if it failed) $ [ $PWD = $HOME ] && echo "home" || pwd (prints "home" if the logged-in user is in the home directory, otherwise the path to the working directory is displayed) # duid=$(awk -F ":" '{print $3}' /etc/passwd | sort | uniq -d); [[ -z "$duid" ]] && echo "NONE" || echo "$duid" (prints duplicate UIDs in the system) |
if <list>; then <list>; [elif <list>; then <list>;] ... [else <list>;] fi | if specifies a condition, if true, then then specifies a required action, if not true, elif specifies another condition and then specifies another action, otherwise else specifies an alternative action, the list of conditions is closed with fi#!/bin/bash # The script checks if the logged-in user is root. If the user is root, it prompts for commands. If the user is not root, it informs them that they are not allowed to run the script and exits with an error message. if [[ $EUID -ne 0 ]]; then echo "User '$(whoami)' is not allowed to run ${0##*/}." exit 1 fi read -p "Enter your commands: " commands eval "$commands" echo "Script completed successfully." #!/bin/bash # The script verifies if a specified package is installed. echo -n "Enter the package name: " while read PACKAGE do rpm -q $PACKAGE > /dev/null if [ $? -eq 0 ] then echo "YES, $PACKAGE is installed." else echo "NO, $PACKAGE is not installed." fi . $0 done |
case <word> in <pattern>[|<pattern>]...) <list>;; esac | executes a command based on the match of the word with the pattern; the word represents any variable, the pattern "*" specifies an action if there is no match, the list of patterns is closed with ")" and the group of commands ends with ";;"#!/bin/bash # The script installs, updates or uninstalls a package, depending on the operation. echo -n 'Enter the operation and package: 'read OPERATION PACKAGE case $OPERATION in install) yum install -y $PACKAGE;; update) yum update -y $PACKAGE;; uninstall|remove) yum remove -y $PACKAGE;; *) echo 'Unknown operation. 'echo 'Usage: {install|update|uninstall|remove} <package>';; esac |
read <variable ...> | reads the line from STDIN and splits it into words which are then assigned to the specified number of variables in the corresponding order for further processing; if there are more words than variables, the remaining words and their delimiters are assigned to the last variable, if there are more variables than words, the remaining variables are assigned empty values, -a <indexed_array> specifies an indexed array where the words are assigned to sequential indexes, -n <n> reads only a specified number of characters, -p <prompt> specifies a prompt that is displayed to the user before reading the input, -r suppresses a special meaning of the "\" character, -s does not display any characters on the input, -t <n> sets a time interval in seconds for reading the input$ cat numbers.txt | { read a; read b; read c; echo "$a/$b/$c";} (reads the first three lines of a file and prints them on one line separated by a slash) #!/bin/bash # The script prompts the user for a username and password and confirms its acceptance. echo -n "Username: "; read username echo -n "Password: "; read -s password echo echo "Password for $username submitted." |
while <list1>; do <list2>; done | executes repeatedly "list2" until "list1" returns a successful return code#!/bin/bash # The script opens four terminal screens. i=0 while [ $i -lt 4 ]; do xterm & i=$[$i+1]; done #!/bin/bash # The script creates a file with information about the currently logged-in users in an interval of five minutes. while true; do who > info-$(date | awk '{print $2,$3,$4,$6}' | sed 's/ /_/g').txt sleep 300; done #!/bin/bash # The script prompts the user for the name of the remote computer, on which it runs a command that detects the version of the Linux distribution and saves the result to a file on the local computer. echo -n "Hostname: "; while read hostname; do ssh $hostname 'echo "Linux distribution": $(cat /etc/redhat-release)' > ${hostname}_info && echo -n "Hostname: "; done |
until <list1>; do <list2>; done | executes repeatedly "list2" until "list1" returns an unsuccessful return code#!/bin/bash # The script prints numbers 0–99. a=-1 until [ $a -eq 99 ]; do a=$(expr $a + 1) echo $a; done #!/bin/bash # The script copies files from the home to the web directory, where it creates a new directory every hour, deleting directories older than 30 days if it is more than 90% full. while true; do DISKFUL=$(df -h $WEBDIR | grep "^/" | \ awk '{print $5}' | cut -d "%" -f1 -) until [ $DISKFUL -ge 90 ]; do WEBDIR=/var/www/webcam DATE=$(date +%Y%m%d) HOUR=$(date +%H) mkdir $WEBDIR/"$DATE" while [ $HOUR -ne 00 ]; do PICDIR=/home/user/pics DESTDIR=$WEBDIR/"$DATE"/"$HOUR" mkdir "$DESTDIR" cp $PICDIR/*.jpg "$DESTDIR"/ sleep 3600 HOUR=$(date +%H); done DISKFULL=$(df -h $WEBDIR | grep "^/" | \ awk '{print $5}' | cut -d "%" -f1 -) done TOREMOVE=$(find $WEBDIR -type d -mtime +30) for i in $TOREMOVE; do rm -rf "$i"; done done |
for <variable> [in <word> ...;] do <list>; done | assigns the values of all words or all positional parameters of the script to the variable one by one and executes the list of commands for each of the items#!/bin/bash # The script displays each command-line argument along with its corresponding number. count=1 for arg; do echo "Argument $count: $arg" ((count++)) done #!/bin/bash # The script creates users specified in the "users" file in the working directory, adds them to the "admins" group and assigns the "password" as their password. for user in $(cat users); do useradd -g admins $user echo password | passwd --stdin $user done #!/bin/bash # The script prints the contents of the working directory. for x in $(ls -F) do echo "Directory $(pwd) contains file or directory: $x" done #!/bin/bash # The script counts the number of items in the working directory. POC=0 for name in * do POC=$(($POC+1)) done echo "Directory $(pwd) contains $POC items." #!/bin/bash # The script converts the format of all .tif files to .jpg. for pic in *.tif; do convert "$pic" "$(echo "$pic" | sed 's/\.tif/.jpg/')" done #!/bin/bash # The script checks which of the specified processes are running, prints their names including the number of lines they occupy and finally prints all running processes and the total number of lines. services="httpd pmon lsnr sap" for service in $services do running_processes="$(ps -ef | grep $service | egrep -v 'grep|vnc|client|API')" if [ -n "$running_processes" ] then echo echo $service: echo echo "$running_processes" echo echo "lines: $(echo "$running_processes" | wc -l)" echo echo "==========" fi done echo echo "Summary:" echo ps -ef echo echo "lines: $(ps -ef | wc -l)" #!/bin/bash # The script connects to all servers whose IP addresses are listed in the "servers" file, runs commands on them that find out the hostname and all its IP addresses, and writes the result to a file on the local computer. for ip in $(< servers); do ssh $ip 'hostname; ifconfig | awk '/inet / {print $2}' | grep -v 127.0.0.1' >> servers_info.txt; done #!/bin/bash # The script connects to remote computers, where it installs software for the specified service, which then starts and verifies its status. for x in {a..c}; do echo "=== node${x} ==="; ssh node${x} 'yum install -y device-mapper-multipath; systemctl enable --now multipathd; systemctl status multipathd'; echo; done |
select <variable> [in <word> ...;] do <list>; done | assigns the values of all words or all positional parameters of the script to the variable one by one, the numbered list of which is displayed together with a prompt for the user to enter the item number and then executes a list of commands for the selected item (interactive equivalent to the "for" command); the line read is saved in the variable "REPLY"#!/bin/bash # The script displays a menu of services. After selecting one of them, a submenu of operations that can be performed appears. while true; do PS3="Select the service or quit: " select svc in cups httpd sshd quit do case $svc in cups) PS3="Select the operation or quit: " select opt in start stop restart status quit do case $opt in start) systemctl start cups break;; stop) systemctl stop cups break;; restart) systemctl restart cups break;; status) systemctl status cups break;; quit) break;; *) echo "Invalid option $REPLY" break;; esac done break;; httpd) PS3="Select the operation or quit: " select opt in start stop restart status quit do case $opt in start) systemctl start httpd break;; stop) systemctl stop httpd break;; restart) systemctl restart httpd break;; status) systemctl status httpd break;; quit) break;; *) echo "Invalid option $REPLY" break;; esac done break;; sshd) PS3="Select the operation or quit: " select opt in start stop restart status quit do case $opt in start) systemctl start sshd break;; stop) systemctl stop sshd break;; restart) systemctl restart sshd break;; status) systemctl status sshd break;; quit) break;; *) echo "Invalid option $REPLY" break;; esac done break;; quit) break 2;; *) echo "Invalid option $REPLY";; esac done; done |
break [<n>] | exits definitively the specific cycle within a "for", "while", "until", or "select" loop based on certain criteria, n specifies the number of levels of nested cycles#!/bin/bash # The script executes a loop that should iterate through numbers from 1 to 5, but prematurely exits the loop during the third iteration when the value of the "cycle" variable becomes 3. for cycle in {1..5}; do if [ "$cycle" -eq 3 ]; then echo "Breaking at iteration $cycle" break fi echo "Iteration: $cycle" done echo "Loop ended." |
continue [<n>] | skips the specific cycle within a "for", "while", "until", or "select" loop based on certain criteria and proceeds to the next one, n specifies the cycle level#!/bin/bash # The script executes a loop that should iterate through numbers from 1 to 5, but skips the third iteration when the value of the "cycle" variable becomes 3 and proceeds to the next iteration. for cycle in {1..5}; do if [ "$cycle" -eq 3 ]; then echo "Skipping iteration $cycle" continue fi echo "Iteration: $cycle" done #!/bin/bash # The script converts uppercase letters in file names to lowercase. LIST=$(ls) for name in $LIST; do if [[ $name != *[[:upper:]]* ]]; then continue; fi ORIG=$name NEW=$(echo $name | tr 'A-Z' 'a-z') mv $ORIG $NEW echo "New name for $ORIG is $NEW" done |
getopts <optstring> <name> [<arguments>] | parses (processes) positional parameters (options and arguments) that are passed to a shell script; <optstring> specifies the list of supported option characters, if a character is followed by a colon (:), the option is expected to have an argument, if the first character is preceded by a colon, silent error reporting is used; each time "getopts" is invoked, it obtains the next option from the positional parameters and places the option character in the variable <name>, if the option does not match those defined in <optstring>, "getopts" sets variable <name> to a question mark (?) and, if silent error reporting is used, the option character found is placed in the "OPTARG" variable; if an option requires an argument, "getopts" places that argument in the "OPTARG" variable, if the required argument is not found and silent error reporting is used, a colon is placed in the <name> variable and "OPTARG" is set to the option character found; when executing the script, the options that require an argument must be followed by their arguments before another option is used#!/bin/bash # The script allows to use only strictly defined options and expected arguments for its execution. usage() { echo "Usage: $0 {-x|-y <string>}" exit 1 } [[ ! "$@" =~ -.+ ]] && usage while getopts :xy: option do case $option in x) echo "Option '-x' is used." ;; y) echo "Option '-y' with argument '$OPTARG' is used." ;; \?) echo "Invalid option '-$OPTARG'." usage ;; :) echo "Option '-$OPTARG' requires an argument." usage ;; esac done |
exit [<n>] | exits a script with the specified return code, if not specified, the return code of the script is the return code of the last command executed within the script |
FUNCTIONS | |
---|---|
function <function> { <list>;} | <function> () { <list>;} | defines a function whose contents are enclosed in braces; the function is executed in the current shell and is used especially in cases where a specific operation (sequence of commands) needs to be performed repeatedly; it is executed by entering its name and by default returns the return code of the last executed command, unless otherwise specified by the "return" command; inside the function, a local variable can be defined with the "local" command (it is also inherited into nested functions), if there is a global variable with the same name, it is suppressed in the function; the function can be used permanently (even in future shell executions) by including it in ~/.bashrc; information about arguments passed to scripts or functions is stored in special variables ("$#" = total number of arguments, "$<n>" = specified argument in order ranging from 1–9, "${<n>}" = specified argument in order in any range, "$*" or "$@" = all arguments)# The "test" function creates a file that is specified as an argument and sets appropriate permissions to it. If a file with the same name already exists or the specified name contains only a space or is completely missing, an error message is displayed. function test { if ! [[ -e $* || $* = '' ]]; then touch $*; chmod 755 $* else echo "Error" fi echo "Number of arguments: $#" echo "All arguments: $*" echo "Second argument: $2" } # The "user" function checks if the user specified as an argument exists in the system and, if so, prints detailed information about the user. user () { if [ $(grep -ic ^$1 /etc/passwd) -eq 0 ]; then echo "User $1 does not exist." else echo "User $1 exists." && finger $1 fi } # The "percentage" function calculates the percentage value of the second numeric argument from the first one, where the first argument represents a value of 100%. percentage () { local x=$1 y=$2 printf "$x = 100% %\n$y = x% %\n" echo "$y = $[$(( 100 * $y )) / $x]% from $x" } # The "usage" function prints possible options to execute the script, if no valid option has been used, it returns a return code 1. usage () { echo "Usage: $0 {-start|-stop|-restart}"; exit 1;} |
local [<variable>[=<value>] ...] | defines a local function variable, -a specifies an indexed array, -A specifies an associative array; with no argument all local function variables are displayed |
return [<n>] | exits a function with the specified return code, if not specified, the return code of the function is the return code of the last command executed within the function |