Skip to content

Latest commit

 

History

History
341 lines (337 loc) · 19.1 KB

Week3.md

File metadata and controls

341 lines (337 loc) · 19.1 KB

Week 3 Notes

Combining Commands and Files

  • 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/profile will 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 || date will display current date after "No such file or directory"
      • ls || date will 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_SUBSHELL to 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).
      • stdin is a pointer to a stream that is coming from the keyboard or use input
      • stdout or stderr usually 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 > file1
        • stdout is redirected to file1
        • file1 will be created if it does not exist
        • if file1 exists, 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 cat command tries to read from the provided file name if not given it tries to read from stdin (keyboard)
          • cat > file1 will allow you to type content. The feature could be used to create text files on the command line. You can come out using the Ctrl+D option.
          • cat file1 displays the content of file1
          • cat takes input from the keyboard and displays it on the screen (line by line; when you press enter) - Finish by pressing Ctrl+D to 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 >> file1 to append text to a file from command line. Come out using Ctrl + D

Redirections

  • combining command and file (continued ..)
    • (contd..)
      • command 2> file1
        • redirects stderr to file1
        • file1, if it exists, will be overwritten.
        • file1 will be created if it does not exist.
        • Example ls $HOME /blah 2> error.txt
      • command > file1 2> file2
        • stdout is redirected to file1
        • stderr is redirected to file2
        • 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 < file1
        • stdin is redirected - a command expecting input from the keyboard could take the input from a file.
        • Example : wc /etc/profile behaves similar to wc < /etc/profile
      • command > file1 2>&1
        • command output will be redirected to file1
        • 2> indicates stderr and that is being redirected to &1 (first stream) which is stdout
        • contents of file1 will be overwritten
        • Example : ls $ HOME /blah > file1 output alone is sent to file1. Error on screen
        • Example : ls $ HOME /blah > file1 2>&1 output and error is sent to file1.
      • command1 | command2 Pipe
        • stdout output of command 1 is sent to stdin of command2 as input
        • Example ls /usr/bin | wc -l
      • command1 | command2 > file1
        • command1 and command2 are combined and the stdout of command2 is sent to file1. Errors are still shown on the screen.
        • Example ls /usr/bin | wc -l > file1 - file1 has the number of lines counted by wc
      • command > file1 2> /dev/null
        • /dev/null file - A sink for output to be discarded. Like a "black hole"
        • We normally don't do anything with the /dev folder 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 stderr to /dev/null
        • stderr is 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 tee command reads from stdin and writes to stdout and file/s.
        • Example : ls $HOME | tee file1 also ls $HOME | tee file1 file2 for creating multiple copies
        • diff file1 file2 comapares files line by line
          • no output if the files are identical
        • Example : ls $HOME /blah | tee file1 file2 | wc -l - Here tee keeps copy of output in a file and also sends output to wc -l for further processing.
        • Example : ls $HOME /blah 2> /dev/null | tee file1 file2 | wc -l to supress errors. Note location of 2> is since the error is generated there.

