info
https://opensource.com/article/18/3/creating-bash-completion-script
COMPREPLY
an array variable used to store the completions. The completion mechanism uses this variable to display its contents as completions
COMPREPLY=( $(compgen -W "now tomorrow never" -- ${COMP_WORDS[COMP_CWORD]}) ) # propose given words at each let choose the first completion from given words and repeat it after (replace)
COMPREPLY=( $(compgen -W "now tomorrow never" "${COMP_WORDS[1]}") ) # let choose the first completion from given words and repeat it after (replace)
complete
complete command to register this list for completion
complete -A directory $cmd # provide completion for directory
complete -d $cmd # provide completion for directory
complete -D $cmd # provide completion for directory
complete -f $cmd # provide completion for file
complete -W "$words" $cmd # Wordlist, provide the list of words for completion to command $cmd
complete -F _foo $cmd # use function _foo_comp to register completions for command $cmd
compopt
https://helpmanual.io/man1/bash/
variables
COMP_WORDS # an array of all the words typed after the name of the program the compspec belongs to
COMP_CWORD # an index of the COMP_WORDS array pointing to the word the current cursor is at—in other words
COMP_LINE # the current command line
tricks
exec bash # reload completions
examples
qemu-img
#!/usr/bin/env bash
_qemuimg_comp()
{
COMPREPLY=()
local cur=${COMP_WORDS[COMP_CWORD]}
local prev="${COMP_WORDS[COMP_CWORD-1]}"
local opts='amend bench bitmap check commit compare convert create dd info map measure snapshot rebase resize'
local formats='blkdebug blklogwrites blkverify bochs cloop compress copy-before-write copy-on-read dmg file ftp ftps gluster host_cdrom host_device http https iscsi iser luks nbd nfs null-aio null
-co nvme parallels preallocate qcow qcow2 qed quorum raw rbd replication snapshot-access ssh throttle vdi vhdx vmdk vpc vvfat'
#echo "COMP_LINE=$COMP_LINE" >> /tmp/qemu
#echo "COMP_WORDS=$COMP_WORDS[@] | COMP_CWORD=$COMP_CWORD" >> /tmp/qemu
#echo "cur=$cur | prev=$prev" >> /tmp/qemu
if [ ${COMP_CWORD} -eq 1 ]; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}" ) )
return 0
elif [[ $prev =~ -[oOf] ]]; then
COMPREPLY=( $(compgen -W "${formats}" -- "${cur}" ) )
else
COMPREPLY=( $(compgen -f -- "${cur}") )
if [ -d "${COMPREPLY}" ]; then
compopt -o nospace
COMPREPLY=${COMPREPLY}/
fi
fi
} &&
complete -F _qemuimg_comp qemu-img
haconf
#!/usr/bin/env bash
#
# Bash completion function for the 'haconf' command.
_haconf()
{
local cur prev path_enabled path_available opts
path_enabled="/etc/haproxy/conf-enabled"
path_available="/etc/haproxy/conf-available"
__disabled() {
local confs conf notused
confs="$(ls "${path_available}")"
for conf in ${confs}; do
! [ -h "${path_enabled}/${conf}" ] && notused="${notused} ${conf}"
done
echo ${notused}
}
__enabled() {
ls ${path_enabled}
}
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
# primary commans
opts='check clear enable disable list reload'
# level 1 for commands
if [ $COMP_CWORD -eq 1 ]; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
# level 2 for arguments
else
case $prev in
enable)
COMPREPLY=( $(compgen -W "$(__disabled)" -- "$cur" ) )
return 0
;;
disable)
COMPREPLY=( $(compgen -W "$(__enabled)" -- "$cur" ) )
return 0
;;
esac
fi
}
complete -F _haconf haconf
COLOR
base
# normal
m=0; for i in {16..128}; do echo -en "\e[${m};${i}m${i}\e[0m" ; done; echo
# bold
m=1; for i in {16..128}; do echo -en "\e[${m};${i}m${i}\e[0m" ; done; echo
# all
for j in {0..5}; do echo "- ${j}"; for i in {16..256}; do echo -en "\e[${j};${i}m${i}\e[0m" ; done; echo; done; echo
256
for i in {16..255}; do echo -en "$i \e[38;5;${i}m#\e[0m" ; done; echo
MAN
synopsis
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
sed [-options] [commande] [] sed [-n [-e commande] [-f script] [-i[.extension]] [l [cesure]] rsu] [] []
[adresse[,adresse]][!]commande[arguments]
[adresse[,adresse]]{
commande1
commande2;commande3
}
options
-n, --quiet, --silent # suppress automatic printing of pattern space
-e script, --expression=script # add the script to the commands to be executed
-f script-file, --file=script-file # add the contents of script-file to the commands to be executed
--follow-symlinks # follow symlinks when processing in place
-i[SUFFIX], --in-place[=SUFFIX] # edit files in place (makes backup if SUFFIX supplied)
-l N, --line-length=N # specify the desired line-wrap length for the `l' command
--posix # disable all GNU extensions
-E, -r, --regexp-extended # use extended regular expressions in the script (for portability use POSIX -E)
-s, --separate # consider files as separate rather than as a single, continuous long stream
--sandbox # operate in sandbox mode
-u, --unbuffered # load minimal amounts of data from the input files and flush the output buffers more often
-z, --null-data # separate lines by NUL characters
--help # display this help and exit
--version # output version information and exit
Zero-address ``commands''
: label # Label for b and t commands
'#'comment # The comment extends until the next newline (or the end of a -e script fragment)
} # The closing bracket of a { } block
Zero- or One- address commands
= # Print the current line number
a \text # Append text, which has each embedded newline preceded by a backslash
i \text # Insert text, which has each embedded newline preceded by a backslash
c \text # Replace text, which has each embedded newline preceded by a backslash
q [exit-code] # Immediately quit the sed script without processing any more input, except that if auto-print is not disabled the current pattern space will be printed
Q [exit-code] # Immediately quit the sed script without processing any more input
r filename # Append text read from filename
R filename # Append a line read from filename. Each invocation of the command reads a line from the file. This is a GNU extension
Commands which accept address ranges
{ # Begin a block of commands (end with a })
b label # Branch to label; if label is omitted, branch to end of script
c \text # Replace the selected lines with text, which has each embedded newline preceded by a backslash
d # Delete pattern space. Start next cycle
D # If pattern space contains no newline, start a normal new cycle as if the d command was issued. Otherwise, delete text in the pattern space up to the first newline, and restart cycle with the resultant pattern space, without reading a new line of input
h H # Copy/append pattern space to hold space
g G # Copy/append hold space to pattern space
l # List out the current line in a ``visually unambiguous'' form
l width # List out the current line in a ``visually unambiguous'' form, breaking it at width characters. This is a GNU extension
n N # Read/append the next line of input into the pattern space
p # Print the current pattern space
P # Print up to the first embedded newline of the current pattern space
s/regexp/replacement/ # Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the special character & to refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp
t label # If a s/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label; if label is omitted, branch to end of script
T label # If no s/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label; if label is omitted, branch to end of script. This is a GNU extension
w filename # Write the current pattern space to filename
W filename # Write the first line of the current pattern space to filename. This is a GNU extension
x # Exchange the contents of the hold and pattern spaces
y/source/dest/ # Transliterate the characters in the pattern space which appear in source to the corresponding character in dest
Addresses
Sed commands can be given with no addresses, in which case the command will be executed for all input lines; with one address, in which case the command will only be executed for input lines which match that address; or with two addresses, in which case the command will be executed for all input lines which match the inclusive range of lines starting from the first address and continuing to the second address. Three things to note about address ranges: the syntax is addr1,addr2 (i.e., the addresses are separated by a comma); the line which addr1 matched will always be accepted, even if addr2 selects an earlier line; and if addr2 is a regexp, it will not be tested against the line that addr1 matched
After the address (or address-range), and before the command, a ! may be inserted, which specifies that the command shall only be executed if the address (or address-range) does not match
The following address types are supported:
number # Match only the specified line number (which increments cumulatively across files, unless the -s option is specified on the command line)
first~step # Match every step'th line starting with line first. For example, ``sed -n 1~2p'' will print all the odd-numbered lines in the input stream, and the address 2~5 will match every fifth line, starting with the second. first can be zero; in this case, sed operates as if it were equal to step. (This is an extension.)
$ # Match the last line
/regexp/ # Match lines matching the regular expression regexp
\cregexpc # Match lines matching the regular expression regexp. The c may be any character
GNU sed also supports some special 2-address forms:
0,addr2 # Start out in "matched first address" state, until addr2 is found. This is similar to 1,addr2, except that if addr2 matches the very first line of input the 0,addr2 form will be at the end of its range, whereas the 1,addr2 form will still be at the beginning of its range. This works only when addr2 is a regular expression
addr1,+N # Will match addr1 and the N lines following addr1
addr1,~N # Will match addr1 and the lines following addr1 until the next line whose input line number is a multiple of N
https://ss64.com/bash/syntax.html
SYNTAX
command > filename # Redirect command output (stdout) into a file
command > /dev/null # Discard stdout of command
command 2> filename # Redirect error output (stderr) to a file
command 2>&1 filename # Redirect stderr to stdout
command 1>&2 filename # Redirect stdout to stderr
command >> filename # Redirect command output and APPEND into a file
command < filename # Redirect a file into a command
command1 < (command2) # Redirect the output of command2 as file input to command1
command1 | tee filename | command2 # Redirect command1 into filename AND command2
command1 | command2 # Redirect stdout of command1 to command2
command1 |& command2 # Redirect stdERR of command1 to command2
command1 & command2 # Run command1 and then run command2 (asynchronous).
command1 ; command2 # Run command1 and afterwards run command2 (synchronous)
command1 && command2 # Run command2 only if command1 is successful (synchronous AND)
command1 || command2 # Run command2 only if command1 is NOT successful
command & # Run command in a subshell.
command &> filename # Redirect every output of command to filename
command > >(tee -a filename1 filename2) # Redirect command output (stdout) to stdout and into filename1 and filename2
# noclobber option can prevent overwriting an existing file
$ set -o noclobber turns ON noclobber
$ set +o noclobber turns OFF noclobber
[n]<word # Redirection of input causes the file whose name results from the expansion of word to be opened for reading on file descriptor n, or the standard input (file descriptor 0) if n is not specified.
[n]>[|]word # Redirection of output causes the file whose name results from the expansion of word to be opened for writing on file descriptor n, or the standard output (file descriptor 1) if n is not specified. If the file does not exist it is created; if it does exist it is truncated to zero size. If the redirection operator is '>', and the noclobber option to the set builtin has been enabled, the redirection will fail if the file whose name results from the expansion of word exists and is a regular file. If the redirection operator is '>|', or the redirection operator is '>' and the noclobber option is not enabled, the redirection is attempted even if the file named by word exists.
[n]>>word # Redirection of output in this fashion causes the file whose name results from the expansion of word to be opened for appending on file descriptor n, or the standard output (file descriptor 1) if n is not specified. If the file does not exist it is created.
# There are three formats for redirecting standard output and standard error:
&>word
>&word
>word 2>&1
ls > dirlist 2>&1 # directs both standard output (file descriptor 1) and standard error (file descriptor 2) to the file dirlist, while the command
ls 2>&1 > dirlist # directs only the standard output to file dirlist, because the standard error was duplicated as standard output before the standard output was redirected to dirlist.
DESCRIPTOR
exec 3< echolist # for reading
exec 3<&-
exec 3>&- # for writing
exec 3<&1.
exec 2> >(tee -a /tmp/2) > >(tee -a /tmp/1) 4>&1 # duplicate stderror & stdout in files & 4 in 1
examples
echo 1234567890 > $file # Write string to file
exec 3<> $file # Open $file and assign fd 3 to it
read -n 4 <&3 # Read only 4 characters
echo -n , >&3 # Write a decimal point there
exec 3>&- # Close fd 3
cat $file # show 1234.67890
SPECIAL FILE FOR REDIRECTIONS
/dev/fd/fd # If fd is a valid integer, file descriptor fd is duplicated
/dev/stdin # File descriptor 0 is duplicated
/dev/stdout # File descriptor 1 is duplicated
/dev/stderr # File descriptor 2 is duplicated
/dev/tcp/host/port # If host is a valid hostname or Internet address, and port is an integer port number, Bash attempts to open a TCP connection to the corresponding socket
/dev/udp/host/port # If host is a valid hostname or Internet address, and port is an integer port number, Bash attempts to open a UDP connection to the corresponding socket
HERE DOCUMENTS
This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input for a command. If the redirection operator is '<<-', then all leading tab characters are stripped from input lines and the line containing delimiter. This allows here-documents within shell scripts to be indented in a natural fashion
<<[-]word
here-document
word
HERE STRINGS
A here string can be considered as a stripped-down form of a here document.
It consists of nothing more than command <<<$word, where $word is expanded and fed to the stdin of command.
command <<<$word
command <<<"$word" # keep formatting
DUPLICATING FILE DESCRIPTORS
[n]<&word
Is used to duplicate input file descriptors. If word expands to one or more digits, the file descriptor denoted by n is made to be a copy of that file descriptor. If the digits in word do not specify a file descriptor open for input, a redirection error occurs. If word evaluates to '-', file descriptor n is closed. If n is not specified, the standard input (file descriptor 0) is used
[n]>&word
Is used similarly to duplicate output file descriptors. If n is not specified, the standard output (file descriptor 1) is used. If the digits in word do not specify a file descriptor open for output, a redirection error occurs. As a special case, if n is omitted, and word does not expand to one or more digits, the standard output and standard error are redirected as described previously
THE REDIRECTION OPERATOR
[n]<>word
causes the file whose name is the expansion of word to be opened for both reading and writing on file descriptor n, or on file descriptor 0 if n is not specified. If the file does not exist, it is created.
PROCESS SUBSTITUTION
>(commands) & <(commands)
The process list is run with its input or output connected to a FIFO or some file in /dev/fd. The name of this file is passed as an argument to the current command as the result of the expansion. If the >(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output of list. Note that no space can appear between the < or > and the left parenthesis, otherwise the construct would be interpreted as a redirection.
examples
$(< file) is faster than $(cat file)
COMMAND EDITING
ctrl+ a # go to the start of the command line
ctrl+ e # go to the end of the command line
ctrl+ k # delete from cursor to the end of the command line
ctrl+ u # delete from cursor to the start of the command line
ctrl+ w # delete from cursor to start of word (i.e. delete backwards one word)
ctrl+ y # paste word or text that was cut using one of the deletion shortcuts (such as the one above) after the cursor
ctrl+ xx # move between start of command line and current cursor position (and back again)
alt+ b # move backward one word (or go to start of word the cursor is currently on)
alt+ f # move forward one word (or go to end of word the cursor is currently on)
alt+ d # delete to end of word starting at cursor (whole word if cursor is at the beginning of word)
alt+ c # capitalize to end of word starting at cursor (whole word if cursor is at the beginning of word)
alt+ u # make uppercase from cursor to end of word
alt+ l # make lowercase from cursor to end of word
alt+ t # swap current word with previous
ctrl+ f # move forward one character
ctrl+ b # move backward one character
ctrl+ d # delete character under the cursor
ctrl+ h # delete character before the cursor
ctrl+ t # swap character under cursor with the previous one
COMMAND RECALL
ctrl+ r # search the history backwards
ctrl+ g # escape from history searching mode
ctrl+ p # previous command in history (i.e. walk back through the command history)
ctrl+ n # next command in history (i.e. walk forward through the command history)
alt+ . # use the last word of the previous command
COMMAND CONTROL
ctrl+ l # clear the screen
ctrl+ s # stops the output to the screen (for long running verbose command)
ctrl+ q # allow output to the screen (if previously stopped using command above)
ctrl+ c # terminate the command
ctrl+ z # suspend/stop the command
BASH BANG COMMAND !
!! # run last command
!blah # run the most recent command that starts with ‘blah’ (e.g. !ls)
!blah:p # print out the command that !blah would run (also adds it as the latest command in the command history)
!$ # the last word of the previous command (same as alt+ .)
!$:p # print out the word that !$ would substitute
!* # the previous command except for the last word (e.g. if you type ‘_find somefile.txt /’, then !* would give you ‘_find somefile.txt’)
!*:p # print out what !* would substitute
PROCESS
!Important you have to launch command with & in start to allow run/stop processes
ps # Get a listing of processes running on the system
jobs # Display a list of current children jobs running in the background
fg ID # Move a background children process into the foreground
bg ID # Move a process into background & start it if a process are already in background
ctrl+z # Pause the current foreground process & move it into the background
kill %ID # End the background running process by his id
nohup $CMD & # Launch in detached process command
wait # Suspend script execution until all children processes running in background have terminated
wait $PID # Suspend script execution until the process with PID id have terminated
cat >pipe # read from stdin
ctrl+d # send EOF to pipe
JOBS
# Display status of jobs
jobs
-l # lists all informations about all processes
-n # lists only processes that have changed status since the last notification
-p # lists PIDs
-r # restrict output to running jobs
-s # restrict output to stopped jobs
job identifier
%N # Job number [N]
%S # Invocation (command-line) of job begins with string S
%?S # Invocation (command-line) of job contains within it string S
%% # "current" job (last job stopped in foreground or started in background)
%+ # "current" job (last job stopped in foreground or started in background)
%- # Last job
$! # Last background process
DISOWN
# unbind jobs from current shell & jobs control; kepp ONLY running jobs
disown
-a # remove all jobs
-h # remobe BUT hold it in jobs control
-r # remove only running jobs
KILL
Note that if the process you are trying to stop by PID is in your shell's job table, it may remain visible there, but terminated, until the process is fg'd again.
kill -TSTP $PID # SIGTSTP, 'polite' stop
kill -STOP $PID # SIGSTOP, 'hard' stop
kill signal -CONT $PID # SIGCONT, resume execution of the process
pkill -f PATTERN # send kill
SID
# Run a program in a new session
setsid $cmd
-w $cmd # Run a program in a new session & wait process finished
PROCESS LIST
pgrep
# return pids list of process matched command name
pgrep $PATTERN
example
pgrep -lf $PATTERN # return full informations process list with matched command name
/proc/PID
cat /proc/PID/status|awk '{print $5}' # return PGRP, ps is VERY LONG *10 / use instead cat /proc...|awk, see man proc
ps/pidof
ps -l $PID # long format
ps -f --pid $PID # full format
ps --ppid $PID # return children processes of parent process $PID
ps auT # return infos on processes associated with this terminal
ps -C $CMD # return process started by command $CMD
ps -g 15603 -o uid,pid,ppid,pgid,egid,rgid,pgrp,tty,time,cmd # return PID process of selected PGRP= PGID=
ps -o pid --no-headers --ppid PID # return chilren PIDS of parent PID
pidof $CMD # return list of pid started with command
EXAMPLES
jobs playing
timeout 20s sleep 200 &
jobs -l
disown -h %1
exit
lock process
FILEPID=/var/run/${0##*/}.pid
FILELOCK=/var/lock/${0##*/}.lock
PID=$$
(
trap "rm -f $FILEPID; exit" INT TERM EXIT
flock -xw 5 9 && echo "IN $PID" || (echo "///// ERROR \\\\\\" && exit 1)
echo $PID >$FILEPID
sleep 3
echo OUT $PID
) 9>$FILELOCK
listen stdin pipe
tail -f $fifo| while read line; do $cmd; done
tail -f /tmp/pipe | while read line; do ssh root@10.0.0.201 "echo $line >> /tmp/toto"; done
read test < <(echo hello world)
# from pipe
read a <$fifo
while read line; do $cmd; done < <(pipe)
while read line; do $cmd; done < <(tail -f pipe)
nc server
nc -l 12345 | nc www.google.com 80
Port 12345 represents the request This starts a nc server on port 12345 and all the connections get redirected to google.com:80. If a web browser makes a request to nc, the request will be sent to google but the response will not be sent to the web browser. That is because pipes are unidirectional. This can be worked around with a named pipe to redirect the input and output.
mkfifo $fifo
nc -l 12345 0<$fifo | nc www.google.com 80 1>$fifo
SYNTAX
comment
the line number is independent of sub selection, all the set of line is parsed and the counter of lines is for the global set
'/^while .*= "quit"/,/^done/ {/^\s*#/! {1, 70 s/^\(\s*\)/#\1/}}' /devs/install/alpine.install
<==>
'1,70 {/^while .*= "quit"/,/^done/ {/^\s*#/! s/^\(\s*\)/#\1/}}' /devs/install/alpine.install
use ';' or -e / different syntax for the same result
'1,70 {/^\s*#/! s/^\(\s*\)/#\1/}; s/^\(\s*\)/#\1/' /devs/install/alpine.install
<=>
-e '1,70 {/^\s*#/! s/^\(\s*\)/#\1/}' -e 's/^\(\s*\)/#\1/' /devs/install/alpine.install
BASIC EXAMPLES
# insert/add
"1i $line" # insert text at the beginning of file
"8i $line" # insert mytext in 8th line of file
"/$reg/ a \$line" # append line after the indicator
"/$reg/ i \$line" # insert line before the indicator
"/$reg/ c \$line" # replace line of the indicator
"s|^|$text|" # append text at the end of line
"s|$|$text|" # prepend text at the beginning of line
# sustitute
"/$begin/,/$end/ {s/\($str\).*/\1$str/}" # modify between two indicators
"/$begin/,$ {s/\($str\).*/\1$str/}" # modify between indicator to the end
"/$begin/,10 {s/\($str\).*/\1$str/}" # modify between indicator and the 10th line
"/$begin/,+2 {s/\($str\).*/\1$str/}" # modify between indicator and two lines after indicator
"s/$sch/$str/3" # replace only the 3rd 'sch' found string by str for each line
"s/$sch/\l$str/" # replace found string 'sch' by 'str' with the first character in lower case
"s/$sch/\L$str/" # replace found string 'sch' by 'str' with all characters in lower case
# modify
-e 's/\(.*\)/\L\1/' # to lowercase
# print/extract
-n "s/$select/ s|^export \(.*\)$|\1|p" # extract text from line
-n '2p;5p' # print 2rd & 5th lines
-n '3,$p' # print line from 3th to end
-n '/while/,+10p' # print lines from line matched while to 10 lines after. **REPEATED FOR EACH MATCHED LINE**
-s -n '4,10 p' /*/$file # print range of lines for each files
# delete
'7,9d' # delete lines between interval
'/pattern_start/,/pattern_start/d' # delete lines between two patterns
# backup
-i.bak '4i $line' $file # insert line at 4th lines & backup old file to $file.bak'
COMPLEX EXAMPLES
percent-code
decode percent-code
echo $text_encoded | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
print TODO lines
print lines are in between patterns '<<TODO' & 'TODO' in /home/shared/dev
while read line; do
echo -e "\n$line"
sed -n '/^<<TODO/,/^TODO/ {p}' "$line"
done < <(grep '<<TODO' /home/shared/dev -rl)
select then modify
prepend '#' where not begin with # (with possible start with \s)
'/^\s*#/! s/^\(\s*\)/\1#/'
subtreatment with lines counter
prepend '#' where line not begin with # (possibly beginning with \s) for the lines are between line matched patterns '^while .*= "quit"' and '^done'
'/^while .*= "quit"/,/^done/ {/^\s*#/! {1, 70 s/^\(\s*\)/#\1/}}' /devs/install/alpine.install
selected lines between matched line and x next lines
prepend '#' for lines between matching $str and 10 lines after, and for wich are not begin with '#'
'/$str/,+10 {/^#/! s/\(.*\)/#\1/}'
inverse selected lines
prepend '#' for lines between matching $str and last line, and for wich are not begin with '#'
'/$str/,$ {/^#/! s/\(.*\)/#\1/}'
treats each file separately
treats each file separately, in difference of |xargs sed
ls $path | xargs -L 1 sed "\$a $str"
ls $path | xargs sed -s "\$a $str"
sed -s "$action" /*/*.conf
grep selected
replace string in file only in selected line by grep
while read line; do
file="${line%%:*}"
line="$(echo "$line"|awk -F : '{ print $2 }')"
echo sed -i "$line s|\(\[ .*\) == \(.* \]\)|\1 = \2|g" "$file"
done <<< "$(grep -rn "\[ .* == .* \]" /home/shared/dev/install/)"
() {} # declare function with global scope for internal declarations
() () # declare function with local scope for internal declarations (subprocess)
DEBUG
https://linuxconfig.org/how-to-debug-bash-scripts
bash -x $script
Short | Long notation | description |
---|---|---|
set -f | set -o noglob | Disable file name generation using metacharacters (globbing) |
set -v | set -o verbose | Prints shell input lines as they are read |
set -x | set -o xtrace | Print command traces before executing command |
To see current state of all variables
echo $-
trap signals
ARG is a command to be read and executed when the shell receives the signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC is supplied) or `-', each specified signal is reset to its original value. If ARG is the null string each SIGNAL_SPEC is ignored by the shell and by the commands it invokes
trap n [condition...]
trap [action condition...]
-l # print a list of signal names and their corresponding numbers
-p # display the trap commands associated with each SIGNAL_SPEC
trap $cmd $signal # launch $cmd when signal $signal is enabled
EXAMPLES
get stdin
function _read() { while IFS= read line; do echo $line; done; }
ls | _read
give answer to command
echo -e "ct\nct"|sudo passwd root
yes ct | sudo passwd root
give the different pids of subprocess in script
file=/tmp/test
paths=$(df -l |grep "^/dev.*120.*" |sed "s|^.* \([^ ]*\)$|\1|" | sed "/save/d")
#paths='/ /var'
echo '#!/bin/bash' > $file
for path in $paths
do
echo "# $path" >> $file
echo "(echo > free2zero; pid=\$!; echo \"start $path - \\\$! \$! - \\\$BASHPID \$BASHPID - \\\$PPID \$PPID - \\\$\\\$ \$\$\"; cd $path; sleep 60; rm free2zero; echo \"end $path - \\\$! \$! - \\\$BASHPID \$BASHPID - \\\$PPID \$PPID - \\\$\\\$ \$\$\"; exit) &" >> $file
done
echo "echo \"itself : \\\$! \$! - \\\$BASHPID \$BASHPID - \\\$PPID \$PPID - \\\$\\\$ \$\$\"; sleep 30" >> $file
chmod +x $file
cat $file
sh $file
wipe free space in devices
file=/tmp/test
paths=$(df -l |grep "^/dev.*" |sed "s|^.* \([^ ]*\)$|\1|" |xargs)
paths=${paths/\/save/}
echo '#!/bin/bash' > $file
for path in $paths
do
echo "# $path" >> $file
echo "(echo \"start $path \$(date +\"%T - %N\")\"; cd $path; dd if=/dev/zero of=free2zero; rm free2zero; echo \"end $path \$(date +\"%T - %N\")\"; exit) &" >> $file
done
chmod +x $file
sh $file
ENV
env # list environment variables
env [options] name=value [cmd [arg]] # Set name to value in the temporary environment & run COMMAND
printenv # list environment variables
printenv $var # return value of environment variables $var if exists
( set -o posix ; set ) # list declared + environment variables
compgen -v # list available variable for completion
compgen -v $pat # list available variable for completion matched for a simple pattern $pat
DECLARE
declare [options]
If no NAMEs are given, Display the attributes and values of all variables
declare [-aAfFgilnrtux] [-p]
-f # restrict action or display to function names and definitions
-F # restrict display to function names only (plus line number and source file when debugging)
-g # create global variables when used in a shell function; otherwise ignored
-p # display the attributes and value of each NAME
declare [options] [name]
Declare variables and give them attributes
declare [-aAfFgilnrtux] [-p] [name[=value] ...]
-a # to make NAMEs indexed arrays (if supported)
-A # to make NAMEs associative arrays (if supported)
-i # to make NAMEs have the `integer' attribute
-l # to convert NAMEs to lower case on assignment
-n # make NAME a reference to the variable named by its value
-r # to make NAMEs readonly
-t # to make NAMEs have the `trace' attribute
-u # to convert NAMEs to upper case on assignment
-x # to make NAMEs export
SCOPE
scope is general
terminal <-> function
terminal <-> sourced file
terminal <-> script / for exported variables : 'export'
script <-> function
script <-> sourced file
script <-> script / for exported variables : 'export'
scope is local
terminal <-> script
terminal <-> function / for localized variables : 'local'
terminal <-> sourced file / for localized variables : 'local'
script <-> script
script <-> function / for localized variables : 'local'
script <-> sourced file / for localized variables : 'local'
EXPANSION
value
${parameter:-[word]} # use default values if parameter is unset or null
${parameter:=[word]} # assign default values if parameter is unset or null
${parameter:?[word]} # indicate error if null or unset if parameter is unset or null
${parameter:+[word]} # use alternative value if parameter is not null
parameter | Set and Not Null | Set But Null | Unset |
---|---|---|---|
${parameter:-word} | substitute parameter | substitute word | substitute word |
${parameter-word} | substitute parameter | substitute null | substitute word |
${parameter:=word} | substitute parameter | assign word | assign word |
${parameter=word} | substitute parameter | substitute null | assign word |
${parameter:?word} | substitute parameter | error, exit | error, exit |
${parameter?word} | substitute parameter | substitute null | error, exit |
${parameter:+word} | substitute word | substitute null | substitute null |
${parameter+word} | substitute word | substitute word | substitute null |
case
${var^} # First char in Uppercase
${var^^} # All chars in UPPERCASE
${var,} # First char in lOWERCASE
${var,,} # All chars in lowercase
remove
${parameter%[word]} # remove smallest suffix pattern. the word shall be expanded to produce a pattern
${parameter%%[word]} # remove largest suffix pattern. the word shall be expanded to produce a pattern
${parameter#[word]} # remove smallest prefix pattern. the word shall be expanded to produce a pattern
${parameter##[word]} # remove largest prefix pattern. the word shall be expanded to produce a pattern
position
${#string} # the length in characters of the value of parameter shall be substituted. the result is unspecified for parameter '*' or '@'
${string:position} # extract string from position
${string:position:length} # extract string from position to lenght
${string#substring} # strip shortest match of $substring from front of $string
${string##substring} # strip longest match of $substring from front of $string
${string%substring} # strip shortest match of $substring from back of $string
${string%%substring} # strip longest match of $substring from back of $string
replace
${string/substring/replacement} # replace first match of $substring with $replacement
${string//substring/replacement} # replace all matches of $substring with $replacement
${string/#substring/replacement} # if $substring matches front end of $string, substitute $replacement for $substring
${string/%substring/replacement} # if $substring matches back end of $string, substitute $replacement for $substring
reference
${!var} # display the value referenced by var (name of variable)
${!varprefix*} / ${!varprefix@} # matches all previously declared variables beginning with varprefix
${string:${#string}<3?0:-3} # take the last 3 characters if string length > 3
str=$(</dev/stdin)
# keep EOF
echo "$str"
# replace EOF
echo $str
SEQUENCE
{0..10..2} / seq 0 2 10 # 0 2 4 6 8 10
{2..-3..1} # 2 1 0 -1 -2 -3
{U..b} # U V W X Y Z [ ] ^ _ ` a b
{b..U} # b a ` _ ^ ] [ Z Y X W V U
SYSTEM VARIABLES
$PWD # Actual working directory
$PATH # Path to binaries /usr/bin ...
$USER # User name
$EUID # "effective" user ID number
$UID # User ID number
$GROUPS # Groups current user belongs to
$HOME # Home directory of the user
$HOSTNAME # The hostname assigned at bootup in an init script
$HOSTTYPE # host type
$IFS # internal field separator
$BASH # The path to the Bash binary itself
$BASH_ENV # An environmental variable pointing to a Bash startup file
$BASH_SUBSHELL # A variable indicating the subshell level
$BASHPID # Process ID of the current instance of Bash, not same as $$
$BASH_VERSION # The version of Bash installed on the system
$BASH_VERSINFO[n] # A 6-element array containing version information
[0] # Major version no
[1] # Minor version no
[2] # Patch level
[3] # Build version
[4] # Release status
[5] # Architecture
$'' # permit embedded \n in variables
$CDPATH # A colon-separated list of search paths available to the cd command
$DIRSTACK # The top value in the directory stack
$EDITOR # The default editor invoked by a script, usually vi or emacs.
$GLOBIGNORE # A list of filename patterns to be excluded from matching in globbing
$IGNOREEOF # number of EOF(control-D) the shell will ignore before logging out
$LC_COLLATE # collation order in filename expansion and pattern matching
$LC_CTYPE # controls character interpretation in globbing and pattern matching
$MACHTYPE # machine type
$OLDPWD # Old working directory ("OLD-Print-Working-Directory")
$OSTYPE # operating system type
$REPLY # The default value when a variable is not supplied to read
$SHELLOPTS # The list of enabled shell options
$SHLVL # Shell level, how deeply Bash is nested
$TMOUT # the shell prompt will time out after $time seconds
$PIPESTATUS # Array variable holding exit status(es) of last executed foreground pipe
[0] # holds the exit status of the first command in the pipe
[1] # the exit status of the second command, and so on.
$PROMPT_COMMAND # holding a command to be executed just before the primary prompt
$PS1 # This is the main prompt, seen at the command-line
$PS2 # The 2nd prompt, when additional input is expected. It displays as ">"
$PS3 # The 3rd prompt, displayed in a select loop
$PS4 # as "+", The 4ry prompt, shown at the beginning of each line of output when invoking a script with the -x [verbose trace] option. It displays
FUNCTION VARIABLES
$PPID # $PPID of a process is the process ID (pid) of its parent process
$FUNCNAME # Name of the current function
$BASH_SOURCE[0] # BASH_SOURCE array with hirerachical calls : level => filename
$LINENO # Line number of the shell script in which this variable appears
$SECONDS # The number of seconds the script has been running
$0 # name of script itself (called)
$1, $2, ... # Positional parameters
${*:2} / ${@:2} # return second & following positional parameters
${*:2:3} # return three positional parameters, starting at second
$# # Number of command-line arguments or positional parameters
$* # All of the positional parameters, must be quoted "$*"
$@ # Same as $*, but each parameter is a quoted string
$- # Flags passed to script (using set)
$! # PID (process ID) of last job run in background
$_ # Special variable set to final argument of previous command executed
$? # Exit status of a command, function, or the script itself
$$ # Process ID (PID) of the script itself. The $$ variable often finds use in scripts to construct "unique" temp file names
https://ss64.com/bash/
https://www.tldp.org/LDP/abs/html/special-chars.html # symbols
COMPGEN
compgen [option] [word] # Generate possible completion matches for word according to the options, which may be any option accepted by the complete builtin with the exception of -p and -r, and write the matches to the standard output
-a # alias
-b # shell builtins
-c # all commands
-d # directory
-e # exported shell variables
-f # file and functions
-g # groups
-j # job
-k # Shell reserved words
-s # service
-u # userAlias names
-v # shell variables
ARITHMETIC
expr expression
Print the result of the expression (no assignement)
expr 18 / 2 / expr 18/2 # return 9. expr 18 /2 is forbiden
expr 35 / 5 + 4 # return 11
let expression
Assign value to a variable
let a=3+1 / let 'a = 3 + 1' # assign the result of '3+1' to variable a
let a++ # add 1 to variable a
$(( expression ))
Print ther the result of the expression, assignement is allowed
echo $((a = 50 /3)) / echo $((a=50 / 3)) # affect 16 to variable a & print 16
b=$(( a = 100 % 12)) # affect 4 to a & b
EXPANSION
ls */path/*/
mv $dir/!(gnome-*) $dir/ # move files except ones matched pattern
MULTIPLE ASSIGNMENT
read a b c <<<"1 2 3"; echo "$a|$b|$c"
read a[{1..3}] <<<"$(echo 2 4 6)"; echo "${a[1]}|${a[2]}|${a[3]}"
str="Learn-to-Split-a-String-in-Bash-Scripting"
IFS='-'
read -ra ADDR <<< "$str"
IFS=' ' # reset to default value after usage
MULTIPLE COMMAND TO A FILE
{
echo "contents of home directory"
ls ~
} > output.txt
FILE DESCRIPTOR
test file descriptor
"$(true 2>/dev/null >&6; echo $?)" # return 0 if a file descriptor 6 is open for output
"$(true 2>/dev/null <&6; echo $?)" # return 0 if a file descriptor 6 is open for input
PROCESS SUBSTITUTION
<( command )
replace a file
sort -k 9 <(ls -l /bin) <(ls -l /usr/bin)|column -t
diff <(ls -l /bin) <(ls -l /usr/bin)
>( command_list )
redirect an entry
tar cf >(bzip2 -c > $file.tar.bz2) $directory
examples
compress pipe
bzip2 -c < pipe > $file.tar.bz2&
tar cf pipe $directory
rm pipe
redirection
ls /dfdf 2>&1 >> /tmp/1| tee -a /tmp/2 # duplicate stderror in files & redirect stdout to file
exec 2> >(tee -a "$file_error" "$file_log") # duplcate stderr in 2 files
exec 2> >(tee -a /tmp/2) > >(tee -a /tmp/1) 4>&1 # duplicate stderror & stdout in files & 4 in 1
exec 2> >(tee -a /tmp/2) > >(tee -a /tmp/1) 4> >(tee /dev/null) # duplicate stderror & stdout in files & &4 in null
exec 2> >(tee -a /tmp/2) > >(tee -a /tmp/1) 4> >(tee -a /tmp/4) # duplicate stderror & stdout in files & &4
read lines
while read line; do cmd $line; done < $file
while read line; do cmd $line; done < <( command )
while read line; do cmd $line; done <<< "$( command )"
while read line; do cmd $line; done <<< "$text"
ls | while read line; do echo $line; done
find / -type f | while read line; do echo $line; done
find / -type f | xargs -I {} echo $line {}
LIST
# return sorted & uniq
printf "%q\n" ${S_IPS_ADMIN} ${S_IPS_DEV}| sort -u
# list contains of current path
echo *
# list only directories with .??*
ls -I. -I.. -ap /opt|grep /|sed 's|/$||'|xargs
# list only directories without .??*
ls -p /opt|grep /|sed 's|/$||'|xargs
# list incolor & full time
ls -al --color --time-style=full-iso $PATHTMP
FIND
exclude path in name finding
sudo find / -not \( -regex '/\(proc\|run\|sys\)' -prune \) -name .Trash*
sudo find / -not \( -path /proc -prune -o -path /run -prune -o -path /sys -prune \) -name .Trash*
mulitple exec
find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;
delete & report the count of deleted
find "$path" -not \( -regex '/\(proc\|run\|sys\)' -prune \) -type f -name "$str" -exec echo "{}" \; -exec rm -f "{}" \; | wc -l
find directories without cover
find Music/ -mindepth 2 -maxdepth 2 -type d ! -exec test -e "{}/cover.jpg" ';' -print
find Music/ -mindepth 2 -maxdepth 2 -type d ! -exec sh -c "ls -1 '{}'|grep -qE '^cover\.(jpg|png)$'" \; -print
rename files with limiting to the 2 first arguments
find . -name *_test.rb | sed -e "p;s/test/spec/" | xargs -n2 mv
find Music/ -depth -empty -delete # find & delete empty directories & files
find Music/ -depth -type d -empty -delete # find & delete empty directories
SSH
display all configuration parameters
sshd -T
ssh keepalive
echo -e "\nServerAliveInterval 60\nServerAliveCountMax 1200" >> /etc/ssh/ssh_config # client
echo -e "\nClientAliveInterval 240\nClientAliveCountMax 3" >> /etc/ssh/sshd_config # server
Running a command on a remote server
ssh [user]@[server] 'command'
ssh [user]@[server] -e 'command'
ssh [user]@[server] 'bash -s' < [local_script]
ssh [user]@[server] << EOF
...
EOF
SYSTEM
env # print environnement variables
cat /proc/cpuinfo # cpu info
cat /proc/meminfo # mem info
free # memory
vmstat # memory
sudo dmidecode --type memory # physical informations about memory
sudo dmidecode -t 17 # physical informations about memory
getfacl /home/shared # access control / get special right
setfacl -b /home/shared # access control / set special right
hdparm -tT $DEVICE # speed reading for DD
stat -c %u $file # get uid of folder on file/folder
stat -c %a $file # get access right on file/folder
lshw -short -C memory # return details about RAM
filesystem
fuse $DEVICE # all processes use filesystem
fuse $FILE # all processes use file
lsof # list opened files of active processes
lsof $FILE # List processes which opened the file
lsof +D $PATHTMP # List opened files under a directory
lsof $DEVICE # List processes using a mount point
lsof -u $USER # List files opened by a specific user
lsof -p $PID # List all open files by a specific process
lsof -u $USER -a -i
lsof -u $USER -a $DEVICE # list processes using a mount point abd used by user
lsof -i | grep ssh # list ssh processes
kill -9 $(lsof -t $DEVICE) # kill all processes using a device# give executed time for command
udisksctl loop-setup -r -f $files_iso # List all network connections used by user# mount without root privileges
RANDOM
# print an uuid
cat /proc/sys/kernel/random/uuid
# generate random string with 14 characters
cat /proc/sys/kernel/random/uuid | sha256sum | head -c14
< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c14
# generate random string
openssl rand -base64 24
openssl rand -hex 12
TRICKS
comm
compare two sorted files line by line
With no options, produce three-column output. Column one contains lines unique to FILE1, column two contains lines unique to FILE2, and column three contains lines common to both files
comm [OPTION]... FILE1 FILE2
-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
-3 suppress column 3 (lines that appear in both files)
--check-order # check that the input is correctly sorted, even if all input lines are pairable
--nocheck-order # do not check that the input is correctly sorted
--output-delimiter=STR # separate columns with STR
--total # output a summary
-z, --zero-terminated # line delimiter is NUL, not newline
example
# return only variables
comm -3 <(comm -3 <(declare | sort) <(declare -f | sort)) <(env | sort)
convert lines to colums /5lines
awk 'ORS=NR%4?" ":"\n"' $file
cat $sfile | paste - - - - > $fileto
merge 2 results or 2 files in 2 columns
paste $file1 $file2
paste <($command1) <($command2)|column -tn
mount without root privileges
udisksctl loop-setup -r -f $FILE_ISO
affect variable to arguments $*
set -- "var1 var2 var3 ..."; echo "$1"; echo "$2"
process
$cmd & # create a subprocess & detach process
nohup $cmd & # create a subprocess & detach process with log the stdout with nohup
hexa to dec
echo $((16#$hexNum))
time & date
time ( $cmd ) # return the time to execute cmd
date -d @1267619929 +'%Y%m%d' # convert timestamp to format
cut -d' ' -f5- $file # get 5th elements to the last, separated by ' '
tr -cs 'A-Za-z' '\n' < $file |grep -c "aaa" # count number of "aaa"
user
useradd -g $gid -u $uid $USER -p "$(mkpasswd "$pwd")" -d </home/user> -c <comment> -s /bin/sh # user add
usermod -G $gid $USER # add group to user
compress
tar czf # compress with gzip
tar cjf # compress with bzip2
XZ_OPT=-9 tar cvJfh # compress with following symlinks & xz & max compression
xz -z9c file > file # compress with max compression
xz -dc file > file # decompress
who
who -a # list all connections
who -q # all login names and number of users logged on
who -u # list users logged in
ps
ps -e / ps -A # all processus
ps ax # all process with command called to start
ps -ef # all process & full informations
dd
dd $cmd status=progress # verbose mode
declaration
# declares and initializes an empty indexed array
myarray=()
# sets the first element of an indexed array. If no array created it
myarray[0]=
# declares an indexed array. if existing not initialized it
declare -a myarray
# declares an associative array
declare -A myarray
value setting
# sets the element N of the indexed array
myarray[N]=VALUE
# sets the element indexed by strING of the associative array
myarray[strING]=VALUE
# set the zeroth element of indexed array, for associative array index with string "0"
myarray=VALUE
# sets array with given ek*lements, starting at zero. existing array is unset before
myarray=(E1 E2 …)
# sets index-value pairs for indexed or associative array
myarray=([X]=E1 [Y]=E2 …)
# append to array
myarray+=(E1 E2 …)
# concat two arrays
myarray3=( ${myarray1[@]} ${myarray2[@]} )
# concat & add elementstwo arrays
myarray3=( ${myarray1[@]:0:2} "str" "str2" )
value getting
# return value of array at index. if N<0 is an offset from the greatest index
${myarray[N]}
# return list of indexes in array
${!myarray[@]}
# return list of values in array, preserves breaks between elements
${myarray[@]}
# when you want join all array elements to a string
${myarray[*]}
# return M elements starting from N, preserves breaks between elements
${myarray[@]:N:M}
${myarray[*]:N:M}
# return M elements from position N from last (-N+M)
${myarray[*]: -N:M}
# return stringlength of value at index N (or key)
${#myarray[N]}
# return count of indexes in array, preserves breaks between elements
${#myarray[@]}
${#myarray[*]}
# return list of indexes in array, preserves breaks between elements
${!myarray[@]}
${!myarray[*]}
# test in key N exists in associative array, return _ if key exists or nothing
${myarray[N]+_}
substring removing
# removes shortest match from front of string(s)
${myarray[@]#*sch}
# longest match from front of string(s)
${myarray[@]##*sch}
# shortest match from back of string(s)
${myarray[@]%sch*}
# Longest match from back of string(s)
${myarray[@]%%sch*}
subtring replacement
# replace first occurrence of substring with replacement.
${myarray[@]/sch/str}
# replace all occurrences of substring.
${myarray[@]//sch/str}
# delete all occurrences of substring.
${myarray[@]//str/}
# replace front-end occurrences of substring.
${myarray[@]/#sch/str}
# replace back-end occurrences of substring.
${myarray[@]/%sch/str}
unset
unset -v myarray
# destroys entirely array
unset -v myarray[@]
unset -v myarray[*]
# destroys array element at index N (or key)
unset -v myarray[N]
create
# create array from file or readarray
mapfile -t myarray FILE
# print table with 2 colums
printf "%s\n" "${!myarray[@]}" "${myarray[@]}" | pr -2t
# copy an array
myarray2=("${myarray1[@]}")
global
syntax
( $exp ) # test expression
! $exp # negation
$exp1 -a $exp2 # and
$exp1 -o $exp2 # or
string
-z "$str" # the length of $str is zero (quotes protects few values for str)
-n "$str" # the length of $str is nonzero, str have to be quoted
-e # file exists
-f # file is a regular file (not a directory or device file)
-s # file is not zero size
-d # file is a directory
-b # file is a block device (device0="/dev/sda2")
-c # file is a character device (device1="/dev/ttyS1")
-p # file is a pipe
-h # file is a symbolic link
-L # file is a symbolic link
-S # file is a socket
-t # file (descriptor) is associated with a terminal device. This test option may be used to check whether the stdin [ -t 0 ] or stdout [ -t 1 ] in a given script is a terminal.
-r # file has read permission (for the user running the test)
-w # file has write permission (for the user running the test)
-x # file has execute permission (for the user running the test)
-g # set-group-id (sgid) flag set on file or directory. 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.
-u # set-user-id (suid) flag set on file.
-k # sticky bit set. 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.
-O # file exists and is owned by the effective user ID
-G # file exists and is owned by the effective group ID
-N # file modified since it was last read
-nt # f1 -nt f2 file f1 is newer than f2
-ot # f1 -ot f2 file f1 is older than f2
-ef # f1 -ef f2 files f1 and f2 have the same device and inode numbers (are hard links to the same file)
numeric
[]
-eq # is equal to
-ne # is not equal to
-gt # is greater than
-ge # is greater than or equal to
-lt # is less than
-le # is less than or equal to
[[]]
< # is less than
<= # is less or equal than
> # is greater than to
>= # is greater than or equal to
string comparison
[ -z "${var}" ] # true if var is not defined or is null
[ -z ${var+x} ] # true if var is not defined, var+x : expand var with x only if var are unset
= # is equal to
[ "$var" = str* ] # if $var are equal to 'str'* expansion , only if $var does not contains space & $var are not empty
[ -z "${var##*str*}" ] # if the expansion of str replace all content of var
[[ ]] # unsensible with empty values: no need quotes on values
[[ $a = z* ]] # True if $a starts with an "z" (pattern matching). use
[[ $a = "z*" ]] # True if $a is equal to 'z*' (literal matching).
[[ $str =~ $regexp ]] # test with regexp
# very usefull for array
[[ " $var " == *" str "* ]]
[[ " $var " =~ " str " ]]
[ "${var/str}" != "$var" ]
IP
ip a / ip addr show # print informations about all interface
ip addr show dev <device> # print informations about specified device
ip -br addr show dev <device> # print brief informations about specified device
ip -4 a / ip -4 addr show # print informations about all interface for inet family
ip -6 a / ip -6 addr show # print informations about all interface for inet6 family
ip -4 -o route show to default # get device name for default IP v4 route
ip -6 -o route show to default # get device name for default IP v6 route
ip -br -4 -o address show dev <interface> | sed 's|.*\s\+\([0-9\.]\+\)/.*|\1|' # get ip v4 of given interface
ip -br -6 -o address show dev <interface> | sed 's|.*\s\+\([0-9a-z:]\+\)/128.*|\1|' # get ip v6 of given interface
NSTAT
Show open port
options
-a # all sockets (default connected)
-l # listening ports
-p # display the process
-n # numerical addresses (no DNS resolution)
-t # only TCP ports
-u # only UDP ports
tricks
netstat -pl | netstat -pla # listening process
netstat -plu # listening process for UDP
netstat -plt # listening process for TCP
netstat -pln # listening process with IP (no NDS resolution)
netstat -patn # process (listening or not) for TCP with IP (no NDS resolution)
netstat -plutn # show listening process for UDP & TCP with IP (no NDS resolution)
netstat -antup
NMAP
Scan network
tricks
# Scan from 192.168.1.0 to 192.168.1.255
nmap 192.168.1.0-10
# Scan with specified range of ports
nmap -p 81-1024 192.168.1.3
# Scan open ports, send a ICMP ECHO (ping) request
nmap -sP 192.168.1.*
# return all open TCP ports by sending SYN messages
nmap -sS $IP
# return all open UDP ports
nmap -sU $IP
# return informations about OS
nmap -O $IP
nmap -A -T4 $IP
# return potential version of OS
nmap -O --osscan-guess $IP
# Scan with a random mac address
nmap --spoof-mac B0:65:BD:01:01:01 192.168.1.3
TRICKS
show open ssh connection
netstat -n --protocol inet | grep ':22'
lsof -i -n | egrep 'ssh'
lsof -i -n | egrep 'sshd'
create mac address
mac=$(< /dev/urandom tr -dc a-z0-9 | head -c10 |sed 's/\(..\)\(..\)\(..\)\(..\)\(..\)/02:\1:\2:\3:\4:\5/')
resolution of domain name
nslookup $DOMAIN
get ip for eth0
ifconfig eth0 | sed -n 's|^[[:space:]]\+inet \(addr:\)\?\([0-9\.]\+\) .*|\2|p'
get ctid for eth0 (openVZ)
ifconfig eth0 | sed -n 's|^[[:space:]]\+inet \(addr:\)\?[0-9\.]\+\.\([0-9]\+\) .*|\2|p'
SCAN
arp
arp -ne -i wlan0 # scan interface wlan0 without dns & print in shell mode
arp-scan -lI wlan0 # scan the entire locanet interface wlan0
arp-scan -lI eth0 129.20.228.1/24 # scan the interface eth0 with a mask 0.0.0.31
arp-scan -I wlan0 192.168.0.100-192.168.0.200 # scan the locanet interface wlan0 with ips between 192.168.0.100 and 192.168.0.200
nmap
nmap -sP 192.168.0.1/24 # scan by pinging ip addresses with mask 0.0.0.255
nmap -e wlan0 -sP 192.168.0.100-199 # scan the interface wlan0 with ips between 192.168.0.100 and 192.168.0.200
nmap -e wlan0 -sP 192.168.0.,1,101 -oG $file # scan the interface wlan0 with ips 192.168.0.100 & print the result in grepable format to file
nmap -e wlan0 -sL 192.168.0.5,10-20 # List cached informations on ips : 192.168.0.5 & between 192.168.0.10 & 192.168.0.2
nc
nc -v -u -z -w 3 91.121.112.140 514 # test udp port open
WIFI
iwconfig wlo1 | iw dev wlo1 link # print technical informations
lshw -C network
iwlist scan # scan & print informations about wifi networks
nmcli connection show # show available connections about wifi networks
nmcli dev wifi