Bash’s Crazy Config Files
In the ‘/etc` directory are some default bash config files that affect bash’ behavior unless countermanded by user set config files.
/etc/profile
This file is read and executed at initial login time by all users. I think that subshells ignore this. It also seems like this gets executed before the the xterm box is ready, so output from this script, like a message of the day, doesn’t seem to make it to the screen. It will make it to a log file however. This means that if you want to print a message or set the PS1 prompt variable, it won’t carry over when X subsequently opens up an xterm.
/etc/bashrc
This file is read and executed by all bash initialization activity such as logging in by any user from anywhere and any sub shell that the user spawns. I think that this is referred to in a lot of unexpected places too. So it’s not smart to have anything too busy here. This file might actually be a fake. It isn’t mentioned in any documentation. It seems to be called from /.bashrc. Therefore, if that file doesn’t exist, then this one is useless. It’s not really a global catch-all if users can pull the reference from their /.bashrc, so I don’t really see the point to it. Although it would take up a trivial amount of extra disk space, a better way would be to have the things that you wanted in here, in a skeleton for creating ~/.bashrc files when you create new users.
$HOME/.bash_profile
This is the users chance to redo the initial login settings established by /etc/profile, if there is one. This does things once only on log in. If the user wants something run every time he logs in, like a back up or something, here’s the good place for it. Be aware that this file has no less than two functionally equivalent synonyms, 1.) /.bash_login and 2.) /.profile which are searched for in order.
$HOME/.bashrc
This file is executed for all the owning user’s new shell activity. This means that these commands will be reissued for each and all subsequent subshells. This is where users can put custom aliases that should be very persistent. This file seems to execute quite frequently - 3 times on initial login for me and once for each subshell.
Pattern-Matching Operators:
-
${variable#pattern} if pattern matches beginning, del shortest part
-
${variable##pattern} if pattern matches beginnnig, del longest part
-
${variable%pattern} if pattern matches end, del shortest part
-
${variable%%pattern} if pattern matches end, del longest part
Here’s an example - this changes a big long list of x001.gif, x002.gif,etc to this b001.gif, b002.gif, b003.gif etc.
for ce in x???.gif; do mv $ce b${ce#x}; done
Another example - this converts a series of tif images with the names tb01.tif, tb02.tif,tbwhatever.tif to tb01.gif, tb02.gif, etc. It also changes the images to 15 color grayscale.
[~/xfile/project/pix]$ for ce in tb*.tif; \
> do convert -colorspace GRAY -colors 15 $ce ${ce%tif}gif; done
Mass updating of files that contain similar things that need changing
Here is a method to massively update lots of files that all contain some bad thing and replace it with some good thing. There might be a smoother way to use the sed command, but redirecting to the same file causes the file to simply disappear. Using a tempfile works just fine.
$ for cxe in project??.type ; do cp $cxe temp.temp; \ sed s/bad/good/g temp.temp > $cxe; done
Here, all files that match the project??.type pattern (project01.type, project1a.type, etc) will be copied into the temporary file temp.temp and then they’ll be pulled back out into their real name line by line by sed which will also make substitutions as requested. In this case, it will change all references of "bad" to "good". Don’t forget to erase the residual temp.temp file when you’re done.
Another note - if the text is long, you need quotes around it so bash doesn’t get wise with it: sed s/"This is very bad."/Nowitsgood/g file
If the text has quotes in it:
$ for X in *.html; do cp $X temp.temp;\ > sed s/height=\"66\"/height=\"100\"/ temp.temp > $X; done
Here’s another example-
$ for XXX in *html ; do cp $XXX temp.temp; \ > sed -e "/---/,/---/s/<table>/<table align=center>/" temp.temp > $XXX; done
This only does the substitution after it finds 3 dashs and only until it finds 3 more dashes.
Redirection
grep hattrick * 2> /dev/null
This will do the expected thing with stdout, but stderr will head off to the trash.
To get all of the garbage a command spits out to go to a file:
make &> compile.error
cmd1 2>&1 | cmd2 cdparanoia -Q 2>&1 | grep "no no"
General Bash Syntax
for variablename [in <list of textstrings or files>] do commands that take advantage of $variablename go here done
#!/bin/bash #cxe- Heredocs are a way to put a lot of arbitrary text into a commands #cxe- standard input stream. Can be good for CGI scripts and the like. #cxe- Here is a sample program that illustrates the idea. cat > test1 <<HEREDOC <html> <head><title>Here Doc Fun!</title><head> <body> HEREDOC #cxe- Note that the heredoc closer needs to be alone on the line. echo Here are commands that aren\'t part of the heredoc date
#cxe- Here are two good examples - the first one justs waits for a #cxe- confirmation message. read REP if [ CXE${REP} != "CXEy" ]; then echo "Ok, maybe next time." exit fi #cxe- The second one, makes some new directories if they need to be made. if [ ! -d ${TND} ]; then echo "Creating the directories:" echo "mkdir "${WSD}" "${TND} mkdir ${WSD} ${TND} fi
#!/bin/bash # getopts_example - Chris X Edwards # Note that the options must come before the arguments. For example: # getopts_example king queen -c jack # Will make "-c" an argument. function show_usage { echo "Usage: getopts_example [-h] [-a alpha] [-b beta] [-c] <arguments>" echo " -h = usage message" echo " -a = set alpha value [default 'First']" echo " -b = set beta value [default not set]" echo " -c = set gamma flag [default not set]" exit } ALPHA="DefaultValue" # Set default value. # Option letters followed by ":" mean has an OPTARG. while getopts "a:b:ch" OPTION do case ${OPTION} in a) ALPHA=${OPTARG};; b) BETA=${OPTARG};; c) GAMMA="true";; h) show_usage;; esac done shift $((OPTIND - 1)) # Leave behind remaining arguments. [ "$ALPHA" ] && echo "Alpha is set to: $ALPHA" [ "$BETA" ] && echo "Beta is set to: $BETA" [ "$GAMMA" ] && echo "Gamma is set." echo "Arguments:" for OP in $* ; do echo $OP ; done