Difference between revisions of "Bash"

From Ilianko
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
http://www.tldp.org/LDP/Bash-Beginners-Guide/html/
 
http://www.tldp.org/LDP/Bash-Beginners-Guide/html/
 +
 +
  
 
== четене от стандартния вход (най-често терминала)==
 
== четене от стандартния вход (най-често терминала)==
Line 37: Line 39:
 
  done
 
  done
  
 +
for VARIABLE in file1 file2 file3
 +
do
 +
  command1 on $VARIABLE
 +
  command2
 +
  commandN
 +
done
  
 +
for OUTPUT in $(Linux-Or-Unix-Command-Here)
 +
do
 +
  command1 on $OUTPUT
 +
  command2 on $OUTPUT
 +
  ...
 +
  commandN
 +
done
  
 
+
Примери:
 
 
for VARIABLE in file1 file2 file3
 
do
 
command1 on $VARIABLE
 
command2
 
commandN
 
done
 
OR
 
 
 
for OUTPUT in $(Linux-Or-Unix-Command-Here)
 
do
 
command1 on $OUTPUT
 
command2 on $OUTPUT
 
commandN
 
done
 
Examples
 
 
 
 
This type of for loop is characterized by counting. The range is specified by a beginning (#1) and ending number (#5). The for loop executes a sequence of commands for each member in a list of items. A representative example in BASH is as follows to display welcome message 5 times with for loop:
 
This type of for loop is characterized by counting. The range is specified by a beginning (#1) and ending number (#5). The for loop executes a sequence of commands for each member in a list of items. A representative example in BASH is as follows to display welcome message 5 times with for loop:
#!/bin/bash
+
#!/bin/bash
for i in 1 2 3 4 5
+
for i in 1 2 3 4 5
do
+
do
 
   echo "Welcome $i times"
 
   echo "Welcome $i times"
done
+
done
 
Sometimes you may need to set a step value (allowing one to count by two's or to count backwards for instance). Latest bash version 3.0+ has inbuilt support for setting up ranges:
 
Sometimes you may need to set a step value (allowing one to count by two's or to count backwards for instance). Latest bash version 3.0+ has inbuilt support for setting up ranges:
  
#!/bin/bash
+
#!/bin/bash
for i in {1..5}
+
for i in {1..5}
do
+
  do
  echo "Welcome $i times"
+
  echo "Welcome $i times"
done
+
  done
 +
 
 
Bash v4.0+ has inbuilt support for setting up a step value using {START..END..INCREMENT} syntax:
 
Bash v4.0+ has inbuilt support for setting up a step value using {START..END..INCREMENT} syntax:
 
+
#!/bin/bash
#!/bin/bash
+
echo "Bash version ${BASH_VERSION}..."
echo "Bash version ${BASH_VERSION}..."
+
for i in {0..10..2}
for i in {0..10..2}
 
 
   do
 
   do
 
     echo "Welcome $i times"
 
     echo "Welcome $i times"
done
+
  done
 +
 
 
Sample outputs:
 
Sample outputs:
 
+
Bash version 4.0.33(0)-release...
Bash version 4.0.33(0)-release...
+
Welcome 0 times
Welcome 0 times
+
Welcome 2 times
Welcome 2 times
+
Welcome 4 times
Welcome 4 times
+
Welcome 6 times
Welcome 6 times
+
Welcome 8 times
Welcome 8 times
+
Welcome 10 times
Welcome 10 times
 
The seq command (outdated)
 
 
 
WARNING! The seq command print a sequence of numbers and it is here due to historical reasons. The following examples is only recommend for older bash version. All users (bash v3.x+) are recommended to use the above syntax.
 
The seq command can be used as follows. A representative example in seq is as follows:
 
 
 
#!/bin/bash
 
for i in $(seq 1 2 20)
 
do
 
  echo "Welcome $i times"
 
done
 
There is no good reason to use an external command such as seq to count and increment numbers in the for loop, hence it is recommend that you avoid using seq. The builtin command are fast.
 
  
 
===Three-expression bash for loops syntax ===
 
===Three-expression bash for loops syntax ===
Line 110: Line 97:
 
command3
 
command3
 
done
 
done
 +
</pre></code>
  
 
A representative three-expression example in bash as follows:
 
A representative three-expression example in bash as follows:
 
+
====Три-условен for====
 
<code><pre>
 
<code><pre>
 
  #!/bin/bash
 
  #!/bin/bash
Line 148: Line 136:
 
</pre></code>
 
</pre></code>
  
 +
===Безкраен цикъл===
  
 +
#!/bin/bash
 +
for (( ; ; ))
 +
do
 +
  echo "infinite loops [ hit CTRL+C to stop]"
 +
done
  
 
+
===Изход с break===
 
 
 
 
 
 
 
 
 
 
How do I use for as infinite loops?
 
 
 
Infinite for loop can be created with empty expressions, such as:
 
 
 
#!/bin/bash
 
for (( ; ; ))
 
do
 
  echo "infinite loops [ hit CTRL+C to stop]"
 
done
 
Conditional exit with break
 
  
 
You can do early exit with break statement inside the for loop. You can exit from within a FOR, WHILE or UNTIL loop using break. General break statement inside the for loop:
 
You can do early exit with break statement inside the for loop. You can exit from within a FOR, WHILE or UNTIL loop using break. General break statement inside the for loop:
  
for I in 1 2 3 4 5
+
for I in 1 2 3 4 5
do
+
do
 
   statements1      #Executed for all values of ''I'', up to a disaster-condition if any.
 
   statements1      #Executed for all values of ''I'', up to a disaster-condition if any.
 
   statements2
 
   statements2
Line 178: Line 157:
 
   fi
 
   fi
 
   statements3          #While good and, no disaster-condition.
 
   statements3          #While good and, no disaster-condition.
done
+
done
 +
 
 
Following shell script will go though all files stored in /etc directory. The for loop will be abandon when /etc/resolv.conf file found.
 
Following shell script will go though all files stored in /etc directory. The for loop will be abandon when /etc/resolv.conf file found.
  
#!/bin/bash
+
#!/bin/bash
for file in /etc/*
+
for file in /etc/*
do
+
  do
if [ "${file}" == "/etc/resolv.conf" ]
+
  if [ "${file}" == "/etc/resolv.conf" ]
then
+
  then
countNameservers=$(grep -c nameserver /etc/resolv.conf)
+
    countNameservers=$(grep -c nameserver /etc/resolv.conf)
echo "Total  ${countNameservers} nameservers defined in ${file}"
+
    echo "Total  ${countNameservers} nameservers defined in ${file}"
break
+
    break
fi
+
  fi
done
+
done
Early continuation with continue statement
 
  
To resume the next iteration of the enclosing FOR, WHILE or UNTIL loop use continue statement.
+
Early continuation with continue statement. To resume the next iteration of the enclosing FOR, WHILE or UNTIL loop use continue statement.
  
for I in 1 2 3 4 5
+
for I in 1 2 3 4 5
do
+
do
 
   statements1      #Executed for all values of ''I'', up to a disaster-condition if any.
 
   statements1      #Executed for all values of ''I'', up to a disaster-condition if any.
 
   statements2
 
   statements2
Line 204: Line 183:
 
   fi
 
   fi
 
   statements3
 
   statements3
done
+
done
 +
 
 +
 
 +
===Пример продължение
 
This script make backup of all file names specified on command line. If .bak file exists, it will skip the cp command.
 
This script make backup of all file names specified on command line. If .bak file exists, it will skip the cp command.
  
 +
#!/bin/bash
 +
FILES="$@"
 +
for f in $FILES
 +
do
 +
# if .bak backup file exists, read next file
 +
  if [ -f ${f}.bak ]
 +
  then
 +
    echo "Skiping $f file..."
 +
    continue  # read next file and skip cp command
 +
  fi
 +
# we are hear means no backup file exists, just use cp command to copy file
 +
  /bin/cp $f $f.bak
 +
done
 +
 +
== Масиви ==
 +
 +
<code><pre>
 
#!/bin/bash
 
#!/bin/bash
FILES="$@"
+
 
for f in $FILES
+
declare abc=()
do
+
 
        # if .bak backup file exists, read next file
+
for((i=0;i<100;i++))
if [ -f ${f}.bak ]
+
do  
then
+
# echo "write something!"
echo "Skiping $f file..."
+
# read line
continue # read next file and skip cp command
+
 
fi
+
sleep 1
        # we are hear means no backup file exists, just use cp command to copy file
+
ping 10.3.0.1  >/dev/null &
/bin/cp $f $f.bak
+
abc+=($!)
 +
 
 +
echo "Process: $i. s PID ${abc[$i]}"
 +
  echo "start pinging"
 +
done
 +
 
 +
sleep 5
 +
 
 +
for((i=0;i<100;i++))
 +
do
 +
sleep 1
 +
kill ${abc[$i]}
 +
echo "killed:  PID ${abc[$i]}"
 +
echo "start pinging"
 
done
 
done
 +
</pre></code>

Latest revision as of 21:03, 28 October 2013

http://www.tldp.org/LDP/Bash-Beginners-Guide/html/


четене от стандартния вход (най-често терминала)

read from stdin

#!/bin/bash
echo "write something!"
  read line 
echo "tova e: $line"

for

How do I use bash for loop to repeat certain task under Linux / UNIX operating system? How do I set infinite loops using for statement? How do I use three-parameter for loop control expression?

A 'for loop' is a bash programming language statement which allows code to be repeatedly executed. A for loop is classified as an iteration statement i.e. it is the repetition of a process within a bash script.


For example, you can run UNIX command or task 5 times or read and process list of files using a for loop. A for loop can be used at a shell prompt or within a shell script itself. for loop syntax

Numeric ranges for syntax is as follows:

for VARIABLE in 1 2 3 4 5 .. N
do
	command1
	command2
	commandN
done
#!/bin/bash
 for i in 1 2 3
 do 
   echo "write something!"
   read line 
   echo "$i. $line"
done
for VARIABLE in file1 file2 file3
do
  command1 on $VARIABLE
  command2
  commandN
done
for OUTPUT in $(Linux-Or-Unix-Command-Here)
do
  command1 on $OUTPUT
  command2 on $OUTPUT
  ...
  commandN
done

Примери: This type of for loop is characterized by counting. The range is specified by a beginning (#1) and ending number (#5). The for loop executes a sequence of commands for each member in a list of items. A representative example in BASH is as follows to display welcome message 5 times with for loop:

#!/bin/bash
for i in 1 2 3 4 5
do
  echo "Welcome $i times"
done

Sometimes you may need to set a step value (allowing one to count by two's or to count backwards for instance). Latest bash version 3.0+ has inbuilt support for setting up ranges:

#!/bin/bash
for i in {1..5}
 do
 echo "Welcome $i times"
 done

Bash v4.0+ has inbuilt support for setting up a step value using {START..END..INCREMENT} syntax:

#!/bin/bash
echo "Bash version ${BASH_VERSION}..."
for i in {0..10..2}
 do
    echo "Welcome $i times"
 done

Sample outputs:

Bash version 4.0.33(0)-release...
Welcome 0 times
Welcome 2 times
Welcome 4 times
Welcome 6 times
Welcome 8 times
Welcome 10 times

Three-expression bash for loops syntax

This type of for loop share a common heritage with the C programming language. It is characterized by a three-parameter loop control expression; consisting of an initializer (EXP1), a loop-test or condition (EXP2), and a counting expression (EXP3).

for (( EXP1; EXP2; EXP3 ))
do
	command1
	command2
	command3
done

A representative three-expression example in bash as follows:

Три-условен for

 #!/bin/bash
 for (( c=1; c<=5; c++ ))
 do
   echo "Welcome $c times"
 done

//Sample output:

Welcome 1 times
Welcome 2 times
Welcome 3 times
Welcome 4 times
Welcome 5 times

Три-условен for с масив

#! /bin/bash
Unix[0]='Debian'
Unix[1]='Red hat'
Unix[2]='Ubuntu'
Unix[3]='Suse'
for ((i=0; i<4; i++))
do
  echo ${Unix[$i]}
done

//Резултат
Debian
Red hat
Ubuntu
Suse

Безкраен цикъл

#!/bin/bash
for (( ; ; ))
do
  echo "infinite loops [ hit CTRL+C to stop]"
done

Изход с break

You can do early exit with break statement inside the for loop. You can exit from within a FOR, WHILE or UNTIL loop using break. General break statement inside the for loop:

for I in 1 2 3 4 5
do
 statements1      #Executed for all values of I, up to a disaster-condition if any.
 statements2
 if (disaster-condition)
 then

break #Abandon the loop.

 fi
 statements3          #While good and, no disaster-condition.
done

Following shell script will go though all files stored in /etc directory. The for loop will be abandon when /etc/resolv.conf file found.

#!/bin/bash
for file in /etc/*
  do
  if [ "${file}" == "/etc/resolv.conf" ]
  then
    countNameservers=$(grep -c nameserver /etc/resolv.conf)
    echo "Total  ${countNameservers} nameservers defined in ${file}"
    break
  fi
done

Early continuation with continue statement. To resume the next iteration of the enclosing FOR, WHILE or UNTIL loop use continue statement.

for I in 1 2 3 4 5
do
 statements1      #Executed for all values of I, up to a disaster-condition if any.
 statements2
 if (condition)
 then

continue #Go to next iteration of I in the loop and skip statements3

 fi
 statements3
done


===Пример продължение This script make backup of all file names specified on command line. If .bak file exists, it will skip the cp command.

#!/bin/bash
FILES="$@"
for f in $FILES
do
# if .bak backup file exists, read next file
  if [ -f ${f}.bak ]
  then
    echo "Skiping $f file..."
    continue  # read next file and skip cp command
  fi
# we are hear means no backup file exists, just use cp command to copy file
 /bin/cp $f $f.bak
done

Масиви

#!/bin/bash

declare abc=()

for((i=0;i<100;i++))
do 
# echo "write something!"
# read line 

sleep 1
 ping 10.3.0.1  >/dev/null &
 abc+=($!)

 echo "Process: $i. s PID ${abc[$i]}"
 echo "start pinging"
done

sleep 5

for((i=0;i<100;i++))
do 
 sleep 1
 kill ${abc[$i]}
 echo "killed:  PID ${abc[$i]}"
 echo "start pinging"
done