Posts

Showing posts from August, 2015

Combining Tests || &&

Combining Tests It is possible to combine tests by using the && and || operators. These perform a Logical AND and Logical OR, respectively. #!/bin/bash filename=${1:-/etc/hosts} if [ -r “$filename” ] && [ -s “$filename” ]; then md5sum $filename else echo “$filename can not be processed” fi # Show the file if possible ls -ld $filename 2>/dev/null ----------- cat f filename=$1 [ -r $filename ] || echo “$filename is not readable” bash f /etc/shadow “/etc/shadow is not readable” ubuntu2@ubuntu2:~/Documents/shellscripting$ bash f t/ cat f filename=$1 [ -r $filename ] && echo “$filename is readable” bash f t/ “t/ is readable” ubuntu2@ubuntu2:~/Documents/shellscripting$ bash f /etc/shadow ----------------

guess number

cat guess #!/bin/bash MAX=50 guess=1 let answer=($RANDOM % $MAX) let answer+=1 ceiling=$MAX floor=0 guesses=0 while [[ “$guess” != “$answer” ]] do echo “The magic number is between $floor and $ceiling.” echo -en “ Make your guess:” read guess guesses=`expr $guesses + 1` if [[ “$guess” < “$answer” ]]; then echo “$guess is too low” if [[ “$guess” > “$floor” ]]; then floor=`expr $guess + 1` fi fi if [[ “$guess” > “$answer” ]]; then echo “$guess is too high” if [[ “$guess” < “$ceiling” ]]; then ceiling=`expr $guess - 1` fi fi done echo “You got it in $guesses guesses!” --------- bash guess “The magic number is between 0 and 50.” “ Make your guess:”33 “33 is too low” “The magic number is between 34 and 50.” “ Make your guess:”40 “40 is too low” “The magic number is between 41 and 50.” “ Make your guess:”46 “46 is too low” “The magic number is between 47 and 50.” “ Make your guess:”49 “49 is too high” “The magic number is between 47 an

=~ operator

A feature new since bash 3 is the =~ operator, which acts much like its perl equivalent This means that you can identify file names that match the pattern *.deb by checking for [[ $pkgname =~ .*\.deb ]]. Note that the doublebracket syntax [[ ... ]] is required.

file inode comparison

The test command can also do a few basic comparisons between files. The -ef comparison tests if two files are actually hard links to the same inode on the same filesystem. This saves quite a bit of trouble, because although stat --format=%i or ls -i can provide the inode number of a file, you would still have to check that the two files are on the same filesystem.

suid

Another feature of Unix-style file permissions are the suid (Set UserID) and sgid (Set GroupID)bits. These allow the program to be run as the user (or group), which owns the file, not necessarily the user (or group) running the program. This is shown as an s instead of an x in the rwx style of displaying file permissions. You can test for these using the -g and -u flags respectively.

for sed elif

#!/bin/bash for i in a b c do echo $i done bash for1  a b c ----------- GNU sed has the option -i to update the file sed s/for/sss/g for1 -i ubuntu2@ubuntu2:~/Documents/shellscripting$ cat for1 #!/bin/bash sss i in a b c do echo $i done --------- How to add text to the particular line in the file:  sed -i '1s/^/task goes here\n/' for1 ------------ sed -n '1p;$p' file.txt  will print 1st and last line of file.txt . ----------  cat for1 #!/bin/bash for i in a b c do echo $i done if [ "$?" -ne "0" ]; then echo not ok else echo ok fi bash for1 a b c ok ----------- cat ifelif1 #!/bin/bash     #   elif example ################## echo Hi OS=`uname -s` if [ "$OS" = "Linux" ]; then echo Linux elif [ "$OS" = "UNIX" ]; then echo UNIX fi bash ifelif1  Hi Linux ------------- cat whileread #/bin/bash while read -p "Enter fi

if conditions | File-based conditions in If statements

