Search
This page shows a basic information on how to create and execute a simple script in BASH. I suppose that you can also use Google and find a suitable tutorial according to your preferences. See also Q/A.
BASH script is a simple text file:
exec
#!/bin/bash
#!/usr/bin/env bash
#
echo “Hello world!”
.sh
stdin
cat
#!/usr/bin/env bash echo "Hello world!" #Set an int and string variables #Note that there must not be any spaces around '=' A=3 B="1 2 3" echo "The value of A is: ${A}" echo 'No substitution here: ${A}' # *** TODO(students): Modify the script to print the C and D variables C="1 2 3 ${B}" D='1 2 3 ${B}' #a simple condition: see 'man test'; IMPORTANT: watch carefully where the spaces are # ***TODO(students): go on and try to test a string (use ''='', ''-n'', etc.) if [ "$A" -eq 3 ] ;then echo "A is equal to 3" else echo "A is not equal to 3" fi #remember that '[' is an alias for the 'test' command. Actually, any command can be used if date ; then echo "You should see that the 'date' command has been executed within the 'if' condition" fi #and a very simple loop (over a list); IMPORTANT: watch carefully where the spaces are # *** TODO(students): Modify the loop using 'case' command and test a few possibilities, i.e.: 2, a, ... for i in 1 2 3 a b c; do echo "i=${i}" done
You might have noticed, that if there is a while loop after a pipe, it is not possible to return a value from the inside, i.e. a counter.
while
x=0 ls /dev | while read file ; do x=$((x+1)) done echo $x #prints '0' (!)
And this is not what we wanted. A solution is to use subshell and a list of commands1):
x=0 #needed to reset the var, it might have been reused when in a sub-loop x=$( ls /dev | { while read i ; do x=$((x+1)) done echo $x } ) echo "x=$x" #prints correct number of items
This is one of the possible solutions. You might also consider the getopts bash built-in (see man bash for more information).
getopts
man bash
#!/bin/bash # Description of the purpose of the script (TODO) # Usage info: $0 [OPTIONS] path (TODO) # OPTIONS: # -v/--verbose Be verbose # -c/--count NUM Numeric parameter example (limit) Default: 1 #Exit codes ERR_PARM=1 #Incorrect parameters ERR_PATH=2 #Incorrect path #Script control variables (remember to define the defaults) #1/0 specifies the verbose output VERBOSE=0 CNT=1 TARGET_PATH='.' if [ $# -eq 0 ] ; then echo "Specify at least one parameter" >&2 echo "Usage: $0 [OPTIONS] path" >&2 exit "${EXIT_PARM}" fi #Now we have at least one parameter, we will loop throug them and (and shift them) while [ -n "$1" ] ; do #if the first parameter is available, process it case "$1 " in "-h|--help" ) #print usage info and exit with exit code 0 #what about writing an usage() function? (TODO) ;; "-v|--verbose" ) VERBOSE=1 ;; "-c|--count" ) #here we have to test if "$2" is available and act accordingly (TODO) N="$2" shift #and we have to shift the parameters left ;; *) #This should be a path. However you need to test it. (TODO) TARGET_PATH="$1" esac #Shift all parameters to the left (discard the first one) shift done #And frome here below we should only use the defined variables as all the commandline params have been processed: # CNT # TARGET_PATH # VERBOSE if [ ${VERBOSE} -eq 1 ] ; then echo "Verbose debug output to stderr..." >&2 fi ...
There are two sockets available:
/dev/tcp/<host>/<port>
/dev/udp/<host>/<port>
You can use these, provided that port and host is a valid port number and hostname/IP respectively. An example follows:
port
host
HOST="www.ciirc.cvut.cz" PORT=80 #Open the socket using FD 3 filedescriptor exec 3<>"/dev/tcp/${HOST}/${PORT}" #Write HTTP request to FD 3 printf "GET / HTTP/1.0\r\n" >&3 printf "Accept: text/html, text/plain\r\n" >&3 printf "Accept-language: en\r\n" >&3 printf "\r\n" >&3 #Read response and print it #Cannot use the 'read' in the while condition, as it returns # exit code of 1 when EOF is reached, however the # line variable still might contain data # You can also simply use cat <&3 to just print the data to stdout while : ; do read -u 3 line exit_code=$? echo $line [ $exit_code -eq 0 ] || exit 0 done #Close FD 3 exec 3>&-