- Executing Multiple Commands
command1; command2; command3;- Each command will be executed one after the other.
command1 && command2- command2 will be executed only if command 1 succeeds
- If the return code is 0 it is true and if it is greater than 0 it is false
ls && date -Q && wc -l /etc/profilewill display the dir listing followed by error that -Q is invalid; wc is not executed.
command1 || command2- command2 will not be executed if command1 succeeds
ls /blah || datewill display current date after "No such file or directory"ls || datewill display just the directory listing- command2 is like a Plan B if command1 doesn't succeed.
- Example
ls /blah ; date ; wc -l /etc/profile ; - If we use parenthesis ie
(ls /blah ; date ; wc -l /etc/profile ;)the command gets executed in a subshell and is returned back to the shell we are using. - We can use
echo $BASH_SUBSHELLto return an integer which tells us at what level of execution we are.(echo $BASH_SUBSHELL)will report a value of 1(ls; (date; echo $BASH_SUBSHELL))will report a value of 2
- Launching too many subshells could be expensive computationally.
- File Descriptors
- Every command in linux has 3 file descriptors -
stdin(0) ,stdout(1),stderr(2).stdinis a pointer to a stream that is coming from the keyboard or use inputstdoutorstderrusually points to the screen where the display or output is made.- the three pointers are looking at only the stream of characters.
- they can be directed to a file or a command, or the default behaviour can be left as it is.
- Combining a command and a file
command > file1stdoutis redirected tofile1file1will be created if it does not exist- if
file1exists, its contents will be overwritten - example :
ls -1 /usr/bin > file1- displays no output on the screen because there is no error ls -1 /blah > file1- displays an error. file1 is overwritten and is now 0 Bytes.hwinfo > hwinfo.txt- trying this command in a folder where there is no w permissions will generate an error
- The
catcommand tries to read from the provided file name if not given it tries to read from stdin (keyboard)cat > file1will allow you to type content. The feature could be used to create text files on the command line. You can come out using theCtrl+Doption.cat file1displays the content offile1cattakes input from the keyboard and displays it on the screen (line by line; when you press enter) - Finish by pressingCtrl+Dto signify end of file.
command >> file1- contents will be appended to file1
- new file1 will be created if it does not exist.
- Example :
date >> file2 ; wc -l /etc/profile >> file2 ; file /usr/bin/znew >> file2 ; cat >> file1to append text to a file from command line. Come out usingCtrl+D
- Every command in linux has 3 file descriptors -
- combining command and file (continued ..)
- (contd..)
command 2> file1- redirects
stderrtofile1 file1, if it exists, will be overwritten.file1will be created if it does not exist.- Example
ls $HOME /blah 2> error.txt
- redirects
command > file1 2> file2stdoutis redirected tofile1stderris redirected tofile2- Contents of file1 and file2 will be overwritten.
- The output is in one file and the errors are in another file.
- Example :
ls $HOME /blah > output.txt 2> error.txt ls -R /etc > output.txt 2> error.txt- permission related errors in error.txt
command < file1stdinis redirected - a command expecting input from the keyboard could take the input from a file.- Example :
wc /etc/profilebehaves similar towc < /etc/profile
command > file1 2>&1- command output will be redirected to
file1 2>indicatesstderrand that is being redirected to&1(first stream) which isstdout- contents of
file1will be overwritten - Example :
ls $ HOME /blah > file1output alone is sent to file1. Error on screen - Example :
ls $ HOME /blah > file1 2>&1output and error is sent to file1.
- command output will be redirected to
command1 | command2Pipestdoutoutput of command 1 is sent tostdinof command2 as input- Example
ls /usr/bin | wc -l
command1 | command2 > file1- command1 and command2 are combined and the
stdoutof command2 is sent tofile1. Errors are still shown on the screen. - Example
ls /usr/bin | wc -l > file1- file1 has the number of lines counted by wc
- command1 and command2 are combined and the
command > file1 2> /dev/null/dev/nullfile - A sink for output to be discarded. Like a "black hole"- We normally don't do anything with the
/devfolder as there are sensitive system files there. - If you are confident that the script is running well and you do not want to display any error on the screen, you can redirect the
stderrto/dev/null stderris redirected to/dev/null- Example :
ls $HOME /blah > file1 2> /dev/null - Example :
ls -R /etc > file1 2> /dev/null- file1 contains the output except errors
command1 | tee file1- Used in sitiations where you want to have a copy of the output in a file as well as on the screen.
- The
teecommand reads fromstdinand writes tostdoutand file/s. - Example :
ls $HOME | tee file1alsols $HOME | tee file1 file2for creating multiple copies diff file1 file2comapares files line by line- no output if the files are identical
- Example :
ls $HOME /blah | tee file1 file2 | wc -l- Hereteekeeps copy of output in a file and also sends output towc -lfor further processing. - Example :
ls $HOME /blah 2> /dev/null | tee file1 file2 | wc -lto supress errors. Note location of2>is since the error is generated there.
- (contd..)
- Creation, inspection, modification, lists
- Creating a variable
myvar="value string"myvarcan't start with a number, but you can mix alphanumeric and_- No space around the
= "value string"is the number,string orcommand. Output of a command can be assigned to myvar by enclosing the command in back-ticks.
- Exporting a variable
export myvar="value string"ormyvar="value string" ; export myvar- This makes the value of the variable available to a shell that is spawned by the current shell.
- Using variable values
echo $myvarecho ${myvar}- can manipulate the value of the variable by inserting some commands within the braces.
echo "${myvar}_something"
- Removing a variable
unset myvar- Removing value of a variable
myvar=
- Test is a variable is set
[[ -v myvar ]] ; echo $?- 0 : success (variable myvar is set)
- 1 : failure (variable myvar is not set)
[[ -z ${myvar+x} ]] ; echo $?(thexcan be any string)- 0 : success (variable myvar is not set)
- 1 : failure (variable myvar is set)
- Substitute default value
- If the variable
myvaris not set, use "default" as its default value echo ${myvar:-"default"}- if
myvaris set display its value - else display "default"
- if
- If the variable
- Set default value
- If the variable
myvaris not set then set "default" as its value echo ${myvar:="default"}- if
myvaris set display its value - else set "default" as its value and display its new value
- if
- If the variable
- Reset value if variable is set
- If the variable
myvaris set, then set "default" as its value echo ${myvar:+"default"}- if
myvaris set, then set "default" as its value and display the new value - else display null
- if
- If the variable
- List of variable names
echo ${!H*}- displays the list of names of shell variables that start with H
- Length of string value
echo ${#myvar}- Display length of the string value of the variable
myvar - if
myvaris not set then display 0
- Display length of the string value of the variable
- Slice of a string value
echo ${myvar:5:4}(5 is the offset and 4 is the slice length)- Display 4 characters of the string value of the variable
myvarafter skipping first 5 characters.
- Display 4 characters of the string value of the variable
- if the slice length is larget than the length of the string then only what is available in the string will be displayed.
- the offset can also be negative. However you need to provide a space after the : to avoid confusion with the earlier usage of the
:-symbol. The offset would come from the right hand side of the string.
- Remove matching pattern
echo ${myvar#pattern}- matches onceecho ${myvar##pattern}- matches maximum possible- Whatever is matching the pattern will be removed and the rest of it will be displayed on the screen.
- Keep matching pattern
echo ${myvar%pattern}- matches onceecho ${myvar%%pattern}- matches maximum possible
- Replace matching pattern
echo ${myvar/pattern/string}- match once and replace with stringecho ${myvar//pattern/string}- match max possible and replace with string
- Replace matching pattern by location
echo ${myvar/#pattern/string}- match at begining and replace with stringecho ${myvar/%pattern/string}- match at the end and replace with string
- Changing case
echo ${myvar,}- Change the first character to lower case.echo ${myvar,,}- Change all characters to lower case.echo ${myvar^}- Change first character to uppercaseecho ${myvar^^}- Change all characters to upper case- The original value of the variable is not changed. Only the display will be modified as the trigger commands are within braces.
- Restricting value types
declare -i myvar- only integers assigneddeclare -l myvar- Only lower case chars assigneddeclare -u myvar- Only upper case chars assigneddeclare -r myvar- Variable is read only- Once a variable is set as read only you may have to restart the bash to be able to set it
- Removing restrictions
declare +i myvar- integer restriction removeddeclare +l myvar- lower case chars restriction removeddeclare +u myvar- upper case chars restriction removeddeclare +r myvar- Can't do once it is read-only
- Indexed arrays
declare -a arr- Declare
arras an indexed array
- Declare
$arr[0]=”value”- Set value of element with index 0 in the array
echo ${arr[0]}- Value of element with index 0 in the array
echo ${#arr[@]}- Number of elements in the array. The
@symbol is a wild character to run through all the elements in the array
- Number of elements in the array. The
echo ${!arr[@]}- Display all indices used
echo ${arr[@]}- Display values of all elements of the array
unset ‘arr[2]’- Delete element with index 2 in the array
arr+=(“value”)- Append an element with a value to the end of the array
- Associative arrays
declare -A hash- declare
hashas an associative array
- declare
$hash[“a”]=”value”- set the value of element with index a in the array
echo ${hash[“a”]}- value of element with index a in the array
echo ${#hash[@]}- number of elements in the array
echo ${!hash[@]}- display all indices used
echo ${hash[@]}- display values of all elements of the array
unset ‘hash[“a”]’- delete an element with index a in the array
- Can do everything in the indexed array except append because there is nothing called the end of the array as there is no sequence for the elements of a hash
- Examples
truealways returns exit code 0falsealways returns exit code 1 (Check withecho $?)- To check whether a variable is present
[[ -v myvar ]] ; echo $?returns 1 if the variable is not present in the memory[[ -z ${myvar+x} ]] ; echo $?returns 0 if variable is not present and 1 if it is present.xis a string that will be used as a replacement if the variable was not present.
- Use of Braces
myvar=FileNameecho $myvarecho "$myvar.txt"prints FileName.txtecho "$myvar_txt"does not print anything as the variablemyvar_txtdoes not existecho "${myvar}_txt"prints Filename_txt- Braces are useful in stating clearly the name of the variable.
- Can also be used outside quotes
echo ${myvar}
- Does the variable we have created get passed on to the shell or any other program created within the shell
myvar=3.14 ; echo $myvarbashone more level of bashps --forestto show that we are one level belowecho $myvarnot present- Use
export myvar=3.14to ensure this variable is available to all spawned sub shells. - Change value of variable within the child shell
- modification of value is not reflected in the value of the variable in the parent shell
- even if you do export of the variable within the child shell it will not change the value within the parent shell.
- Use of back-ticks
mydate=`date`value of mydate will be output of date.mydate=`echo Sunday that is today` ; echo $mydate
- Manipulations for variables within the shell environment
- We would like to have echo display a default value if variable is not available
echo ${myvar:-hello}the-indicates if the value is not present what is the display valueecho ${myvar:-"myvar is not set"}- Set the value if it was not set already
echo ${myvar:=hello}if absent / not set then set it to the value after=- If it is present it will not change
echo ${myvar:?"myvar is not set"}displays a little more information and a debug message.bash: myvar: myvar is not set- Unset the value of a variable using
unset myvar echo ${myvar:+HELLO}displays the message if the variable is present
- Inspecting all the variables in the shell environment
printenvenvecho ${!H*}displays the names of variables begining with 'H' -!indicates names of the variables instead of value.
- Counting characters
mydate=`date`stores the output of thedatecommand inmydateecho ${#mydate}prints the length of the value present in mydate.- length of a non-existing variable is zero
- Features of using colon : within braces {}
- Extracting part of a string from the value of a particular variable.
echo ${mydate:6:10}echo ${myvar:3:3}will printdefformyvar=abcdefgie: 3 characters after the offset (position 3)
- Using negative offset
echo ${myvar: -3:3}andecho ${myvar: -3:4}will printefgformyvar=abcdefg- note
-is to be preceeded with a blank to avoid confusion - asking for more characters, will print just what is available
- note
echo ${myvar: -3:2}will printefformyvar=abcdefg
- Extracting a portion of the date
- Output of
dateisTuesday 25 January 2022 09:10:20 PM IST - Output of
date +"%d %B %Y"is25 January 2022 - if
mydate=`date`thenecho ${mydate:8:16}will also print25 January 2022
- Output of
- Extracting patterns from a string
myvar=filename.txt.jpgecho ${myvar#*.}minimal matching displaystxt.jpgmyvar=filename.somethingelse.jpegecho ${myvar##*.}maximal matching displaysjpegecho ${myvar%*.}displays filename.somethingelse- the
%is used to indicate what has not been matched. (minimal)
- the
echo ${myvar%%*.}displays filename- the
%is used to indicate what has not been matched. (maximal)
- the
- Can be combined
echo ${myvar%%.*}.${myvar##*.}to getfilename.jpeg
- Replacing what has been matched
- Pattern matching in Linux usually goes with a pair of forward slashes.
- Convert all
etoEin a stringecho ${myvar/e/E}replaces only the first occurance ofeecho ${myvar//e/E}replaces all occurances ofe
- Replace characters at the begining of a string
echo ${myvar/#f/F}replaces the occurance offin the begining of the string withF. The#indicates the begining of the string
- Replace characters at the end of a string
echo ${myvar/%g/G}replaces the occurance ofgat the end of the string withG. The%indicates the end of the string.
- Replace jpeg with jpg, only if it is at the end of a string
echo ${myvar/%jpeg/jpg}
- Modifying and storing it in a variable
myvar1=`echo ${myvar//jpeg/jpg}`
- Generic command to remove day from date
echo ${mydate#*day}
- Upper case to lower case and vice-versa
echo ${mydate,}changes first character to lowercaseecho ${mydate,,}converts all characters to lowercaseecho ${mydate^}changes first character to uppercaseecho ${mydate^^}changes all characters to uppercase
- Restricting values that can be assigned to shell variables using
declaredeclareis a shell builtin+to unset a restriction and-to set it (Note : counterintutuve )-afor indexed arrays (need not be ordered indexes)-Afor associative arrays (dictionaries)-ifor integers-ufor uppercase conversion on assignment- Integer restriction
declare -i mynummynum=10will assign 10 to mynummynum=hellowill assign 0 to mynum
- lowercase restriciton
declare -l myvarmyvar=helloassigns hello to myvarmyvar=BELLOWconverts BELLOW to lowercase and assigns it to myvar.
- removing a restriction
declare +l myvar- the value is still contained after removing the restriction but you can now store upper case characters as well
- declaring a read-only variable
declare -r myvar- once a variable has been set as read only, you cannot change its value and you cannot remove the read-only restriction using
+r declare +r myvargives the errorbash: declare: myvar: readonly variable
- Arrays
declare -a arrarr[0]=Sundayarr[1]=Mondayecho ${arr[0]}echo ${arr[1]}echo ${#arr[@]}gives number of elements in the arrayecho ${arr[@]}displays all valuesecho ${!arr[@]}displays the indices`- You can have any index without filling up intermediate indices. Indices are not necessarily contiguous.
arr[100]=Fridayis also valid- Removing an element from an array =
unset 'arr[100]' - Appending to an array
arr+=(Tuesday) - Populating an array in one go
arr=(Sunday Monday Tuesday). The indices are sequential
- Associative Arrays / Hashes
declare -A hashhash[0]="Amal"hash["mm12b001"]="Charlie"echo ${!hash[@]}to get indicesecho ${hash["mm12b001"]}
- File names in a shell variable
myfiles=(`ls`)echo ${myfiles[@]}
- Extracting part of a string from the value of a particular variable.