Shell Variables - Part 1

  • Creation, inspection, modification, lists
  • Creating a variable
    • myvar="value string"
      • myvar can't start with a number, but you can mix alphanumeric and _
      • No space around the =
      • "value string" is the number,string or command. Output of a command can be assigned to myvar by enclosing the command in back-ticks.
  • Exporting a variable
    • export myvar="value string" or
    • myvar="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 $myvar
    • echo ${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 $? (the x can be any string)
      • 0 : success (variable myvar is not set)
      • 1 : failure (variable myvar is set)
  • Substitute default value
    • If the variable myvar is not set, use "default" as its default value
    • echo ${myvar:-"default"}
      • if myvar is set display its value
      • else display "default"
  • Set default value
    • If the variable myvar is not set then set "default" as its value
    • echo ${myvar:="default"}
      • if myvar is set display its value
      • else set "default" as its value and display its new value
  • Reset value if variable is set
    • If the variable myvar is set, then set "default" as its value
    • echo ${myvar:+"default"}
      • if myvar is set, then set "default" as its value and display the new value
      • else display null
  • 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 myvar is not set then display 0
  • 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 myvar after skipping first 5 characters.
    • 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 once
    • echo ${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 once
    • echo ${myvar%%pattern} - matches maximum possible
  • Replace matching pattern
    • echo ${myvar/pattern/string} - match once and replace with string
    • echo ${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 string
    • echo ${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 uppercase
    • echo ${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 assigned
    • declare -l myvar - Only lower case chars assigned
    • declare -u myvar - Only upper case chars assigned
    • declare -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 removed
    • declare +l myvar - lower case chars restriction removed
    • declare +u myvar - upper case chars restriction removed
    • declare +r myvar - Can't do once it is read-only
  • Indexed arrays
    • declare -a arr
      • Declare arr as an indexed array
    • $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
    • 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 hash as an associative array
    • $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
    • true always returns exit code 0
    • false always returns exit code 1 (Check with echo $?)
    • 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. x is a string that will be used as a replacement if the variable was not present.
    • Use of Braces
      • myvar=FileName
      • echo $myvar
      • echo "$myvar.txt" prints FileName.txt
      • echo "$myvar_txt" does not print anything as the variable myvar_txt does not exist
      • echo "${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 $myvar
      • bash one more level of bash
      • ps --forest to show that we are one level below
      • echo $myvar not present
      • Use export myvar=3.14 to 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 value
      • echo ${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
      • printenv
      • env
      • echo ${!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 the date command in mydate
      • echo ${#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 print def for myvar=abcdefg ie: 3 characters after the offset (position 3)
      • Using negative offset
        • echo ${myvar: -3:3} and echo ${myvar: -3:4} will print efg for myvar=abcdefg
          • note - is to be preceeded with a blank to avoid confusion
          • asking for more characters, will print just what is available
        • echo ${myvar: -3:2} will print ef for myvar=abcdefg
      • Extracting a portion of the date
        • Output of date is Tuesday 25 January 2022 09:10:20 PM IST
        • Output of date +"%d %B %Y" is 25 January 2022
        • if mydate=`date` then echo ${mydate:8:16} will also print 25 January 2022
      • Extracting patterns from a string
        • myvar=filename.txt.jpg
        • echo ${myvar#*.} minimal matching displays txt.jpg
        • myvar=filename.somethingelse.jpeg
        • echo ${myvar##*.} maximal matching displays jpeg
        • echo ${myvar%*.} displays filename.somethingelse
          • the % is used to indicate what has not been matched. (minimal)
        • echo ${myvar%%*.} displays filename
          • the % is used to indicate what has not been matched. (maximal)
        • Can be combined echo ${myvar%%.*}.${myvar##*.} to get filename.jpeg
      • Replacing what has been matched
      • Pattern matching in Linux usually goes with a pair of forward slashes.
      • Convert all e to E in a string
        • echo ${myvar/e/E} replaces only the first occurance of e
        • echo ${myvar//e/E} replaces all occurances of e
      • Replace characters at the begining of a string
        • echo ${myvar/#f/F} replaces the occurance of f in the begining of the string with F. The # indicates the begining of the string
      • Replace characters at the end of a string
        • echo ${myvar/%g/G} replaces the occurance of g at the end of the string with G. 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 lowercase
        • echo ${mydate,,} converts all characters to lowercase
        • echo ${mydate^} changes first character to uppercase
        • echo ${mydate^^} changes all characters to uppercase
      • Restricting values that can be assigned to shell variables using declare
        • declare is a shell builtin
        • + to unset a restriction and - to set it (Note : counterintutuve )
        • -a for indexed arrays (need not be ordered indexes)
        • -A for associative arrays (dictionaries)
        • -i for integers
        • -u for uppercase conversion on assignment
        • Integer restriction
          • declare -i mynum
          • mynum=10 will assign 10 to mynum
          • mynum=hello will assign 0 to mynum
        • lowercase restriciton
          • declare -l myvar
          • myvar=hello assigns hello to myvar
          • myvar=BELLOW converts 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 myvar gives the error bash: declare: myvar: readonly variable
      • Arrays
        • declare -a arr
        • arr[0]=Sunday
        • arr[1]=Monday
        • echo ${arr[0]}
        • echo ${arr[1]}
        • echo ${#arr[@]} gives number of elements in the array
        • echo ${arr[@]} displays all values
        • echo ${!arr[@]} displays the indices`
        • You can have any index without filling up intermediate indices. Indices are not necessarily contiguous.
        • arr[100]=Friday is 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 hash
        • hash[0]="Amal"
        • hash["mm12b001"]="Charlie"
        • echo ${!hash[@]} to get indices
        • echo ${hash["mm12b001"]}
      • File names in a shell variable
        • myfiles=(`ls`)
        • echo ${myfiles[@]}