bash

#define bash: \ I----------------------------------------------------------------\ I----------------------------------------------------------------\ I----------------------------------------------------------------\ I /$$$$$$$ /$$ \ I | $$__ $$ | $$ \ I | $$ \ $$ /$$$$$$ /$$$$$$$| $$$$$$$ \ I | $$$$$$$ |____ $$ /$$_____/| $$__ $$ \ I | $$__ $$ /$$$$$$$| $$$$$$ | $$ \ $$ \ I | $$ \ $$ /$$__ $$ \____ $$| $$ | $$ \ I | $$$$$$$/| $$$$$$$ /$$$$$$$/| $$ | $$ \ I |_______/ \_______/|_______/ |__/ |__/ \ I----------------------------------------------------------------\ I----------------------------------------------------------------\ I----------------------------------------------------------------I "Bourne Again SHell" GNU Readline library : used for all input operations (see AT "C++/Readline\/History") # high quality introduction https://mywiki.wooledge.org/BashGuide # interactive introduction https://github.com/agvxov/bashtutor • as bash uses readline for input, all readline shortcuts apply (in theory however terminal emulators may have confronting bindings) (see AT "C++/Readline\/History") bash [options] : launches interactive bash session — f : disable globing (see AT "./Globs") --noprofile : ignore bash profile files (/etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profile) --norc : ignore bashrc files (~/.bashrc) Files: .bashrc : where settings and preferences are read from .bash_profile : where strictly interactive shell settings and preferences are read from .bash_history : where command history is stored .bash_logout : where commands to be executed on log out are read from Builtins: • features which behave like programs • they are faster than using real programs, because there is no fork involved • there is no technical guarantee regarding the availability of builtins, however they dont change much and you may list them with "compgen -b" • see controlling builtins under enable, BELOW . [file] : execute bash script [file], in the current shell $ bat example.sh ───────┬─────────────────── │ File: example.sh ───────┼─────────────────── 1 │ goo="nar" ───────┴─────────────────── $ ./example.sh $echo ${goo} $ . ./example.sh $ echo ${goo} nar : : null command; does nothing; its exit status is always success [ ] alias : lists defined aliases alias [name]="[command]" : creates alias unalias [name] : deletes alias • to add a permanent alias one must specify it in a config file {".bashrc"} (see AT "/Bash/Files") • [alias] [...] will append [...] to the called command as argument(s) • to never use an alias or alternatively put, escape it, one can prefix any bash command with a '\\' char $ alias pwd="echo Dunno mate, somewhere..." $ pwd Dunno mate, somewhere... $ \pwd /home/user bg : see AT /Linux/Processes bind : sets readline keybinding from the command line break : exits the current loop builtin [builtin] [args] : executes [builtin] with [args] passed; never does a binary lookup caller cd [folder] : changes directory command compgen complete compopt continue declare [options] [var declaration] : declares var with special traits • use a '+' to instead remove an attribute from a var (yes, yes really) — a : array — f : function name — i : int — r : read only — x : export; make global dirs : prints directory stack; see AT ../Directory_stack disown : disown (separate; make independent of) a program from the shell; use with '&' {mousepad & disown} echo <string> : echoes <string> back enable [options] : controls builtins — a || -p : prints all builtins — n [builtin] : disables [builtin] — s : prints POSIX "special" builtins — f [file] : load builtin — d [builtin] : unload builtin [builtin] loaded with -f eval <string> : evaluates <string> as a bash command exec exit export false fc fg : foreground; brings background process to the foreground getopts <string> [name] : utility for easy option parsing; stores parsed options in [name]; <string> is a not separated list of expected options; options expecting a meta option shall have a ':' after them; meant to be used in a while loop; saves progress index into ${OPTIND}; if calling getopts multiple times is desired ${OPTIND} must be manuali reset to 1 saves the meta option to ${OPTARG} while getopts "hvo:" MYVAR; do // please ignore the '(' at the start of the lines case "$MYVAR" in h) my_help ;; v) my_version ;; o) my_option=${OPTARG} ;; esac done hash help : display information about builtins history jobs kill let local logout mapfile popd : pops directory stack; see more AT ../Directory_stack printf pushd : pushes a path to the directory stack; see more AT ../Directory_stack pwd read [options] [var] : reads a line and stores it in [var] — r : do not allow backslashes to escape any chars readarray readonly [var-name] : makes [var-name] readonly (const); [name] must be assigned after hand return set shift <int> : shift positional parameters; rename the positional parameters $<int>+1,$<int>+2... to $1,$2... if <int> is not given, it is assumed to be 1 shopt : "SHell OPTion"; controls internal bash options source [FILE] : alias of '.'; see ABOVE suspend test times trap true type typeset ulimit umask unalias unset [var-name] : delete-s [var-name]; [var-name] is only the name, no '$' is needed; readonly variables cannot be unset { $ MYVAR="my value" $ echo $MYVAR my value $ unset MYVAR $ echo $MYVAR $ } wait Globs: • sometimes also called wildcards • used for matching patterns • do not match hidden files (see AT ./Glob_related_options) • can be escaped { \* } ? : any (one) char * : any or none chars [(!||^)[...]||[keyword]] : a list of chars from which one is to be matched { [02468] }; '!' and '^' signal negation { [!a] -> "not 'a'" } • case sensitive • '-' can be used to symbolize a range { [0-9] } { [a-z] } { [A-Z] } [keyword]: [:alnum:] : any alphanumeric char [:space:] : any whitespace char [:digit:] : any digit char, '_' or '.' Extended_globs: • turned off by default shopt -s extglob • can be nested [specifier]([pattern](|pattern[|[...]])) [specifier]: ? : matches zero or one occurrences of the patterns * : matches zero or more occurrences of the patterns + : matches one or more occurrences of the patterns @ : matches occurrences of atleast one of the patterns ! : matches anything not containing any of the patterns [pattern]: • string { ls @(M|S)* -> all files starting with an 'M' or 'S' } • not necessary, but sometimes a glob expression (particularly in '!' expressions) { ls !(*.jpg|*.gif) -> all non-jpgs and non-gifs} { ls !(*Megadeth*|*01.*) -> lists all albums (presuming a nice and orderly naming of them) except the the first ones of a band and the ones made by Megadeth } Glob_related_option: extglob : see ABOVE nullglob : expands non-matching glob extension to an empty string rather then itself dotglob : makes the '*' glob match hidden files too, but not .. or . globstar : makes "**" match all files and folders recursively; "**/" will only match folders failglob : reports an expansion error if no matches are found Directory_stack: • a container of stored directories • for fast and easy directory manouvering • the directory on the top of the stack is always the current working directory • the stack is 0 indexed (>all following commands are builtins) ( dirs : prints directory stack pushd ([path]) ([num]) : pushes [path] to the top of the stack; if no [path] is supplied, swaps the top two directories; [num] is an index to bring forward other stack members popd ([num]) : removes the [num] indexed directory from the stack; if no [num] is supplied, the top is defaulted SCRIPTING: #!/bin/bash • you are obviously gonna be using bash commands and variables Comments: #[comment] : single line • multi line comments are feasible, but not intended; just use '#' Variables: • every variable behaves as a string being copy pasted left and right ○ list of builtins which manipulate variables • readonly • unset [name]=[value] : assign variable a variable; do not use whitespaces $[name] || ${[name]} : reference an already declared variable • it is recommended to use curly braces whenever referencing one ( ${[name]} ), otherwise it might be subject to word splitting { $ MYVAR="some value" $ echo ${MYVAR} some value } ${#[name]} : expands to the length of [name] Strings: • 0 indexed ${[name]:} : expands to ${[name]} from the <int>th char until the end ${[name]:[int-1]:[int-2]} : expands to ${[name]} from the [int-1]th char until the [int-2]th char Arrays: • always 1 dimensional Indexable: • not required to be continuous • every unassigned position will return an empty string [name]=([values]) : declares and assigns an array; [values] is a ${IFS} separated list of strings [name]<int>=[value] : declares an array and assigns a single, arbitrary index of it [name]+=([values]) : concatenates [values] to an array $[array-name] : expands to the first member of [array-name] ${[array-name][]} : expands to the <int>th member of [array-name] ${[array-name][*]} : expands to every member of the array separated by the first char of ${IFS} Associative: pass Default: • otherwise called keyword variables <int> : argument(/positional parameter) number <int>; between 1-9, to access later arguments see AT "../Builtins/shift"; 0 is always the scripts name @ : array of arguments(/positional parameters) (starting from one); for POSIX compliance reasons it expands to all elements instead of just the first * : ${@}, BUT when used between quotes it uses ${IFS} (see BELOW) to separate them on return # : number of arguments(/positional parameters) (-1) $ : process id of the shell ! : process id of the most recently executed background process ? : return value of the most recently executed program — : set builtin command?! _ : last argument to the previous command; at shell startup, set to the absolute pathname auto_resume : if set to 1, the last background process can be brought to the foreground without a preceding '%' BASH : the full path to file used to invoke current bash instance { /bin/bash } BASH_ALIASES : array of all bash aliases BASH_ARGC : array of all stack frame argument counts; XXX: shopt -s extdebug BASH_ARGV : array of all stack frame arguments; XXX: shopt -s extdebug BASH_ARGV0 : $0 (see ABOVE) BASH_CMDS : ?! BASH_COMMAND : the command currently being executed or about to be executed BASH_COMPAT : ?! BASH_LINENO : ?! BASHOPT : a colon-separated list of enabled shell options BASHPID : the process id of current bash instance BASH_REMATCH : ?! BASH_SOURCE : ?! BASH_SUBSHELL : ?! BASH_VERSINFO : array whose members hold version information about this bash instance 0 : release number 1 : version number 2 : patch level 3 : build level 4 : release status 5 : value of MACHTYPE (?!) BASH_VERSION : a string representing the version of the version of the instance of bash BASH_XTRACTEFD : ?! CDPATH : a colon separated list of directories which will be searched by cd for subdirector before . is CHILD_MAX : ?! COLUMNS : number of available columns to print to (width in chars) COMP_CWORD : ?! COMP_KEY : ?! COMP_POINT : ?! COMPRELY : ?! COMP_TYPE : ?! COMP_WORDBREAKS : ?! COMP_WORDS : ?! COPROC : ?! DIRSTACK : ?! EMACS : ?! ENV : ?! EPOCHREALTIME : the number of seconds since epoch as a float EPOCHSECONDS : expands to the number of seconds since epoch EUID : expands to the used ID of the current user FCEDIT : ?! FIGNORE : colon separated list of suffixes to never auto complete files possessing them FUNCNAME : ?! FUNCNEST : maximum function nesting, surpassing this value will result in an abort; its for excaping infinite recursiveness GLOBIGNORE : colon separated list of patterns to never match paths possessing them with globs GROUPS : array whose members are the groups the current user is a member of histchars : ?! HISTCMD : ?! HISTCONTROL : colon separated list of options to be used on saving the history ignorespace : dont save lines beginning with a space ignoredups : dont save lines matching the previous one ignoreboth : short for ignorespace:ignoredubs erasedups : remove all lines matching the current one before saving HISTFILE : the file to be used for saving history HISTSIZE : number of commands to remember; set to 0 to disable history; set to a negative number to make it unlimited HISTTIMEFORMAT : format string to mark the time of execution HOME : the home directory of the current user HOSTFILESIZE : maximum number of lines in $HISTFILE HOSTFILE : the file that contains hostnames that the shell might need to complete HOSTIGNORE : colon separated list of patterns to ignore commands on save HOSTNAME : the host's name {kali} HOSTTYPE : the host's type {x86_64} IFS : Internal Field Separator; expands to space, tab and newline; { ls$IFS-l } IGNOREEOF : number of consecutive EOF signals ([ctrl] + [d]) to be required before exiting the shell INPUTRC : ?! LANG : locale LC_ALL : ?! LC_COLLATE : ?! LC_CTYPE : ?! LC_MESSAGES : ?! LC_NUMERIC : ?! LINENO : the line where its referenced if in a script, otherwise no meaning is guaranteed, but seems to be the number of the commands run from the bash instance LINES : number of lines of the console MACHTYPE : "[CPU]-[manufacturer]-[system]" ($HOSTTYPE-[manufacturer]-$OSTYPE) {x86_64-pc-linux-gnu} MAILCHECK : specifies how often to check for mail in seconds MAILPATH : colon separated list of file names to be checked for mail MAPFILE : ?! OLDPWD : the previous working directory OPTARG : ?! OPTERR : ?! OPTIND : ?! OSTYPE : operating system type {linux-gnu} PATH : colon separated list of directories to search for commands PIPESTATUS : ?! POSIXLY_CORRECT : ?! PPID : Parents Process ID PROMPT_COMMAND : ?! PROMPT_DIRTRIM : ?! PS0 : "Prompt String 0"; displayed before output messages of programs PS1 : "Prompt String 1"; the string which is displayed before the shell takes a command PS2 : "Prompt String 2"; displayed whenever the shell continues to take commands after a command {multi lines; bash statements {if}} PS3 : "Prompt String 3"; displayed inside select (builtin) loops PS4 : ?! PWD : the working directory RANDOM : a random number between 0 and 32767 READLINE_LINE : ?! READLINE_POINT : ?! REPLY : ?! SECONDS : number of seconds since the current shell was invoked SHELL : full path name of the shell SHELLOPTS : colon separated list of enable shell options SHLVL : Shell Level; number of bash instances running on top of each other SRANDOM : a 32 bit random number TIMEFORMAT : ?! TMOUT : ?! TMPDIR : name of the directory where bash shall place temporary files UID : User ID Execution: [cmd-1] [operator] [cmd-2] • by placing operatirs between individual commands the nature of there execution can be altered Sequentual: • usual behaviour • each command in the line waits for the previous to finish execution Pure: operator: ; • experienced through the commandlines basic usage • implicitly invoked when a new line is encountered and a builtin doesnt override the behaviour • explicit-ly invoked by a semi-colon { // Echo "Done" after sleep-ing is finished sleep 10; echo "Done" } And: operator: && • only execute the second command if the first one exited successfully { // only output the contents of my_file.txt if it contains any 'a' letters grep 'a' my_file.txt && cat my_file.txt } • notice how its behaviour is best explained from the perspective of execution, but its perfectly equivalent to a logical and operator { // Echo "True" if ${EXAMPLEVAR} equals "test" read EXAMPLEVAR [ "$EXAMPLEVAR" == "test" ] && echo "True" // Extending an 'if' statement; // is ${EXAMPLEVAR} both larger than 10 and lesser than 100? read EXAMPLEVAR if (( 10 < $EXAMPLEVAR )) && (( $EXAMPLEVAR < 100 )); then echo "It is." fi } Or: operator: || • only execute the second command if the first one exit value indicates failure { // only output the contents of my_file.txt if it does not contain any 'a' letters grep 'a' my_file.txt || cat my_file.txt } • notice how its behaviour is best explained from the perspective of execution, but its perfectly equivalent to a logical or operator with short circuiting { // Echo "True" if ${EXAMPLEVAR} equals "test" read EXAMPLEVAR [ "$EXAMPLEVAR" == "test" ] || echo "True" // Extending an 'if' statement; // is ${EXAMPLEVAR} either lesser than 100 or larger than 200? read EXAMPLEVAR if (( $EXAMPLEVAR < 100 )) || (( 200 < $EXAMPLEVAR )); then echo "It is." fi } Paralel: • run multiple commands at the same time • do not wait for finish Pure: operator: & • closest thing Bash has to multithreading { // Run 2 functions simultaneously // Just to be perfectly clear: this examples aim is to show that // we DO NOT get a homogeneous sequence #// function 1 function my_fun1(){ for i in $(seq 1 1 100); do echo $i done } #// function 2 function my_fun2(){ for i in $(seq 100 1 200); do echo $i done } #// execute my_fun1 & my_fun2 } • can be used during interactive usage to "put something to the background" (obviously stdout wont just magically disappier) Pipe: operator: | • by far the most powerful feature of Bash • hooks the first commands stdout to the seconds stdin creating a chain of sorts • all common pajeet "tutorials" fail to mention that the two commands run simultaneously // include some examples; ?! Operators: var: ${/[str1]/[str2]]} : replaces first occurrences of [str1] with [str2]; do not prefix [variable] with a '$' ${//[str1]/[str2]]} : replaces all occurrences of [str1] with [str2]; do not prefix [variable] with a '$' ${#} : expands to string length ${#[regex]} : expands to <string> with the shortest match of [regex] deleted from the beginning ${##[regex]} : expands to <string> with the longest match of [regex] deleted from the beginning ${%[regex]} : expands to <string> with the shortest match of [regex] deleted from the end ${%%[regex]} : expands to <string> with the longest match of [regex] deleted from the end Logic: spaces mater hardcore Comparison_operators: { if [condition]; then [...] (elif [condition]; then [...]) (else [...]) fi //yes, really } [condition]: • if tests the exit value of [condition] • bash provides many builtins with versatile operators to ease writing conditions • to deploy logic between conditions one must deploy builtin sequential execution operator-s (see AT "../Execution/Sequentual") Builtin!: ! [condition] • performs logical not on the [condition] to its right Builtin[]: [ [operator] ] • whitespace sensitive if [ $1 == "-h" ]; then show_my_help_message fi # --- [ -v myvar ] || myvar="default" Strings: [string-1] == [string-2] : equals [string-1] != [string-2] : not equals [string-1] =~ [string-2] : regex equals [string-1] > [string-2] : greater than [string-1] < [string-2] : less than [string-1] >= [string-2] : greater than or equal to [string-1] <= [string-2] : less then or equal to — n <string> : is not null (ie. not empty) — z <string> : is null (ie. empty) Integers: [int-1] -eq [int-2] : equals [int-1] -ne [int-2] : not equals [int-1] -gt [int-2] : greater than [int-1] -lt [int-2] : less than [int-1] -ge [int-2] : greater than or equal to [int-1] -le [int-2] : less than or equal to FILE: — d [path] : is directory path — e [path] : is existing path — s [path] : is not an empty file — O [path] : is owned by ${USER} — r [path] : is readable by ${USER} Misc: — v [var] : is set Builtin(()): (( [operator] )) • whitespace sensitive { if (( $1 > 100 )); then show_my_error_message fi } [int-1] == [int-2] : equals [int-1] != [int-2] : not equals [int-1] > [int-2] : greater than [int-1] < [int-2] : less than [int-1] >= [int-2] : greater than or equal to [int-1] <= [int-2] : less then or equal to Loops: While: { while [condition] do [...] done } Until: { until [condition] do [...] done } • opposite of while; runs while condition is false For: { for (([initialize var]; [condition]; [increment])) do [...] done } • pay special attention to the braces For_each: { for [var] in [list] do [...] done } (>[list] can be an array or files) • for gods sake, do not do { for i in ${ls .} }; do { for i in * } instead! Select: • intended for easy interactive menus • enum-s a [list] of options and takes input repeatedly • invalid input is discarded • ints in the enum range are accepted • a given var-s value is set to the chosen option • break/continue applies { select [var] in [list] do [...] done } break // what you continue // would expect... Functions: { (function) [name]() { [code] (return ([value])) } } • the keyword "function" is optional, however if ones aiming for compatibility with other shells, its best to NOT use it, but using it could prevent collisions with alias-es ○ calling [name] (arguments) Redirections: [command] < [file] : places [file]s contents to [command]s stdin [command] [source][mode] [file] : redirects specified outputs of [command] to [file] [source]: • || 1> : stdout 2> : stderr &> : stdout and stderr [mode]: [none] : overwrite | : overwrite even if noclobber is set • : append { echo "asd" >> ./my_file.log /*appends "asd" to my_file.log*/ } ![...] : runs a command from the command history ! : previous command; useful for running a command again with sudo {sudo !!} [num] : [num]th command from history — [num] : relative position in command history; -1 being the previous command <string> : most recent command from history STARTING with <string> ?<string>? : most recent command from history CONTAINING <string> # : the current command, from beging till itself { printf !# -> printf printf -> "printf" printed} $ : last argument of the last command {[...]} : clarifies that only the text between the curly braces are meant to be interpreted { echo Vera; {!-1}nda; the ';' is not literal, commands executed in the same line are written to the history file at the same time therefore literal "; {!-1}" will result in non-sense} Jobs: the concept of jobs only exists on the shell level; it is an abstraction, it has no real kernel-wise representation • every process invoked interactively is a job • jobs are bound to the invoking shell instance and therefor do not overlive it • the job blocks the shell for reprompting is said to be running in the foreground • the job(s) which do not run in the foreground are said to be running in the background • both foreground and background jobs stdout and stderr outputs are displayed in terminal (if not redirected) • jobs run in the foreground by default [cmd] & : invokes a process in the background; '&' is just the pure parallel execution operator without a second argument, see "/Bash/Execution/Paralel/Pure" jobs : lists background jobs; '+' marks the default job '-' marks the reserve job, which will become the default that terminates bg ([job]) : makes previously stopped job [job] resume execution in the background; if [job] is not specified the default is used fg ([job]) : moves [job] to the foreground; if [job] is not specified the default is used [job]: %<int> : by id %+ : default job %- : reserve job ### Jobs in Bash ### #₩ # this operation takes a considerably long time to finish $ find / -iname '*a*' &> files_with_a_in_their_names.list # long long thinking $ # however, by running it in the background, # we don't have to wait before we can run another command from the same shell $ find / -iname '*a*' &> files_with_a_in_their_names.list & $ moving a job from the background to the foreground # start a few jobs so we have a few options to choose from $ find / -iname '*a*' &> files_with_a_in_their_names.list & $ find / -iname '*b*' &> files_with_b_in_their_names.list & $ find / -iname '*c*' &> files_with_c_in_their_names.list & $ find / -iname '*d*' &> files_with_d_in_their_names.list & [1] 17156 [2] 17157 [3] 17158 [4] 17159 # listing the background jobs because in this example # I'm a goldfish with a very small terminal $ jobs [1] Running find / -iname '*a*' &> files_with_a_in_their_names.list & [2] Running find / -iname '*b*' &> files_with_b_in_their_names.list & [3]- Running find / -iname '*c*' &> files_with_c_in_their_names.list & [4]+ Running find / -iname '*d*' &> files_with_d_in_their_names.list & # bring the 3th one into the foreground $ fg %3 moving a job from the foreground to the background # start in the foreground $ find / -iname '*a*' &> files_with_a_in_their_names.list # stopping it explicitly # Yellow( Ctrl+z ) key combination hit ^Z [1]+ Stopped find / -iname '*a*' > files_with_a_in_their_names.list # resume in the background $ bg %1 #