Basic Shell (Console) operation for beginners
Our character sets have more characters than our keyboards. Some of
these characters are very useful in presenting our posts and documents
more correctly or better formatted.
echo "¢ £ ¤ ¥ § © « ® ² ³ ¶ · ¹ º » ¼ ½ ¾ ÷ ø"
I called the script xtrachars
We can run the script, it will output to the screen, then select the
characters and click middle mouse button to paste them into our
document. To use for later copying and pasting.
I'm interested in finding some ambitious person to modify the script so
that it pipes the output to the clipboard. This way all we have to do is run
it and click middle mouse button, thus saving some extra work.
~
these characters are very useful in presenting our posts and documents
more correctly or better formatted.
echo "¢ £ ¤ ¥ § © « ® ² ³ ¶ · ¹ º » ¼ ½ ¾ ÷ ø"
I called the script xtrachars
We can run the script, it will output to the screen, then select the
characters and click middle mouse button to paste them into our
document. To use for later copying and pasting.
I'm interested in finding some ambitious person to modify the script so
that it pipes the output to the clipboard. This way all we have to do is run
it and click middle mouse button, thus saving some extra work.
~
Introducing more fun stuff
» while loop
» integer math using the echo command
» x instead of quotes, explained
The variable cnt has not been initialized prior to the
start of the loop. This means the loop will run at least one time.
It also means the variable cnt doesn't exist at all
when the loop starts.
In previous examples I used quotes
[ "$cnt" != "20" ]
The reason for the quotes was to have something there which is equal on
both sides of our comparison. We are comparing the value in $cnt with
the value 20
In this example I used x in place of quotes for exactly the same reason, I
used quotes. Note: it is easier to type one lowercase x than two " "
[ x$cnt != x20 ]
What if I didn't use "" or x or something?
Considering that $cnt doesn't exist at the beginning of the loop our test
would look like this:
[ != 20 ]
!= is a comparison operator and there is nothing to compare to. Bash will
see the error, complain and quit.
[ x$cnt != x20 ] is actually [ x != x20 ] , we have something for Bash to
compare and that's all it wants.
This is why we use x's , quotes or something of your choice in these test
statements.
Now you know the echo command can also perform integer math. And the
example shows how it can be done. There are a variety of ways to do
math in our scripts. All in due time.
~
» while loop
» integer math using the echo command
» x instead of quotes, explained
Code: Select all
#!/bin/bash
# Count by two until we reach 20, then quit
# A trivial program
while [ x$cnt != x20 ] ; do
cnt=`echo $((cnt + 2))`
echo $cnt
done
start of the loop. This means the loop will run at least one time.
It also means the variable cnt doesn't exist at all
when the loop starts.
In previous examples I used quotes
[ "$cnt" != "20" ]
The reason for the quotes was to have something there which is equal on
both sides of our comparison. We are comparing the value in $cnt with
the value 20
In this example I used x in place of quotes for exactly the same reason, I
used quotes. Note: it is easier to type one lowercase x than two " "
[ x$cnt != x20 ]
What if I didn't use "" or x or something?
Considering that $cnt doesn't exist at the beginning of the loop our test
would look like this:
[ != 20 ]
!= is a comparison operator and there is nothing to compare to. Bash will
see the error, complain and quit.
[ x$cnt != x20 ] is actually [ x != x20 ] , we have something for Bash to
compare and that's all it wants.
This is why we use x's , quotes or something of your choice in these test
statements.
Now you know the echo command can also perform integer math. And the
example shows how it can be done. There are a variety of ways to do
math in our scripts. All in due time.
~
Introducing the time saving 'printf' statement
For this post, I took a very small snippet of xine -help output.
It has indents to maintain and characters which would throw echo off, if echo were not properly quoted.
Typically bash programmers use the echo command for on screen display.
But when you have a lot of text to display there is a much easier way.
First example: echo command on each line with quotes on non empty
lines. The echo and its quotes do not display on the output.
Second example using the bash printf statement. It requires one quote
at the beginning and one quote at the end. The formatting is maintained.
The printf and the two quotes do not display on the output.
~
For this post, I took a very small snippet of xine -help output.
It has indents to maintain and characters which would throw echo off, if echo were not properly quoted.
Typically bash programmers use the echo command for on screen display.
But when you have a lot of text to display there is a much easier way.
First example: echo command on each line with quotes on non empty
lines. The echo and its quotes do not display on the output.
Code: Select all
echo "Usage: xine [OPTIONS]... [MRL]"
echo
echo "OPTIONS are:"
echo " -v, --version Display version."
echo " --verbose [=level] Set verbosity level. Default is 1."
echo " -c, --config <file> Use config file instead of default one."
echo " -V, --video-driver <drv> Select video driver by id. Available drivers:"
echo " dxr3 aadxr3 xv SyncFB opengl raw xshm aa caca"
echo " -A, --audio-driver <drv> Select audio driver by id. Available drivers:"
echo " null alsa oss esd file none"
echo " -u, --spu-channel <#> Select SPU (subtitle) channel '#'."
echo " -a, --audio-channel <#> Select audio channel '#'."
echo " -p, --auto-play [opt] Play on start. Can be followed by:"
echo " 'f': in fullscreen mode."
echo " 'h': hide GUI (panel, etc.)."
echo " 'w': hide video window."
echo " 'q': quit when play is done."
echo " 'd': retrieve playlist from DVD. (deprecated. use -s DVD)"
echo " 'v': retrieve playlist from VCD. (deprecated. use -s VCD)"
echo " 'F': in xinerama fullscreen mode."
at the beginning and one quote at the end. The formatting is maintained.
The printf and the two quotes do not display on the output.
Code: Select all
printf "
Usage: xine [OPTIONS]... [MRL]
OPTIONS are:
-v, --version Display version.
--verbose [=level] Set verbosity level. Default is 1.
-c, --config <file> Use config file instead of default one.
-V, --video-driver <drv> Select video driver by id. Available drivers:
dxr3 aadxr3 xv SyncFB opengl raw xshm aa caca
-A, --audio-driver <drv> Select audio driver by id. Available drivers:
null alsa oss esd file none
-u, --spu-channel <#> Select SPU (subtitle) channel '#'.
-a, --audio-channel <#> Select audio channel '#'.
-p, --auto-play [opt] Play on start. Can be followed by:
'f': in fullscreen mode.
'h': hide GUI (panel, etc.).
'w': hide video window.
'q': quit when play is done.
'd': retrieve playlist from DVD. (deprecated. use -s DVD)
'v': retrieve playlist from VCD. (deprecated. use -s VCD)
'F': in xinerama fullscreen mode.
-s, --auto-scan <plugin> auto-scan play list from <plugin>
-f, --fullscreen start in fullscreen mode,
-F, --xineramafull start in xinerama fullscreen (display on several screens),
"
Bruce B wrote:I tried the time command and couldn't figure out how to apply to the
script. Some examples please?
Code: Select all
#!/bin/bash
date
function million {
for ((i=1;i<999999;i++));do
:
done
}
time million
echo
date
Jpeps,
Thanks for coming to the rescue. I'll call suicide prevention and tell them
it was just a false alarm.
Have you ever worked with other programmers in a community?
I haven't.
Would you like to do a fairly small group project, here online?
If so, would you be willing to be the benevolent dictator?
Let me know, if you are interested. If so I'll define the project I have in
mind, if you don't like the project, you can change your mind.
Bruce
~
Thanks for coming to the rescue. I'll call suicide prevention and tell them
it was just a false alarm.
Have you ever worked with other programmers in a community?
I haven't.
Would you like to do a fairly small group project, here online?
If so, would you be willing to be the benevolent dictator?
Let me know, if you are interested. If so I'll define the project I have in
mind, if you don't like the project, you can change your mind.
Bruce
~
Introducing the 'case' statement
Earlier, I introduced the if statement with the elif and else
In order to avoid too many elif's, programmers often choose the case
statement when it will work by using words. It is clean and easy to work
with.
I'll show you an example of our earlier if,elif,else structure compared with
the case structure. You will be able to see the difference. Both structures
do the same thing.
In some instances, the case statement would be the better choice.
Until you memorize things it is often wise to copy and paste an example
to a file in your scripts directory.
Suppose we name this file case-example. You can name it how you
want. You could have a file with examples and named such. In a way the
naming doesn't matter because you can grep all your scripts by keyword.
Remember case terminates with case spelled backward, esac.
# grep esac * will find the file with the case example.
~
Earlier, I introduced the if statement with the elif and else
In order to avoid too many elif's, programmers often choose the case
statement when it will work by using words. It is clean and easy to work
with.
I'll show you an example of our earlier if,elif,else structure compared with
the case structure. You will be able to see the difference. Both structures
do the same thing.
Code: Select all
if [ "$clr" = "red" ] ; then
echo " You entered a valid primary color \"$clr\""
elif [ "$clr" = "green" ] ; then
echo " You entered a valid primary color \"$clr\""
elif [ "$clr" = "blue" ] ; then
echo " You entered a valid primary color \"$clr\""
elif [ "$clr" = "yellow" ] ; then
echo " You entered a primary color used in painting \"$clr\""
else
echo " \"$clr\" is not known to the program as a primary color"
echo " We use red, green, and blue as primary colors"
fi
Code: Select all
case $clr in
red) echo " You entered a valid primary color \"$clr\"" ;;
green) echo " You entered a valid primary color \"$clr\"" ;;
blue) echo " You entered a valid primary color \"$clr\"" ;;
yellow) echo " You entered a primary color used in painting \"$clr\"" ;;
*) echo " \"$clr\" is not known to the program as a primary color"
echo " We use red, green, and blue as primary colors" ;;
esac
Until you memorize things it is often wise to copy and paste an example
to a file in your scripts directory.
Suppose we name this file case-example. You can name it how you
want. You could have a file with examples and named such. In a way the
naming doesn't matter because you can grep all your scripts by keyword.
Remember case terminates with case spelled backward, esac.
# grep esac * will find the file with the case example.
~
An Intrusion Prevention Script
Notes:
~
Notes:
- » logs date and time of each attempt
» would take a good Linux user to work around
» shuts machine down on first bad access attempt
» then all subsequent attempts to enter system
» traps Ctrl+C and other methods to defeat
» put script in /etc/profile.local
» script is partially tested and looks good
» user can refine
» ask if you have questions about it
» displays message -- Unauthorized Access Attempt --
» subsequent messages -- System has been compromised, shutting down now --
Code: Select all
#!/bin/bash
KEYWORD=foobar
SAFEFILE=/var/log/safe~
trap caught 1 2 3 4 5 6
function std() {
echo -en "\033[0m"
}
function bred() {
echo -en "\033[31;1m"
}
function caught() {
echo date >>$SAFEFILE # remove this echo
bred
echo "-- System has been compromised, shutting down now --"
std
echo poweroff # remove this echo
}
if [ -f $SAFEFILE ] ; then
echo date >>$SAFEFILE # remove this echo
bred
echo "-- System has been compromised, shutting down now --"
std
echo poweroff # remove this echo
fi
echo -n "Login: "
read a
if [ x$a != x$KEYWORD ] ; then
echo date >>$SAFEFILE # remove this echo
bred
echo -- Unauthorized Access Attempt --
std
echo poweroff # remove this echo
fi
~
Example of using time to time a funtion:
On my ancient machine I get this output:
real 1m1.969s
user 0m54.140s
sys 0m1.010s
Another example:
time ls -lR /
Code: Select all
#!/bin/bash
function million {
for ((i=1;i<999999;i++));do
:
done
}
time million
real 1m1.969s
user 0m54.140s
sys 0m1.010s
Another example:
time ls -lR /
- Moose On The Loose
- Posts: 965
- Joined: Thu 24 Feb 2011, 14:54
Another point is that the "$A" construct keeps any spaces that may happen to be in ABruce B wrote:Introducing more fun stuff
In this example I used x in place of quotes for exactly the same reason, I
used quotes. Note: it is easier to type one lowercase x than two " "
[ x$cnt != x20 ]
What if I didn't use "" or x or something?
~
Code: Select all
# A="Hi "
# echo $A c
Hi c
# echo "$A" c
Hi c
#
[ "x$cnt" != x20 ] works just as well. the thing is that with 'sh' (only single-brackets supported), the first value cannot be null. the other way to avoid that is to reverse the values -but it reads really weird:
[ 20 != "$cnt" ]
If you are writing for bash, use double brackets and then the first value can be null and no errors result:
[[ "$cnt" != 20 ]]
[ 20 != "$cnt" ]
If you are writing for bash, use double brackets and then the first value can be null and no errors result:
[[ "$cnt" != 20 ]]
Might as well store colors in a separate file:Bruce B wrote:An Intrusion Prevention Script
save "colors" in $PATH
Code: Select all
#!/bin/sh
### example: echo -e $RED"Hello"
## Black background
export RED='\E[31;40m'
export WHITE='\E[37;40m'
export GREEN='\E[32;40m'
export YELLOW='\E[33;40m'
export MAGENTA='\E[35;40m'
export CYAN='\E[36;40m'
export BLACK='\E[30;40m'
## White background
# export RED='\E[31;47m'
# export WHITE='\E[37;47m'
# export GREEN='\E[32;47m'
# export YELLOW='\E[33;47m'
# export MAGENTA='\E[35;47m'
# export CYAN='\E[36;47m'
# export BLACK='\E[30;47m'
Code: Select all
#!/bin/bash
. colors
KEYWORD=foobar
SAFEFILE=/var/log/safe~
trap caught 1 2 3 4 5 6
function caught() {
echo date >>$SAFEFILE # remove this echo
echo -e $RED"-- System has been compromised, shutting down now --"
echo -e $WHITE"poweroff" # remove this echo
}
if [ -f $SAFEFILE ] ; then
echo date >>$SAFEFILE # remove this echo
echo -e $RED"-- System has been compromised, shutting down now --"
echo -e $WHITE"poweroff" # remove this echo
fi
echo -n "Login: "
read a
if [ x$a != x$KEYWORD ] ; then
echo date >>$SAFEFILE # remove this echo
echo -e $RED"-- Unauthorized Access Attempt --"
echo -e $WHITE"poweroff" # remove this echo
fi
Only a problem for variables without quotes:amigo wrote:[ "x$cnt" != x20 ] works just as well. the thing is that with 'sh' (only single-brackets supported), the first value cannot be null. the other way to avoid that is to reverse the values -but it reads really weird:
[ 20 != "$cnt" ]
If you are writing for bash, use double brackets and then the first value can be null and no errors result:
[[ "$cnt" != 20 ]]
Code: Select all
#!/bin/bash
echo "with quotes:"
[ "$VAR" != "2" ] && echo "no error"
echo -e "\nwithout quotes:"
[ $VAR != "2" ] && echo "no error"
What I meant was to save the script as "colors" and put it somewhere in your PATH so that you can reference it. (e.g, /usr/local/bin:/root/my-applications/bin...)PupGeek wrote:jpeps wrote:
Might as well store colors in a separate file:
save "colors" in $PATH
cool idea jpeps, but aren't we really defining each color in the environment and not saving them to the $PATH variable?
- Moose On The Loose
- Posts: 965
- Joined: Thu 24 Feb 2011, 14:54
Another useful trick for making the help message is the here-document
The "aaa" in the example could be any string
Code: Select all
# (cat - | more) <<aaa
> hi there
> how are you
> aaa
hi there
how are you
#
Actually it's not redundant. As long as you're using the bash shell, you don't need to add ". colors" to scripts, and can use colors right on the terminal.PupGeek wrote:I know it seems a bit redundant on the surface, but it provides color formatting while keeping the bashrc file nice and neat by defining the variables externally.
Code: Select all
[ -f /tmp/log ] || echo -e $RED"error"
Planning Your Program
Carefully plan what you want your program to do. The coding is partially
complete while planning, because a portion of your mind is already
working out how to do it. You will be more relaxed when coding. You will
know when you are done. You will know if you left something out.
You can give your plans to any coder and have someone else do the
coding and get the same end result.
When done, you can add your plan as comments. Anyone in the future
will understand the program's purpose and specifications.
Wanted an alarm clock
My situation
I sleep listening to music. If a quiet alarm goes off, I may not hear it. If
an alarm goes off, which is easy to turn off, I might turn it off and fall
back asleep.
Specs
» usage example: alarm 8 (for eight hours)
» is shell script that runs in background
» plays a sound file even if xmms or mp3blaster is in use
» (I can adjust the gain in the sound file to make it loud)
» play either mp3 or wav alarm file
» cli player: wavplay or mpg123 or?
» continuous playback until turned off
» name of player set by variable
» name of sound file set by variable
» hard to turn off, maybe type in the name of a script to turn it off
» (making it hard, forces me into an awake state to turn it off)
» uses very little CPU while running
» only needs to be accurate to within a minute or two
~
Carefully plan what you want your program to do. The coding is partially
complete while planning, because a portion of your mind is already
working out how to do it. You will be more relaxed when coding. You will
know when you are done. You will know if you left something out.
You can give your plans to any coder and have someone else do the
coding and get the same end result.
When done, you can add your plan as comments. Anyone in the future
will understand the program's purpose and specifications.
Wanted an alarm clock
My situation
I sleep listening to music. If a quiet alarm goes off, I may not hear it. If
an alarm goes off, which is easy to turn off, I might turn it off and fall
back asleep.
Specs
» usage example: alarm 8 (for eight hours)
» is shell script that runs in background
» plays a sound file even if xmms or mp3blaster is in use
» (I can adjust the gain in the sound file to make it loud)
» play either mp3 or wav alarm file
» cli player: wavplay or mpg123 or?
» continuous playback until turned off
» name of player set by variable
» name of sound file set by variable
» hard to turn off, maybe type in the name of a script to turn it off
» (making it hard, forces me into an awake state to turn it off)
» uses very little CPU while running
» only needs to be accurate to within a minute or two
~