if [ -f regularfile ]; then if [ -r readablefile]; then The syntax of an if statement (a short explanation) if <condition>; then <commands> fi ----- The -z test returns true if the string has zero length , while -n returns true if the string has nonzero length . while [ -z “$input” ]; do read -p “Please give your input: “ input done echo “Thank you for saying $input” ----- The string comparisons < and > only work within the [[ ... ]] compound command. You can use the == and != tests within either a single or double bracket test, but the single bracket test is the only one that works with a single equal sign (=).  The reason for this complexity is to maintain compatibility with the Bourne shell while adding the more powerful [[ command. ----- ls -l new old -rw-rw-r-- 1 steve steve 11 Dec 14 13:21 new -rw-rw-r-- 1 steve steve 9 Dec 14 13:20 old $ if [ new -nt old ]; then echo “ new is newer ” else echo “ old is newer ” fi -----

add the same value into manu files | for

for i in f* do date > $i done

if true do nothing else do

How do I write the "do nothing" statement in the following example? Example: if (( "$x"="1" && "$y"="a" && "$z"="happy" )) then do nothing else command command fi if (( "$x"="1" && "$y"="a" && "$z"="happy" )); then : else command command fi Another way, invert your test : Code: if (( "$x"!="1" || "$y"!="a" || "$z"!="happy" )) then command command fi ======================== value=$( grep -ic "benjamin" /etc/passwd ) if [ $value -eq 1 ] then echo "I found Benjamin" fi value=$( grep -ic "benjamin" /etc/passwd ) if [ $value -ge 1 ] then if [ $value -eq 1 ] then echo "I found Benjamin" elif [ $value -eq 2 ] then echo "I found two Benjamins" else

rm -rf | rename multiple files | uppercase | mmv

how to remove folder -rf drwxrwxr-x 2 ubuntu2 ubuntu2 4096 Aug 16 09:21 -rf/ ubuntu2@ubuntu2:~/temp/s$ rm -r -- -rf ----------- if you want to match the character [, you have to put it first in the list, as [[aeiou] if you want to match the character -, you can put it at the start or the end ubuntu2@ubuntu2:~/temp/s$ ls [[ael]* a1  a2  a3  a4  a5  l if you want to match the character -, you can put it at the start or the end ls [-ael] or [ael-] ---------------- rename multiple files -rw-rw-r-- 1 ubuntu2 ubuntu2    0 Aug 16 09:32 z1.dot -rw-rw-r-- 1 ubuntu2 ubuntu2    0 Aug 16 09:32 z2.dot -rw-rw-r-- 1 ubuntu2 ubuntu2    0 Aug 16 09:32 z3.dot ubuntu2@ubuntu2:~/temp/s$ rename s/z/b/ z{1..3}.dot -rw-rw-r-- 1 ubuntu2 ubuntu2    0 Aug 16 09:32 b1.dot -rw-rw-r-- 1 ubuntu2 ubuntu2    0 Aug 16 09:32 b2.dot -rw-rw-r-- 1 ubuntu2 ubuntu2    0 Aug 16 09:32 b3.dot ---------------- rename s:b:z: b{1..3}.dot -rw-rw-r-- 1 ubuntu2 ubuntu2    0 Aug 16 09:3

shopt nocaseglob

$ shopt -s nocaseglob $ ll a* -rw-rw-r-- 1 ubuntu2 ubuntu2 0 Aug 12 12:53 a1 -rw-rw-r-- 1 ubuntu2 ubuntu2 0 Aug 12 12:59 A1 -rw-rw-r-- 1 ubuntu2 ubuntu2 0 Aug 12 12:53 a2 -rw-rw-r-- 1 ubuntu2 ubuntu2 0 Aug 12 12:59 A2 $ shopt -u nocaseglob  ubuntu2@ubuntu2:~/temp/s$ ls a* a1  a2  a3  a4  a5

patterns ? * + @ !

Wildcards pattern MatcheS ? (pattern-list) Zero or one of the patterns * (pattern-list) Zero or more of the patterns + (pattern-list) One or more of the patterns @ (pattern-list) Exactly one of the patterns ! (pattern-list) Anything except one of the patterns

for file in do md5sum

s$ cat l for file in a* do md5sum $file done bash l d41d8cd98f00b204e9800998ecf8427e  a1 d41d8cd98f00b204e9800998ecf8427e  a2

shel options

 Why does rm -rf /tmp/myfiles/* not result in an empty directory? Because of /tmp/myfiles/.config. You can’t use rm -rf /tmp/ myfiles/.* because that would match /tmp/myfiles/.., which is /tmp itself. You could always use rm -rf /tmp/myfiles, which will remove /tmp/myfiles and everything in it, but if you want the directory to remain, you can use the dotglob shell option.

available classes

claSS MeMBerS Alnum A-Z, a-z, 0-9 Alpha A-Z, a-z Blank Space, Tab Cntrl ASCII characters 0-31 (nonprinting control characters) Digit 0-9 .... etc

PATH

PATH is a colon-separated list of directories used to find program files. It is searched left-to-right, so if PATH=/home/steve/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11 In PATH, a period (.) is used to represent the current directory of the calling program. Less well known is that a double colon (::) will do the same, and a single colon at the beginning or end of the PATH variable will also expand to the current working directory. So if your PATH=:/usr/bin:/bin, then any file called ls in the current directory will be executed when you call ls.  An attacker could place a malicious ls in /tmp, and simply wait for the superuser to decide to list the files in /tmp

cd itself will cd to the $HOME

 If you run cd by itself, it will cd to the value of $HOME

bash -x set -x set +x

cat sc #!/bin/bash for i in {1..3} do let i++ echo $i done ---------- bash -x sc + for i in '{1..3}' + let i++ + echo 2 2 + for i in '{1..3}' + let i++ + echo 3 3 + for i in '{1..3}' + let i++ + echo 4 4 ------------------  use the set -x and set +x in the script to enable the -x log- ging feature of the shell just for that part of the script

FUNCNAME

 cat main #!/bin/bash . lib1.sh . lib2.sh func1 ubuntu2@ubuntu2:~/temp$ cat lib1.sh  #!/bin/bash function func1() { echo "func1: FUNCNAME0 is ${FUNCNAME[0]}" echo "func1: FUNCNAME1 is ${FUNCNAME[1]}" echo "func1: FUNCNAME2 is ${FUNCNAME[2]}" echo "func1: BASH_SOURCE0 is ${BASH_SOURCE[0]}" echo "func1: BASH_SOURCE1 is ${BASH_SOURCE[1]}" echo "func1: BASH_SOURCE2 is ${BASH_SOURCE[2]}" echo "func1: LINENO is ${LINENO}" func2 } ubuntu2@ubuntu2:~/temp$ cat lib2.sh  function func2() { echo "func2: FUNCNAME0 is ${FUNCNAME[0]}" echo "func2: FUNCNAME1 is ${FUNCNAME[1]}" echo "func2: FUNCNAME2 is ${FUNCNAME[2]}" echo "func2: BASH_SOURCE0 is ${BASH_SOURCE[0]}" echo "func2: BASH_SOURCE1 is ${BASH_SOURCE[1]}" echo "func2: BASH_SOURCE2 is ${BASH_SOURCE[2]}" # This comment makes lib2.sh different from lib1.sh echo "func2: LINENO is ${LI

BASH_ENV SHELLOPTS BASH_COMMAND

BASH_ENV is the name of a file (which may be a relative path, in which case be very careful about where you run your scripts from!) which is parsed before executing the file , much as ~/.bashrc is parsed before starting an interactive shell. echo $ SHELLOPTS braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor SHELLOPTS is similar to BASHOPTS; it is a list of -o options set. So if you set -o vi, then vi will appear in the list of options, and the shell will work in its vi. Like BASHOPTS, SHELLOPTS is read-only BASH_COMMAND is the name of the currently executing command. BASH_SOURCE, FUNCNAME, LINENO and BASH_LINENO are incredibly useful debugging variables that tell you just where you are in the script, even when you have multiple files in use. LINENO simply gives you the current line number in the script: ubuntu2@ubuntu2:~/temp$ cat f1 #!/bin/bash  echo “Hello, World”  echo “This is line $LINENO ”  ubuntu2@ubuntu2:~/temp$ bas

echo -n

the -n switch to echo tells echo not to put a newline character at the end.

~/.inputrc and /etc/inputrc

/etc/inputrc and ~/.inputrc are used by GNU readline facility (used by bash and many other utilities to read a line of text from the terminal) to control how readline behaves. useful bash option to know is set completion-ignore-case On which means that when you type cd foo and press the Tab key, if there is no foo* directory, the shell will search without case, so that any directories named Foo*, fOo* or fOO* will match. 

HISTCONTROL HISTIGNORE

HISTIGNORE is a colon-separated list of commands that should not be stored in the history HISTCONTROL can tell history to ignore leading space or duplicates

paste

paste file1 file2 name,surname salary,bonus Emma,Stanford 1000,100 Ilya,Ivanov 500,100 George,Miller 400,50 paste file1 file2 -d "," name,surname,salary,bonus Emma,Stanford,1000,100 Ilya,Ivanov,500,100 George,Miller,400,50

tac

ubuntu2@ubuntu2:~$ cat file1 hello Mon Aug 10 11:31:34 PDT 2015 ubuntu2  :0           2015-08-10 11:10 (:0) ubuntu2  pts/2        2015-08-10 11:14 (:0) ubuntu2@ubuntu2:~$ tac file1 ubuntu2  pts/2        2015-08-10 11:14 (:0) ubuntu2  :0           2015-08-10 11:10 (:0) Mon Aug 10 11:31:34 PDT 2015 hello ubuntu2@ubuntu2:~$

curl

https://www.gitbook.com/download/pdf/book/bagder/everything-curl download file $ curl -O http://www.asipress.ir/en/index.txt   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                  Dload  Upload   Total   Spent    Left  Speed 100 24632    0 24632    0     0  22433      0 --:--:--  0:00:01 --:--:-- 22453 ------------------------- if you pressed ctrl+C, you can try to resume stopped session Using curl -C option, you can continue a download which was stopped already for some reason. $ curl -C - -O http://www.asipress.ir/en/index.txt ** Resuming transfer from byte position 16384   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                  Dload  Upload   Total   Spent    Left  Speed   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0 curl: (33) HTTP server doesn't seem to support byte ranges. Cannot resume. -------------------------