Get Smart Season 2
Get your copy at alibris.com
( 4.7/5.0 ★ | 496 downloads )
-- Click the link to download --
https://click.linksynergy.com/link?id=*C/UgjGtUZ8&offerid=1494105.26
530883929061501&type=15&murl=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Fwww.alibris.com%2Fsearch%2
Fbooks%2Fisbn%2F0883929061501
Get Smart Season 2
ISBN: 0883929061501
Category: Media > DVDs & Movies
File Fomat: PDF, EPUB, DOC...
File Details: 4.1 MB
Language: English
Website: alibris.com
Short description: Very Good. USED.
DOWNLOAD: https://click.linksynergy.com/link?id=*C/UgjGtUZ8&
offerid=1494105.26530883929061501&type=15&murl=http%3A%2F%2F
www.alibris.com%2Fsearch%2Fbooks%2Fisbn%2F0883929061501
Get Smart Season 2
• Click the link: https://click.linksynergy.com/link?id=*C/UgjGtUZ8&offerid=1494105.2653088392906150
1&type=15&murl=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Fwww.alibris.com%2Fsearch%2Fbooks%2Fisbn%2F0883929061501 to do
latest version of Get Smart Season 2 in multiple formats such as PDF, EPUB, and more.
• Don’t miss the chance to explore our extensive collection of high-quality resources, books, and guides on
our website. Visit us regularly to stay updated with new titles and gain access to even more valuable
materials.
.
arguments and/or options. Especially suitable for this are tr and
grep.
# From "wstrings.sh" example.
wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \
tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '`
Example 36-21. Fun with anagrams
#!/bin/bash
# agram.sh: Playing games with anagrams.
# Find anagrams of...
LETTERSET=etaoinshrdlu
FILTER='.......' # How many letters minimum?
# 1234567
anagram "$LETTERSET" | # Find all anagrams of the
letterset...
grep "$FILTER" | # With at least 7 letters,
grep '^is' | # starting with 'is'
grep -v 's$' | # no plurals
grep -v 'ed$' # no past tense verbs
# Possible to add many combinations of conditions and
filters.
# Uses "anagram" utility
#+ that is part of the author's "yawl" word list
package.
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
# http://bash.deta.in/yawl-0.3.2.tar.gz
exit 0 # End of code.
bash$ sh agram.sh
islander
isolate
isolead
isotheral
# Exercises:
# ---------
# Modify this script to take the LETTERSET as a
command-line parameter.
# Parameterize the filters in lines 11 - 13 (as with
$FILTER),
#+ so that they can be specified by passing arguments to
a function.
# For a slightly different approach to anagramming,
#+ see the agram2.sh script.
See also Example 29-4, Example 16-25, and Example A-9.
Use "anonymous here documents" to comment out blocks of code,
to save having to individually comment out each line with a #. See
Example 19-11.
Running a script on a machine that relies on a command that might
not be installed is dangerous. Use whatis to avoid potential
problems with this.
CMD=command1 # First choice.
PlanB=command2 # Fallback option.
command_test=$(whatis "$CMD" | grep 'nothing
appropriate')
# If 'command1' not found on system , 'whatis' will
return
#+ "command1: nothing appropriate."
#
# A safer alternative is:
# command_test=$(whereis "$CMD" | grep \/)
# But then the sense of the following test would have
to be reversed,
#+ since the $command_test variable holds content only
if
#+ the $CMD exists on the system.
# (Thanks, bojster.)
if [[ -z "$command_test" ]] # Check whether command
present.
then
$CMD option1 option2 # Run command1 with
options.
else # Otherwise,
$PlanB #+ run command2.
fi
An if-grep test may not return expected results in an error case,
when text is output to stderr, rather that stdout.
if ls -l nonexistent_filename | grep -q 'No such file or
directory'
then echo "File \"nonexistent_filename\" does not
exist."
fi
Redirecting stderr to stdout fixes this.
if ls -l nonexistent_filename 2>&1 | grep -q 'No such
file or directory'
# ^^^^
then echo "File \"nonexistent_filename\" does not
exist."
fi
# Thanks, Chris Martin, for pointing this out.
If you absolutely must access a subshell variable outside the
subshell, here's a way to do it.
TMPFILE=tmpfile # Create a temp file to
store the variable.
( # Inside the subshell ...
inner_variable=Inner
echo $inner_variable
echo $inner_variable >>$TMPFILE # Append to temp file.
)
# Outside the subshell ...
echo; echo "-----"; echo
echo $inner_variable # Null, as expected.
echo "-----"; echo
# Now ...
read inner_variable <$TMPFILE # Read back shell
variable.
rm -f "$TMPFILE" # Get rid of temp file.
echo "$inner_variable" # It's an ugly kludge,
but it works.
The run-parts command is handy for running a set of command
scripts in a particular sequence, especially in combination with cron
or at.
For doing multiple revisions on a complex script, use the rcs
Revision Control System package.
Among other benefits of this is automatically updated ID header
tags. The co command in rcs does a parameter replacement of
certain reserved key words, for example, replacing # $Id$ in a script
with something like:
# $Id: hello-world.sh,v 1.1 2004/10/16 02:43:05 bozo Exp
$
36.7.2. Widgets
It would be nice to be able to invoke X-Windows widgets from a
shell script. There happen to exist several packages that purport to
do so, namely Xscript, Xmenu, and widtools. The first two of these
no longer seem to be maintained. Fortunately, it is still possible to
obtain widtools here.
The widtools (widget tools) package requires the XForms library
to be installed. Additionally, the Makefile needs some judicious
editing before the package will build on a typical Linux system.
Finally, three of the six widgets offered do not work (and, in
fact, segfault).
The dialog family of tools offers a method of calling "dialog" widgets
from a shell script. The original dialog utility works in a text console,
but its successors, gdialog, Xdialog, and kdialog use X-Windows-
based widget sets.
Example 36-22. Widgets invoked from a shell script
#!/bin/bash
# dialog.sh: Using 'gdialog' widgets.
# Must have 'gdialog' installed on your system to run this
script.
# Or, you can replace all instance of 'gdialog' below with
'kdialog' ...
# Version 1.1 (corrected 04/05/05)
# This script was inspired by the following article.
# "Scripting for X Productivity," by Marco Fioretti,
# LINUX JOURNAL, Issue 113, September 2003, pp. 86-9.
# Thank you, all you good people at LJ.
# Input error in dialog box.
E_INPUT=85
# Dimensions of display, input widgets.
HEIGHT=50
WIDTH=60
# Output file name (constructed out of script name).
OUTFILE=$0.output
# Display this script in a text widget.
gdialog --title "Displaying: $0" --textbox $0 $HEIGHT $WIDTH
# Now, we'll try saving input in a file.
echo -n "VARIABLE=" > $OUTFILE
gdialog --title "User Input" --inputbox "Enter variable,
please:" \
$HEIGHT $WIDTH 2>> $OUTFILE
if [ "$?" -eq 0 ]
# It's good practice to check exit status.
then
echo "Executed \"dialog box\" without errors."
else
echo "Error(s) in \"dialog box\" execution."
# Or, clicked on "Cancel", instead of "OK" button.
rm $OUTFILE
exit $E_INPUT
fi
# Now, we'll retrieve and display the saved variable.
. $OUTFILE # 'Source' the saved file.
echo "The variable input in the \"input box\" was:
"$VARIABLE""
rm $OUTFILE # Clean up by removing the temp file.
# Some applications may need to retain this file.
exit $?
# Exercise: Rewrite this script using the 'zenity' widget set.
The xmessage command is a simple method of popping up a
message/query window. For example:
xmessage Fatal error in script! -button exit
The latest entry in the widget sweepstakes is zenity. This utility pops
up GTK+ dialog widgets-and-windows, and it works very nicely
within a script.
get_info ()
{
zenity --entry # Pops up query window . . .
#+ and prints user entry to stdout.
# Also try the --calendar and --scale
options.
}
answer=$( get_info ) # Capture stdout in $answer variable.
echo "User entered: "$answer""
For other methods of scripting with widgets, try Tk or wish (Tcl
derivatives), PerlTk (Perl with Tk extensions), tksh (ksh with Tk
extensions), XForms4Perl (Perl with XForms extensions), Gtk-Perl
(Perl with Gtk extensions), or PyQt (Python with Qt extensions).
36.8. Security Issues
36.8.1. Infected Shell Scripts
A brief warning about script security is indicated. A shell script may
contain a worm, trojan, or even a virus. For that reason, never run
as root a script (or permit it to be inserted into the system startup
scripts in /etc/rc.d) unless you have obtained said script from a
trusted source or you have carefully analyzed it to make certain it
does nothing harmful.
Various researchers at Bell Labs and other sites, including M.
Douglas McIlroy, Tom Duff, and Fred Cohen have investigated the
implications of shell script viruses. They conclude that it is all too
easy for even a novice, a "script kiddie," to write one. [128]
Here is yet another reason to learn scripting. Being able to look at
and understand scripts may protect your system from being
compromised by a rogue script.
36.8.2. Hiding Shell Script Source
For security purposes, it may be necessary to render a script
unreadable. If only there were a utility to create a stripped binary
executable from a script. Francisco Rosales' shc -- generic shell script
compiler does exactly that.
Unfortunately, according to an article in the October, 2005 Linux
Journal, the binary can, in at least some cases, be decrypted to
recover the original script source. Still, this could be a useful method
of keeping scripts secure from all but the most skilled hackers.
36.8.3. Writing Secure Shell Scripts
Dan Stromberg suggests the following guidelines for writing
(relatively) secure shell scripts.
Don't put secret data in environment variables.
Don't pass secret data in an external command's arguments
(pass them in via a pipe or redirection instead).
Set your $PATH carefully. Don't just trust whatever path you
inherit from the caller if your script is running as root. In fact,
whenever you use an environment variable inherited from the
caller, think about what could happen if the caller put something
misleading in the variable, e.g., if the caller set $HOME to /etc.
36.9. Portability Issues
It is easier to port a shell than a
shell script.
--Larry Wall
This book deals specifically with Bash scripting on a GNU/Linux
system. All the same, users of sh and ksh will find much of value
here.
As it happens, many of the various shells and scripting languages
seem to be converging toward the POSIX 1003.2 standard. Invoking
Bash with the --posix option or inserting a set -o posix at the head
of a script causes Bash to conform very closely to this standard.
Another alternative is to use a #!/bin/sh sha-bang header in the
script, rather than #!/bin/bash. [129] Note that /bin/sh is a link to
/bin/bash in Linux and certain other flavors of UNIX, and a script
invoked this way disables extended Bash functionality.
Most Bash scripts will run as-is under ksh, and vice-versa, since
Chet Ramey has been busily porting ksh features to the latest
versions of Bash.
On a commercial UNIX machine, scripts using GNU-specific features
of standard commands may not work. This has become less of a
problem in the last few years, as the GNU utilities have pretty much
displaced their proprietary counterparts even on "big-iron" UNIX.
Caldera's release of the source to many of the original UNIX utilities
has accelerated the trend.
Bash has certain features that the traditional Bourne shell lacks.
Among these are:
Certain extended invocation options
Command substitution using $( ) notation
Brace expansion
Certain array operations, and associative arrays
The double brackets extended test construct
The double-parentheses arithmetic-evaluation construct
Certain string manipulation operations
Process substitution
A Regular Expression matching operator
Bash-specific builtins
Coprocesses
See the Bash F.A.Q. for a complete listing.
36.9.1. A Test Suite
Let us illustrate some of the incompatibilities between Bash and the
classic Bourne shell. Download and install the "Heirloom Bourne
Shell" and run the following script, first using Bash, then the classic
sh.
Example 36-23. Test Suite
#!/bin/bash
# test-suite.sh
# A partial Bash compatibility test suite.
# Run this on your version of Bash, or some other shell.
default_option=FAIL # Tests below will fail unless . .
.
echo
echo -n "Testing "
sleep 1; echo -n ". "
sleep 1; echo -n ". "
sleep 1; echo ". "
echo
# Double brackets
String="Double brackets supported?"
echo -n "Double brackets test: "
if [[ "$String" = "Double brackets supported?" ]]
then
echo "PASS"
else
echo "FAIL"
fi
# Double brackets and regex matching
String="Regex matching supported?"
echo -n "Regex matching: "
if [[ "$String" =~ R.....matching* ]]
then
echo "PASS"
else
echo "FAIL"
fi
# Arrays
test_arr=$default_option # FAIL
Array=( If supports arrays will print PASS )
test_arr=${Array[5]}
echo "Array test: $test_arr"
# Command Substitution
csub_test ()
{
echo "PASS"
}
test_csub=$default_option # FAIL
test_csub=$(csub_test)
echo "Command substitution test: $test_csub"
echo
# Completing this script is an exercise for the reader.
# Add to the above similar tests for double parentheses,
#+ brace expansion, process substitution, etc.
exit $?
36.10. Shell Scripting Under
Windows
Even users running that other OS can run UNIX-like shell scripts, and
therefore benefit from many of the lessons of this book. The Cygwin
package from Cygnus and the MKS utilities from Mortice Kern
Associates add shell scripting capabilities to Windows.
Another alternative is UWIN, written by David Korn of AT&T, of Korn
Shell fame.
In 2006, Microsoft released the Windows Powershell®, which
contains limited Bash-like command-line scripting capabilities.
Chapter 37. Bash, versions 2,
3, and 4
37.1. Bash, version 2
The current version of Bash, the one you have running on your
machine, is most likely version 2.xx.yy, 3.xx.yy, or 4.xx.yy.
bash$ echo $BASH_VERSION
3.2.25(1)-release
The version 2 update of the classic Bash scripting language added
array variables, string and parameter expansion, and a better
method of indirect variable references, among other features.
Example 37-1. String expansion
#!/bin/bash
# String expansion.
# Introduced with version 2 of Bash.
# Strings of the form $'xxx'
#+ have the standard escaped characters interpreted.
echo $'Ringing bell 3 times \a \a \a'
# May only ring once with certain terminals.
# Or ...
# May not ring at all, depending on terminal settings.
echo $'Three form feeds \f \f \f'
echo $'10 newlines \n\n\n\n\n\n\n\n\n\n'
echo $'\102\141\163\150'
# B a s h
# Octal equivalent of characters.
exit
Example 37-2. Indirect variable references - the new way
#!/bin/bash
# Indirect variable referencing.
# This has a few of the attributes of references in C++.
a=letter_of_alphabet
letter_of_alphabet=z
echo "a = $a" # Direct reference.
echo "Now a = ${!a}" # Indirect reference.
# The ${!variable} notation is more intuitive than the old
#+ eval var1=\$$var2
echo
t=table_cell_3
table_cell_3=24
echo "t = ${!t}" # t = 24
table_cell_3=387
echo "Value of t changed to ${!t}" # 387
# No 'eval' necessary.
# This is useful for referencing members of an array or
table,
#+ or for simulating a multi-dimensional array.
# An indexing option (analogous to pointer arithmetic)
#+ would have been nice. Sigh.
exit 0
# See also, ind-ref.sh example.
Example 37-3. Simple database application, using indirect
variable referencing
#!/bin/bash
# resistor-inventory.sh
# Simple database / table-lookup application.
#
==============================================================
#
# Data
B1723_value=470 # Ohms
B1723_powerdissip=.25 # Watts
B1723_colorcode="yellow-violet-brown" # Color
bands
B1723_loc=173 # Where they
are
B1723_inventory=78 # How many
B1724_value=1000
B1724_powerdissip=.25
B1724_colorcode="brown-black-red"
B1724_loc=24N
B1724_inventory=243
B1725_value=10000
B1725_powerdissip=.125
B1725_colorcode="brown-black-orange"
B1725_loc=24N
B1725_inventory=89
#
==============================================================
#
echo
PS3='Enter catalog number: '
echo
select catalog_number in "B1723" "B1724" "B1725"
do
Inv=${catalog_number}_inventory
Val=${catalog_number}_value
Pdissip=${catalog_number}_powerdissip
Loc=${catalog_number}_loc
Ccode=${catalog_number}_colorcode
echo
echo "Catalog number $catalog_number:"
# Now, retrieve value, using indirect referencing.
echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip}
watt]\
resistors in stock." # ^ ^
# As of Bash 4.2, you can replace "ohm" with \u2126 (using
echo -e).
echo "These are located in bin # ${!Loc}."
echo "Their color code is \"${!Ccode}\"."
break
done
echo; echo
# Exercises:
# ---------
# 1) Rewrite this script to read its data from an external
file.
# 2) Rewrite this script to use arrays,
#+ rather than indirect variable referencing.
# Which method is more straightforward and intuitive?
# Which method is easier to code?
# Notes:
# -----
# Shell scripts are inappropriate for anything except the
most simple
#+ database applications, and even then it involves
workarounds and kludges.
# Much better is to use a language with native support for
data structures,
#+ such as C++ or Java (or even Perl).
exit 0
Example 37-4. Using arrays and other miscellaneous trickery
to deal four random hands from a deck of cards
#!/bin/bash
# cards.sh
# Deals four random hands from a deck of cards.
UNPICKED=0
PICKED=1
DUPE_CARD=99
LOWER_LIMIT=0
UPPER_LIMIT=51
CARDS_IN_SUIT=13
CARDS=52
declare -a Deck
declare -a Suits
declare -a Cards
# It would have been easier to implement and more intuitive
#+ with a single, 3-dimensional array.
# Perhaps a future version of Bash will support
multidimensional arrays.
initialize_Deck ()
{
i=$LOWER_LIMIT
until [ "$i" -gt $UPPER_LIMIT ]
do
Deck[i]=$UNPICKED # Set each card of "Deck" as unpicked.
let "i += 1"
done
echo
}
initialize_Suits ()
{
Suits[0]=C #Clubs
Suits[1]=D #Diamonds
Suits[2]=H #Hearts
Suits[3]=S #Spades
}
initialize_Cards ()
{
Cards=(2 3 4 5 6 7 8 9 10 J Q K A)
# Alternate method of initializing an array.
}
pick_a_card ()
{
card_number=$RANDOM
let "card_number %= $CARDS" # Restrict range to 0 - 51, i.e.,
52 cards.
if [ "${Deck[card_number]}" -eq $UNPICKED ]
then
Deck[card_number]=$PICKED
return $card_number
else
return $DUPE_CARD
fi
}
parse_card ()
{
number=$1
let "suit_number = number / CARDS_IN_SUIT"
suit=${Suits[suit_number]}
echo -n "$suit-"
let "card_no = number % CARDS_IN_SUIT"
Card=${Cards[card_no]}
printf %-4s $Card
# Print cards in neat columns.
}
seed_random () # Seed random number generator.
{ # What happens if you don't do this?
seed=`eval date +%s`
let "seed %= 32766"
RANDOM=$seed
} # Consider other methods of seeding the random number
generator.
deal_cards ()
{
echo
cards_picked=0
while [ "$cards_picked" -le $UPPER_LIMIT ]
do
pick_a_card
t=$?
if [ "$t" -ne $DUPE_CARD ]
then
parse_card $t
u=$cards_picked+1
# Change back to 1-based indexing, temporarily. Why?
let "u %= $CARDS_IN_SUIT"
if [ "$u" -eq 0 ] # Nested if/then condition test.
then
echo
echo
fi # Each hand set apart with a blank
line.
let "cards_picked += 1"
fi
done
echo
return 0
}
# Structured programming:
# Entire program logic modularized in functions.
#===============
seed_random
initialize_Deck
initialize_Suits
initialize_Cards
deal_cards
#===============
exit
# Exercise 1:
# Add comments to thoroughly document this script.
# Exercise 2:
# Add a routine (function) to print out each hand sorted in
suits.
# You may add other bells and whistles if you like.
# Exercise 3:
# Simplify and streamline the logic of the script.
37.2. Bash, version 3
On July 27, 2004, Chet Ramey released version 3 of Bash. This
update fixed quite a number of bugs and added new features.
Some of the more important added features:
A new, more generalized {a..z} brace expansion operator.
#!/bin/bash
for i in {1..10}
# Simpler and more straightforward than
#+ for i in $(seq 10)
do
echo -n "$i "
done
echo
# 1 2 3 4 5 6 7 8 9 10
# Or just . . .
echo {a..z} # a b c d e f g h i j k l m n o p q
r s t u v w x y z
echo {e..m} # e f g h i j k l m
echo {z..a} # z y x w v u t s r q p o n m l k j
i h g f e d c b a
# Works backwards, too.
echo {25..30} # 25 26 27 28 29 30
echo {3..-2} # 3 2 1 0 -1 -2
echo {X..d} # X Y Z [ ] ^ _ ` a b c d
# Shows (some of) the ASCII
characters between Z and a,
#+ but don't rely on this type of
behavior because . . .
echo {]..a} # {]..a}
# Why?
# You can tack on prefixes and suffixes.
echo "Number #"{1..4}, "..."
# Number #1, Number #2, Number #3, Number #4,
...
# You can concatenate brace-expansion sets.
echo {1..3}{x..z}" +" "..."
# 1x + 1y + 1z + 2x + 2y + 2z + 3x + 3y + 3z +
...
# Generates an algebraic expression.
# This could be used to find permutations.
# You can nest brace-expansion sets.
echo {{a..c},{1..3}}
# a b c 1 2 3
# The "comma operator" splices together
strings.
# ########## ######### ############ ###########
######### ###############
# Unfortunately, brace expansion does not lend
itself to parameterization.
var1=1
var2=5
echo {$var1..$var2} # {1..5}
# Yet, as Emiliano G. points out, using "eval"
overcomes this limitation.
start=0
end=10
for index in $(eval echo {$start..$end})
do
echo -n "$index " # 0 1 2 3 4 5 6 7 8 9 10
done
echo
The ${!array[@]} operator, which expands to all the indices of
a given array.
#!/bin/bash
Array=(element-zero element-one element-two element-
three)
echo ${Array[0]} # element-zero
# First element of array.
echo ${!Array[@]} # 0 1 2 3
# All the indices of Array.
for i in ${!Array[@]}
do
echo ${Array[i]} # element-zero
# element-one
# element-two
# element-three
#
# All the elements in Array.
done
The =~ Regular Expression matching operator within a double
brackets test expression. (Perl has a similar operator.)
#!/bin/bash
variable="This is a fine mess."
echo "$variable"
# Regex matching with =~ operator within [[ double
brackets ]].
if [[ "$variable" =~ T.........fin*es* ]]
# NOTE: As of version 3.2 of Bash, expression to
match no longer quoted.
then
echo "match found"
# match found
fi
Or, more usefully:
#!/bin/bash
input=$1
if [[ "$input" =~ "[0-9][0-9][0-9]-[0-9][0-9]-[0-9]
[0-9][0-9][0-9]" ]]
# ^ NOTE: Quoting not necessary, as
of version 3.2 of Bash.
# NNN-NN-NNNN (where each N is a digit).
then
echo "Social Security number."
# Process SSN.
else
echo "Not a Social Security number!"
# Or, ask for corrected input.
fi
For additional examples of using the =~ operator, see Example
A-29, Example 19-14, Example A-35, and Example A-24.
The new set -o pipefail option is useful for debugging pipes.
If this option is set, then the exit status of a pipe is the exit
status of the last command in the pipe to fail (return a non-zero
value), rather than the actual final command in the pipe.
See Example 16-43.
The update to version 3 of Bash breaks a few scripts that
worked under earlier versions. Test critical legacy scripts to
make sure they still work!
As it happens, a couple of the scripts in the Advanced Bash
Scripting Guide had to be fixed up (see Example 9-4, for
instance).
37.2.1. Bash, version 3.1
The version 3.1 update of Bash introduces a number of bugfixes and a
few minor changes.
The += operator is now permitted in in places where previously only
the = assignment operator was recognized.
a=1
echo $a # 1
a+=5 # Won't work under versions of Bash
earlier than 3.1.
echo $a # 15
a+=Hello
echo $a # 15Hello
Here, += functions as a string concatenation operator. Note that its
behavior in this particular context is different than within a let
construct.
a=1
echo $a # 1
let a+=5 # Integer arithmetic, rather than string
concatenation.
echo $a # 6
let a+=Hello # Doesn't "add" anything to a.
echo $a # 6
Jeffrey Haemer points out that this concatenation operator can be
quite useful. In this instance, we append a directory to the $PATH.
bash$ echo $PATH
/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin/:/usr/games
bash$ PATH+=:/opt/bin
bash$ echo $PATH
/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin/:/usr/games:/opt/bin