contact me site uses txt2html
-- DDS Tape Drives - Observations and Best Practices At home, after writing backup data to DDS tape, I rewind, and read each tape file to validate the tape. If that tape drive fails, I want to be able to recover using a different drive. I have several drives, can they read each others tapes? SCSI DDS tape drives have always been dicey, delicate devices for me. Yesterday, I ran some preliminary tests. My DDS3 drive can read DDS2 tapes created by other drives. As a rule, it appears, my DDS2 drives can read each other's tapes. Unfortunately my DDS2 drives can not read any DDS2 tape that was written to by my DDS3 tape drive. I have checked the density of the writes with 'mt -f /dev/st0 stat', and DDS2 is reported. Needless to say I won't be creating any more DDS2 tape backups w/my DDS3 drive. After each backup, is done I update the paper label on the tape with the date, and the name of the specific tape drive that wrote it. -- Ever have a DDS tape refuse to eject? Take the steps needed so you can see the outside of the drive itself from the side. On one side, there should be a hole in the metal drive cover, for a small screw driver. Around this hole should be a CW or CCW arrow, to suggest which way to rotate the internal screw head. It is geared down, so it takes many turns to eject the tape - as you turn, be careful, to untangle the tape media, if the drive has 'eaten the tape'. Wed 26 Aug 2009 -- nice and backgrounding a ~/.bashrc function Say you have a bash function defined as part of your login sequence, so it is available to your interactive shell. You want to run this function for a job you know will take hours, so you'd like to background it and run at a lower priority. In the last example below I want to report diffs on my "day plan" (a text file 'dp') over a 6 year period; 'dp' was cron/auto checked in to RCS revision control each work day. methods that fail, the third suggests the solution: ~ $ bash -c '(set -x; alias pgrep; type _history)' + alias pgrep bash: line 1: alias: pgrep: not found + type _history bash: line 1: type: _history: not found ~ $ bash -lc '(set -x; alias pgrep; type _history)' + alias pgrep bash: line 1: alias: pgrep: not found + type _history bash: line 1: type: _history: not found ~ $ bash -lic '(set -x; alias pgrep; type _history)' + alias pgrep alias pgrep='pgrep -l -f' + type _history _history is a function _history () { case $BASH_VERSION in [12]*) history "$@" ;; *) HISTTIMEFORMAT="%x %X " history "$@" ;; esac } ~ $ So in my real world case, here is the solution: nice bash -lic 'hrcs -t "6 years ago" /tmp/dp' &>/var/tmp/foo & # 'hrcs' (show RCS history) is bash function I define for my # login sessions; so above job runs in background at lower # priority. see 'man bash': ( -l ==> login; -i ==> interactive) -- hint at a simplier approach, that fails: ~ $ foo() { echo hi; } ~ $ foo hi ~ $ nice foo nice: foo: No such file or directory Tue 25 Aug 2009 -- math with gnu bc Where others would use a spreadsheet for simple floating point math, I often use gnu bc, awk or perl. Below is an example using bc: converts a present value into a series of payments over 10, 15 and 20 year periods: Ex /tmp $ cat calc0 #!/usr/bin/bc -lq ## house sale profit as series of monthly payments scale = 10 # 10 digits used in calculations sale_profit = 85000 yearlyint=2 i = yearlyint/100/12 print "Assumptions:\n" print " starting amount: ";sale_profit print " interest rate : ";yearlyint print "\n" for ( years=10; years <= 20;years +=5) { n=years * 12 a= i * (1 + i)^n /((1 + i )^n - 1 ) * sale_profit scale = 2 print "total years: "; years print "constant per month: "; a/1 print "\n" scale=10 } quit /tmp $ ./calc0 Assumptions: starting amount: 85000 interest rate : 2 total years: 10 constant per month: 782.11 total years: 15 constant per month: 546.98 total years: 20 constant per month: 430.00 The next example shows three bash functions using GNU date and bc. I define them for my login session. They calculate hours, minutes or days between dates. Ex /tmp $ which hbd hbd is a function hbd () { echo -e "scale=2\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/3600"|bc -l } /tmp $ which dbd dbd is a function dbd () { echo -e "scale=1\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/3600/24"|bc -l } /tmp $ which mbd mbd is a function mbd () { echo -e "scale=2\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/60"|bc -l } /tmp $ echo 12/25/2009 ["$(date)"] 12/25/2009 [Tue Aug 25 15:23:05 CDT 2009] /tmp $ dbd 12/25/2009 "$(date)" 121.3 /tmp $ dbd 12/25/2009 121.3 -- Sun 23 Aug 2009 Tips on the versatile GNU date command: time zones, time zone conversions, scheduling 'at' jobs.. Ex date --date "$(date --date 'next month' '+%m/1/%Y') -1 day" # last day in month Ex echo rm -f /tmp/foo|at $(date -d "1am +3 weeks" '+%H:%M %D') # 'at' command likes above date output format Ex TZ=America/Chicago \ date -d \ "1970-01-01 UTC $(TZ=Asia/Calcutta date -d "Jun 8 7:20:06" '+%s') sec" The best way to understand the notes is to try the examples shown: http://trodman.com/cgi-bin/lualu?@3ywfmg -- Thu 20 Aug 2009 -- tar using ssh to remote host w/o pipes Ex /tmp $ ssh rodmant@hera date #hera is another linux box Thu Aug 20 08:12:45 CDT 2009 /tmp $ which ssh ssh is /usr/bin/ssh /tmp $ ssh rodmant@hera ls /tmp/bar.tar ls: cannot access /tmp/bar.tar: No such file or directory /tmp $ tar --rsh-command=/usr/bin/ssh -cf rodmant@hera:/tmp/bar.tar foo /tmp $ ssh rodmant@hera ls -l /tmp/bar.tar -rw-r--r-- 1 rodmant staff 10240 2009-08-20 08:15 /tmp/bar.tar /tmp $ tar --rsh-command=/usr/bin/ssh -tvf rodmant@hera:/tmp/bar.tar -rw-r--r-- rodmant/staff 3893 2009-08-20 08:10:58 foo Replace /tmp/bar.tar above w/remote host's tape drive. The --rsh-command= is supported by GNU tar; is documented in 'info tar'. -- Wed 19 Aug 2009 -- trivial m4 example Ex /tmp $ cat _date_here.m4 m4_divert(-1) above divert throws away all m4 output m4_define(_date_here,m4_esyscmd(date|tr -d \\n )) The 'tr -d \\n' is needed to remove the trailing new line. Notice xx_esyscmd macro is passing it's argument to the shell. xx_divert below restores m4 output to STDOUT. The trailing xx_dnl prevents an unwanted newline. m4_divert(0)m4_dnl /tmp $ cat foo.m4 hi/_date_here/ho bye /tmp $ m4 -P _date_here.m4 foo.m4 hi/Wed Aug 19 08:53:45 CDT 2009/ho bye -- 'info m4' snip (note that m4 quotes are *not* redefined tho): `-P' `--prefix-builtins' Internally modify *all* builtin macro names so they all start with the prefix `m4_'. For example, using this option, one should write `m4_define' instead of `define', and `m4___file__' instead of `__file__'. Tue 18 Aug 2009 -- revision control for UNIX config files One of the first tips I was given from a stern, elder UNIX system administrator over 20 years ago was to use SCCS revision control for all the config files on our SUN Sparc II workstations. I've long since switched to RCS, but have held myself to his rule to this day with no regrets. why version control for your system config files?: run rcsdiff on each change you make to double check your edits before 'committing' straightforward back outs you may add comments for each revision at check in you always have the original 'as shipped/out of the box' version use rlog and rcsdiff to show the changes as a history; as system problems arise you can look back at the time and date stamped change history and spot a correlation (if any) imp: you can write a script to locate and backup all your modified files based on a search for the ',v' RCS archive files. Typically this archive is amazingly small. once every year or two, some how, a file is deleted; no problem since you are using revison control This same approach works on Windows, under Cygwin, using RCS, provided that you're careful to write a wrapper around ci and co, so that the existing file permissions (and timestamps) do not have to be impacted by a check in. -- Sat 15 Aug 2009 -- 1 liners for analyzing ~full disk http://trodman.com/cgi-bin/lualu?@dae4e:di Fri 14 Aug 2009 a bit dry, and a couple of years old, still I plan to listen again, FSF lawyer Ebon Moglen on GPL2 and GPL3: http://twit.cachefly.net/FLOSS-013.mp3 Thu 13 Aug 2009 -- reverse command line args order in bash Works for args containing spaces. # temp var x & array y used (y must be unset or empty at start) if test $# -gt 0 then # reverse order of args for x do eval y=\(\"$x\"${y+\ \"\$\{y[@]\}\"}\) #prepend #$y apparently is 1st element in array done set "${y[@]}" unset y x fi #-- Ex ~ $ unset y ~ $ set hi "hello there" greetings "best regards" ~ $ for x > do > eval y=\(\"$x\"${y+\ \"\$\{y[@]\}\"}\) > done ~ $ ~ $ set "${y[@]}" ~ $ unset y x ~ $ for f;do echo "/$f/";done /best regards/ /greetings/ /hello there/ /hi/ Ex dumb but fun earlier attempt: ~ $ set fee fi fo fum ~ $ set $(rev <<<"$*") ~ $ echo $* muf of if eef ~ $ Ex $y vs ${y[0]}: ~ $ unset y; echo /$y/ // ~ $ y=("1st entry" "second array entry" last) ~ $ echo "/$y/" /1st entry/ ~ $ echo ${y[2]} last -- Mon 10 Aug 2009 -- linux recovery hardcopy notes I print this out in a tiny font and tape it near my monitor. It's intended to fit on 1 page - cryptic notes on what to do in an emergency, in single user mode when you have a corrupted file system, disk i/o errors, a boot problem or .. : http://trodman.com/cgi-bin/lualu?@e603d3:rv find bad soft links in a tree find . -type l |while read f;do test -e "$f" || echo $f;done # below CWD -- Sun 09 Aug 2009 -- my disk recovery tags www.connotea.org/user/zfyarpe/tag/ddrescue www.connotea.org/user/zfyarpe/tag/disk www.connotea.org/user/zfyarpe/tag/recovery www.connotea.org/user/zfyarpe/tag/backup www.connotea.org/user/zfyarpe/tag/mbr saving your delicious bookmarks to xml www.shell-fu.org/lister.php?id=843 Ex /tmp $ cygcheck -f /usr/bin/wget wget-1.11.4-3 /tmp $ wget --user=johndoe --no-check-certificate --password=XXXX https://api.del.icio.us/v1/posts/all -O bookmarks.xml &>/tmp/log /tmp $ ls -l bookmarks.xml /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 2395 Aug 9 11:55 /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 1138749 Aug 9 11:55 bookmarks.xml /tmp $ wc -l bookmarks.xml 3225 bookmarks.xml /tmp $ "bookmarks.xml" is one line per URL, it's easy to grep. Sat 08 Aug 2009 Apr 29 2009 Randal Schwartz "Dynamic Returns": www.cincomsmalltalk.com/audio/2009/industry%5Fmisinterpretations135.mp3 refering link: www.cincomsmalltalk.com/blog/b..ynamic_Returns&entry=3419405760 related: http://therning.org/magnus/archives/620 michaelgalloy.com/2009/05/14/r..z-talk-about-dynamic-languages.html -- Fri 07 Aug 2009 -- debugging interactive shell bash startup sequence Where was that alias, function or env var definition?: http://trodman.com/cgi-bin/lualu?@474e0:e To help debugging I add lines to the startup files as hinted: ~ $ head ~/.bashrc |grep login_seq : login_seq-starting: ~/.bashrc ~ $ tail ~/.bashrc |grep login_seq : login_seq-EOF ~/.bashrc ~ $ -- Is your shell interactive? Programmatic check. http://trodman.com/cgi-bin/lualu?@8cd98f:i #safe# two line prompt for system admin work Ever pasted your terminal clip board into a root shell session by mistake? After I paste a large number of lines, I try to nearly empty the clipboard, by putting a single space char into the clipboard (I use putty as a terminal). This prompt starts with a shell comment char '#', so it can limit the damage of an mistaken paste: /etc/local/team/mke/bash $ cat prompt # ==================================================================== # set up prompt # ==================================================================== case $USER in root)prompt_char='#' ;; *) prompt_char='$' ;; esac PS1="# \t \D{%a %y%m%d} \jj \l $$ \w\n# \h \u ${prompt_char} " # \t the current time in 24-hour HH:MM:SS format # \D see 'man bash|col -b|less +/strftime; man 3 strftime ## ' # \d the date in "Weekday Month Date" format (e.g.,"Tue May 26") # \j the number of jobs currently managed by the shell # \l the basename of the shell's terminal device name # $$ PID for current shell # \w the current working directory # \h the hostname up to the first `.' # \u the username of the current user /etc/local/team/mke/bash $ source prompt /etc/local/team/mke/bash $ -- Not sure what's in your clip board, or you want to "park it" somewhere? Here's an alias I use for that: alias _e='(stty -echo cbreak;cat)' Type '_e<enter>' then safely paste your terminal clipboard; ^C to get your prompt back. -- Tue 04 Aug 2009 Idiom for copying directories The trailing "/." is crucial: cp -af foo/. bar # Dir 'bar' will have same files and subdirs as dir 'foo'. # Does not matter if bar/ pre-exists. mnemonic- "slashdot" Ex /tmp $ mkdir -p foo/a/b/c/d /tmp $ ls bar ls: bar: No such file or directory /tmp $ command cp -a foo/. bar /tmp $ diff -qr foo bar; echo $? # no diffs 0 /tmp $ command cp -af foo/. bar # bar/ pre-exists, hence the -f /tmp $ diff -qr foo bar; echo $? 0 The -a preserves timestamps and permissions, the -f deals with preexisting destination files and dirs. Sun 02 Aug 2009 rounding idiom for bash: printf %.0f $YOURNUMBER Ex ~ $ printf "%.0f\n" 0.5 0 ~ $ printf "%.0f\n" 1.5 2 ~ $ printf "%.0f\n" 2.5 2 ~ $ printf "%.0f\n" 3.5 4 above is 'unbiased rounding' (evens down, odds up): www.gnu.org/manual/gawk/html_n../gawk/html_node/Round-Function.html -- manually validating a podcast link, before subscribing - ie checking for fresh mp3s: I made up a grep like bash function - a wrapper for wget: ~ $ which wgrep wgrep is a function wgrep () { : supports a global array 'wgrep_sw' used for egrep switches; local regex=$1; shift; local TMP=$(mktemp /tmp/$FUNCNAME.wget-out2.XXXXXXX); local site wget_stat; for site in "$@"; do if test -n "${wgrep_sw[*]:-}"; then wget -O - "$site" 2>$TMP | egrep "${wgrep_sw[@]}" "$regex"; wget_stat=${PIPESTATUS[0]}; else wget -O - "$site" 2>$TMP | egrep -i "$regex"; wget_stat=${PIPESTATUS[0]}; fi; if ! test "$wget_stat" = 0; then { echo -e "\nwget STDERR:"; sed -e 's~^~ ~' $TMP; echo } 1>&2; fi; done } example run: ~ $ wgrep 'pubdate|link.*mp3' http://leoville.tv/podcasts/floss.xml|head -3 <pubDate>Sat, 01 Aug 2009 15:11:30 -0400</pubDate> <link>http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-080.mp3</link> <pubDate>Sat, 01 Aug 2009 14:55:43 -0400</pubDate> -- Thu 30 Jul 2009 Ruby on Rails founder David Heinemeier interviewed by Randal Schwartz: http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-079.mp3 -- Sun 19 Jul 2009 notes on 'patch', patching a whole tree of scripts: http://trodman.com/cgi-bin/lualu?:@7a7b22:p -- Wed 15 Jul 2009 idioms for setting defaults in bash scripts, bash 'Parameter Expansion': http://trodman.com/cgi-bin/lualu?:parameter%20expansion bash startup notes: http://trodman.com/cgi-bin/lualu?:login%20sequence -- Mon 13 Jul 2009 GNU find examples (a work in progress): http://trodman.com/cgi-bin/lualu?@7boJHe:f -- Sat 11 Jul 2009 One way to check your backups is to re-read the entire tape file you just wrote, here are some recent test notes on Linux mt command: http://trodman.com/cgi-bin/lualu?@Se7Ysf:d -- Mon 06 Jul 2009 FLOSS interview on Arduino (open source hardware) www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-061.mp3 http://www.arduino.cc -- various Tom Rodman accounts Study and work related bookmarks: www.connotea.org/user/zfyarpe -- twitter: http://twitter.com/xriorb -- gtalk, and aim accounts - pls email me for them: www.trodman.com/cgi-bin/showTSRemail -- about www.trodman.com/blog Short notes on Linux and UNIX system administration, and scripting in bash and perl. Posts arise when I need to refer to my 15+ years of plain text notes - I have time for this now because I'm actively looking for a job. To help me find a job please share these links: resume for Tom Rodman: www.trodman.com/cv contact info: www.trodman.com Tom Rodman's blog: www.trodman.com/blog Thank-you!
At home, after writing backup data to DDS tape, I rewind, and read each tape file to validate the tape.
If that tape drive fails, I want to be able to recover using a different drive.
I have several drives, can they read each others tapes? SCSI DDS tape drives have always been dicey, delicate devices for me. Yesterday, I ran some preliminary tests. My DDS3 drive can read DDS2 tapes created by other drives. As a rule, it appears, my DDS2 drives can read each other's tapes.
Unfortunately my DDS2 drives can not read any DDS2 tape that was written to by my DDS3 tape drive. I have checked the density of the writes with 'mt -f /dev/st0 stat', and DDS2 is reported. Needless to say I won't be creating any more DDS2 tape backups w/my DDS3 drive. After each backup, is done I update the paper label on the tape with the date, and the name of the specific tape drive that wrote it.
-- Ever have a DDS tape refuse to eject? Take the steps needed so you can see the outside of the drive itself from the side. On one side, there should be a hole in the metal drive cover, for a small screw driver. Around this hole should be a CW or CCW arrow, to suggest which way to rotate the internal screw head. It is geared down, so it takes many turns to eject the tape - as you turn, be careful, to untangle the tape media, if the drive has 'eaten the tape'. Wed 26 Aug 2009 -- nice and backgrounding a ~/.bashrc function Say you have a bash function defined as part of your login sequence, so it is available to your interactive shell. You want to run this function for a job you know will take hours, so you'd like to background it and run at a lower priority. In the last example below I want to report diffs on my "day plan" (a text file 'dp') over a 6 year period; 'dp' was cron/auto checked in to RCS revision control each work day. methods that fail, the third suggests the solution: ~ $ bash -c '(set -x; alias pgrep; type _history)' + alias pgrep bash: line 1: alias: pgrep: not found + type _history bash: line 1: type: _history: not found ~ $ bash -lc '(set -x; alias pgrep; type _history)' + alias pgrep bash: line 1: alias: pgrep: not found + type _history bash: line 1: type: _history: not found ~ $ bash -lic '(set -x; alias pgrep; type _history)' + alias pgrep alias pgrep='pgrep -l -f' + type _history _history is a function _history () { case $BASH_VERSION in [12]*) history "$@" ;; *) HISTTIMEFORMAT="%x %X " history "$@" ;; esac } ~ $ So in my real world case, here is the solution: nice bash -lic 'hrcs -t "6 years ago" /tmp/dp' &>/var/tmp/foo & # 'hrcs' (show RCS history) is bash function I define for my # login sessions; so above job runs in background at lower # priority. see 'man bash': ( -l ==> login; -i ==> interactive) -- hint at a simplier approach, that fails: ~ $ foo() { echo hi; } ~ $ foo hi ~ $ nice foo nice: foo: No such file or directory Tue 25 Aug 2009 -- math with gnu bc Where others would use a spreadsheet for simple floating point math, I often use gnu bc, awk or perl. Below is an example using bc: converts a present value into a series of payments over 10, 15 and 20 year periods: Ex /tmp $ cat calc0 #!/usr/bin/bc -lq ## house sale profit as series of monthly payments scale = 10 # 10 digits used in calculations sale_profit = 85000 yearlyint=2 i = yearlyint/100/12 print "Assumptions:\n" print " starting amount: ";sale_profit print " interest rate : ";yearlyint print "\n" for ( years=10; years <= 20;years +=5) { n=years * 12 a= i * (1 + i)^n /((1 + i )^n - 1 ) * sale_profit scale = 2 print "total years: "; years print "constant per month: "; a/1 print "\n" scale=10 } quit /tmp $ ./calc0 Assumptions: starting amount: 85000 interest rate : 2 total years: 10 constant per month: 782.11 total years: 15 constant per month: 546.98 total years: 20 constant per month: 430.00 The next example shows three bash functions using GNU date and bc. I define them for my login session. They calculate hours, minutes or days between dates. Ex /tmp $ which hbd hbd is a function hbd () { echo -e "scale=2\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/3600"|bc -l } /tmp $ which dbd dbd is a function dbd () { echo -e "scale=1\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/3600/24"|bc -l } /tmp $ which mbd mbd is a function mbd () { echo -e "scale=2\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/60"|bc -l } /tmp $ echo 12/25/2009 ["$(date)"] 12/25/2009 [Tue Aug 25 15:23:05 CDT 2009] /tmp $ dbd 12/25/2009 "$(date)" 121.3 /tmp $ dbd 12/25/2009 121.3 -- Sun 23 Aug 2009 Tips on the versatile GNU date command: time zones, time zone conversions, scheduling 'at' jobs.. Ex date --date "$(date --date 'next month' '+%m/1/%Y') -1 day" # last day in month Ex echo rm -f /tmp/foo|at $(date -d "1am +3 weeks" '+%H:%M %D') # 'at' command likes above date output format Ex TZ=America/Chicago \ date -d \ "1970-01-01 UTC $(TZ=Asia/Calcutta date -d "Jun 8 7:20:06" '+%s') sec" The best way to understand the notes is to try the examples shown: http://trodman.com/cgi-bin/lualu?@3ywfmg -- Thu 20 Aug 2009 -- tar using ssh to remote host w/o pipes Ex /tmp $ ssh rodmant@hera date #hera is another linux box Thu Aug 20 08:12:45 CDT 2009 /tmp $ which ssh ssh is /usr/bin/ssh /tmp $ ssh rodmant@hera ls /tmp/bar.tar ls: cannot access /tmp/bar.tar: No such file or directory /tmp $ tar --rsh-command=/usr/bin/ssh -cf rodmant@hera:/tmp/bar.tar foo /tmp $ ssh rodmant@hera ls -l /tmp/bar.tar -rw-r--r-- 1 rodmant staff 10240 2009-08-20 08:15 /tmp/bar.tar /tmp $ tar --rsh-command=/usr/bin/ssh -tvf rodmant@hera:/tmp/bar.tar -rw-r--r-- rodmant/staff 3893 2009-08-20 08:10:58 foo Replace /tmp/bar.tar above w/remote host's tape drive. The --rsh-command= is supported by GNU tar; is documented in 'info tar'. -- Wed 19 Aug 2009 -- trivial m4 example Ex /tmp $ cat _date_here.m4 m4_divert(-1) above divert throws away all m4 output m4_define(_date_here,m4_esyscmd(date|tr -d \\n )) The 'tr -d \\n' is needed to remove the trailing new line. Notice xx_esyscmd macro is passing it's argument to the shell. xx_divert below restores m4 output to STDOUT. The trailing xx_dnl prevents an unwanted newline. m4_divert(0)m4_dnl /tmp $ cat foo.m4 hi/_date_here/ho bye /tmp $ m4 -P _date_here.m4 foo.m4 hi/Wed Aug 19 08:53:45 CDT 2009/ho bye -- 'info m4' snip (note that m4 quotes are *not* redefined tho): `-P' `--prefix-builtins' Internally modify *all* builtin macro names so they all start with the prefix `m4_'. For example, using this option, one should write `m4_define' instead of `define', and `m4___file__' instead of `__file__'. Tue 18 Aug 2009 -- revision control for UNIX config files One of the first tips I was given from a stern, elder UNIX system administrator over 20 years ago was to use SCCS revision control for all the config files on our SUN Sparc II workstations. I've long since switched to RCS, but have held myself to his rule to this day with no regrets. why version control for your system config files?: run rcsdiff on each change you make to double check your edits before 'committing' straightforward back outs you may add comments for each revision at check in you always have the original 'as shipped/out of the box' version use rlog and rcsdiff to show the changes as a history; as system problems arise you can look back at the time and date stamped change history and spot a correlation (if any) imp: you can write a script to locate and backup all your modified files based on a search for the ',v' RCS archive files. Typically this archive is amazingly small. once every year or two, some how, a file is deleted; no problem since you are using revison control This same approach works on Windows, under Cygwin, using RCS, provided that you're careful to write a wrapper around ci and co, so that the existing file permissions (and timestamps) do not have to be impacted by a check in. -- Sat 15 Aug 2009 -- 1 liners for analyzing ~full disk http://trodman.com/cgi-bin/lualu?@dae4e:di Fri 14 Aug 2009 a bit dry, and a couple of years old, still I plan to listen again, FSF lawyer Ebon Moglen on GPL2 and GPL3: http://twit.cachefly.net/FLOSS-013.mp3 Thu 13 Aug 2009 -- reverse command line args order in bash Works for args containing spaces. # temp var x & array y used (y must be unset or empty at start) if test $# -gt 0 then # reverse order of args for x do eval y=\(\"$x\"${y+\ \"\$\{y[@]\}\"}\) #prepend #$y apparently is 1st element in array done set "${y[@]}" unset y x fi #-- Ex ~ $ unset y ~ $ set hi "hello there" greetings "best regards" ~ $ for x > do > eval y=\(\"$x\"${y+\ \"\$\{y[@]\}\"}\) > done ~ $ ~ $ set "${y[@]}" ~ $ unset y x ~ $ for f;do echo "/$f/";done /best regards/ /greetings/ /hello there/ /hi/ Ex dumb but fun earlier attempt: ~ $ set fee fi fo fum ~ $ set $(rev <<<"$*") ~ $ echo $* muf of if eef ~ $ Ex $y vs ${y[0]}: ~ $ unset y; echo /$y/ // ~ $ y=("1st entry" "second array entry" last) ~ $ echo "/$y/" /1st entry/ ~ $ echo ${y[2]} last -- Mon 10 Aug 2009 -- linux recovery hardcopy notes I print this out in a tiny font and tape it near my monitor. It's intended to fit on 1 page - cryptic notes on what to do in an emergency, in single user mode when you have a corrupted file system, disk i/o errors, a boot problem or .. : http://trodman.com/cgi-bin/lualu?@e603d3:rv find bad soft links in a tree find . -type l |while read f;do test -e "$f" || echo $f;done # below CWD -- Sun 09 Aug 2009 -- my disk recovery tags www.connotea.org/user/zfyarpe/tag/ddrescue www.connotea.org/user/zfyarpe/tag/disk www.connotea.org/user/zfyarpe/tag/recovery www.connotea.org/user/zfyarpe/tag/backup www.connotea.org/user/zfyarpe/tag/mbr saving your delicious bookmarks to xml www.shell-fu.org/lister.php?id=843 Ex /tmp $ cygcheck -f /usr/bin/wget wget-1.11.4-3 /tmp $ wget --user=johndoe --no-check-certificate --password=XXXX https://api.del.icio.us/v1/posts/all -O bookmarks.xml &>/tmp/log /tmp $ ls -l bookmarks.xml /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 2395 Aug 9 11:55 /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 1138749 Aug 9 11:55 bookmarks.xml /tmp $ wc -l bookmarks.xml 3225 bookmarks.xml /tmp $ "bookmarks.xml" is one line per URL, it's easy to grep. Sat 08 Aug 2009 Apr 29 2009 Randal Schwartz "Dynamic Returns": www.cincomsmalltalk.com/audio/2009/industry%5Fmisinterpretations135.mp3 refering link: www.cincomsmalltalk.com/blog/b..ynamic_Returns&entry=3419405760 related: http://therning.org/magnus/archives/620 michaelgalloy.com/2009/05/14/r..z-talk-about-dynamic-languages.html -- Fri 07 Aug 2009 -- debugging interactive shell bash startup sequence Where was that alias, function or env var definition?: http://trodman.com/cgi-bin/lualu?@474e0:e To help debugging I add lines to the startup files as hinted: ~ $ head ~/.bashrc |grep login_seq : login_seq-starting: ~/.bashrc ~ $ tail ~/.bashrc |grep login_seq : login_seq-EOF ~/.bashrc ~ $ -- Is your shell interactive? Programmatic check. http://trodman.com/cgi-bin/lualu?@8cd98f:i #safe# two line prompt for system admin work Ever pasted your terminal clip board into a root shell session by mistake? After I paste a large number of lines, I try to nearly empty the clipboard, by putting a single space char into the clipboard (I use putty as a terminal). This prompt starts with a shell comment char '#', so it can limit the damage of an mistaken paste: /etc/local/team/mke/bash $ cat prompt # ==================================================================== # set up prompt # ==================================================================== case $USER in root)prompt_char='#' ;; *) prompt_char='$' ;; esac PS1="# \t \D{%a %y%m%d} \jj \l $$ \w\n# \h \u ${prompt_char} " # \t the current time in 24-hour HH:MM:SS format # \D see 'man bash|col -b|less +/strftime; man 3 strftime ## ' # \d the date in "Weekday Month Date" format (e.g.,"Tue May 26") # \j the number of jobs currently managed by the shell # \l the basename of the shell's terminal device name # $$ PID for current shell # \w the current working directory # \h the hostname up to the first `.' # \u the username of the current user /etc/local/team/mke/bash $ source prompt /etc/local/team/mke/bash $ -- Not sure what's in your clip board, or you want to "park it" somewhere? Here's an alias I use for that: alias _e='(stty -echo cbreak;cat)' Type '_e<enter>' then safely paste your terminal clipboard; ^C to get your prompt back. -- Tue 04 Aug 2009 Idiom for copying directories The trailing "/." is crucial: cp -af foo/. bar # Dir 'bar' will have same files and subdirs as dir 'foo'. # Does not matter if bar/ pre-exists. mnemonic- "slashdot" Ex /tmp $ mkdir -p foo/a/b/c/d /tmp $ ls bar ls: bar: No such file or directory /tmp $ command cp -a foo/. bar /tmp $ diff -qr foo bar; echo $? # no diffs 0 /tmp $ command cp -af foo/. bar # bar/ pre-exists, hence the -f /tmp $ diff -qr foo bar; echo $? 0 The -a preserves timestamps and permissions, the -f deals with preexisting destination files and dirs. Sun 02 Aug 2009 rounding idiom for bash: printf %.0f $YOURNUMBER Ex ~ $ printf "%.0f\n" 0.5 0 ~ $ printf "%.0f\n" 1.5 2 ~ $ printf "%.0f\n" 2.5 2 ~ $ printf "%.0f\n" 3.5 4 above is 'unbiased rounding' (evens down, odds up): www.gnu.org/manual/gawk/html_n../gawk/html_node/Round-Function.html -- manually validating a podcast link, before subscribing - ie checking for fresh mp3s: I made up a grep like bash function - a wrapper for wget: ~ $ which wgrep wgrep is a function wgrep () { : supports a global array 'wgrep_sw' used for egrep switches; local regex=$1; shift; local TMP=$(mktemp /tmp/$FUNCNAME.wget-out2.XXXXXXX); local site wget_stat; for site in "$@"; do if test -n "${wgrep_sw[*]:-}"; then wget -O - "$site" 2>$TMP | egrep "${wgrep_sw[@]}" "$regex"; wget_stat=${PIPESTATUS[0]}; else wget -O - "$site" 2>$TMP | egrep -i "$regex"; wget_stat=${PIPESTATUS[0]}; fi; if ! test "$wget_stat" = 0; then { echo -e "\nwget STDERR:"; sed -e 's~^~ ~' $TMP; echo } 1>&2; fi; done } example run: ~ $ wgrep 'pubdate|link.*mp3' http://leoville.tv/podcasts/floss.xml|head -3 <pubDate>Sat, 01 Aug 2009 15:11:30 -0400</pubDate> <link>http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-080.mp3</link> <pubDate>Sat, 01 Aug 2009 14:55:43 -0400</pubDate> -- Thu 30 Jul 2009 Ruby on Rails founder David Heinemeier interviewed by Randal Schwartz: http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-079.mp3 -- Sun 19 Jul 2009 notes on 'patch', patching a whole tree of scripts: http://trodman.com/cgi-bin/lualu?:@7a7b22:p -- Wed 15 Jul 2009 idioms for setting defaults in bash scripts, bash 'Parameter Expansion': http://trodman.com/cgi-bin/lualu?:parameter%20expansion bash startup notes: http://trodman.com/cgi-bin/lualu?:login%20sequence -- Mon 13 Jul 2009 GNU find examples (a work in progress): http://trodman.com/cgi-bin/lualu?@7boJHe:f -- Sat 11 Jul 2009 One way to check your backups is to re-read the entire tape file you just wrote, here are some recent test notes on Linux mt command: http://trodman.com/cgi-bin/lualu?@Se7Ysf:d -- Mon 06 Jul 2009 FLOSS interview on Arduino (open source hardware) www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-061.mp3 http://www.arduino.cc -- various Tom Rodman accounts Study and work related bookmarks: www.connotea.org/user/zfyarpe -- twitter: http://twitter.com/xriorb -- gtalk, and aim accounts - pls email me for them: www.trodman.com/cgi-bin/showTSRemail -- about www.trodman.com/blog Short notes on Linux and UNIX system administration, and scripting in bash and perl. Posts arise when I need to refer to my 15+ years of plain text notes - I have time for this now because I'm actively looking for a job. To help me find a job please share these links: resume for Tom Rodman: www.trodman.com/cv contact info: www.trodman.com Tom Rodman's blog: www.trodman.com/blog Thank-you!
--
Say you have a bash function defined as part of your login sequence, so it is available to your interactive shell. You want to run this function for a job you know will take hours, so you'd like to background it and run at a lower priority.
In the last example below I want to report diffs on my "day plan" (a text file 'dp') over a 6 year period; 'dp' was cron/auto checked in to RCS revision control each work day.
methods that fail, the third suggests the solution: ~ $ bash -c '(set -x; alias pgrep; type _history)' + alias pgrep bash: line 1: alias: pgrep: not found + type _history bash: line 1: type: _history: not found ~ $ bash -lc '(set -x; alias pgrep; type _history)' + alias pgrep bash: line 1: alias: pgrep: not found + type _history bash: line 1: type: _history: not found ~ $ bash -lic '(set -x; alias pgrep; type _history)' + alias pgrep alias pgrep='pgrep -l -f' + type _history _history is a function _history () { case $BASH_VERSION in [12]*) history "$@" ;; *) HISTTIMEFORMAT="%x %X " history "$@" ;; esac } ~ $ So in my real world case, here is the solution: nice bash -lic 'hrcs -t "6 years ago" /tmp/dp' &>/var/tmp/foo & # 'hrcs' (show RCS history) is bash function I define for my # login sessions; so above job runs in background at lower # priority. see 'man bash': ( -l ==> login; -i ==> interactive) -- hint at a simplier approach, that fails: ~ $ foo() { echo hi; } ~ $ foo hi ~ $ nice foo nice: foo: No such file or directory
Where others would use a spreadsheet for simple floating point math, I often use gnu bc, awk or perl. Below is an example using bc: converts a present value into a series of payments over 10, 15 and 20 year periods:
Ex /tmp $ cat calc0 #!/usr/bin/bc -lq ## house sale profit as series of monthly payments scale = 10 # 10 digits used in calculations sale_profit = 85000 yearlyint=2 i = yearlyint/100/12 print "Assumptions:\n" print " starting amount: ";sale_profit print " interest rate : ";yearlyint print "\n" for ( years=10; years <= 20;years +=5) { n=years * 12 a= i * (1 + i)^n /((1 + i )^n - 1 ) * sale_profit scale = 2 print "total years: "; years print "constant per month: "; a/1 print "\n" scale=10 } quit /tmp $ ./calc0 Assumptions: starting amount: 85000 interest rate : 2 total years: 10 constant per month: 782.11 total years: 15 constant per month: 546.98 total years: 20 constant per month: 430.00
The next example shows three bash functions using GNU date and bc. I define them for my login session. They calculate hours, minutes or days between dates.
Ex /tmp $ which hbd hbd is a function hbd () { echo -e "scale=2\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/3600"|bc -l } /tmp $ which dbd dbd is a function dbd () { echo -e "scale=1\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/3600/24"|bc -l } /tmp $ which mbd mbd is a function mbd () { echo -e "scale=2\n($(date --date "$1" +%s) - $(date --date "${2:-$(date)}" +%s))/60"|bc -l } /tmp $ echo 12/25/2009 ["$(date)"] 12/25/2009 [Tue Aug 25 15:23:05 CDT 2009] /tmp $ dbd 12/25/2009 "$(date)" 121.3 /tmp $ dbd 12/25/2009 121.3
-- Sun 23 Aug 2009 Tips on the versatile GNU date command: time zones, time zone conversions, scheduling 'at' jobs.. Ex date --date "$(date --date 'next month' '+%m/1/%Y') -1 day" # last day in month Ex echo rm -f /tmp/foo|at $(date -d "1am +3 weeks" '+%H:%M %D') # 'at' command likes above date output format Ex TZ=America/Chicago \ date -d \ "1970-01-01 UTC $(TZ=Asia/Calcutta date -d "Jun 8 7:20:06" '+%s') sec" The best way to understand the notes is to try the examples shown: http://trodman.com/cgi-bin/lualu?@3ywfmg -- Thu 20 Aug 2009 -- tar using ssh to remote host w/o pipes Ex /tmp $ ssh rodmant@hera date #hera is another linux box Thu Aug 20 08:12:45 CDT 2009 /tmp $ which ssh ssh is /usr/bin/ssh /tmp $ ssh rodmant@hera ls /tmp/bar.tar ls: cannot access /tmp/bar.tar: No such file or directory /tmp $ tar --rsh-command=/usr/bin/ssh -cf rodmant@hera:/tmp/bar.tar foo /tmp $ ssh rodmant@hera ls -l /tmp/bar.tar -rw-r--r-- 1 rodmant staff 10240 2009-08-20 08:15 /tmp/bar.tar /tmp $ tar --rsh-command=/usr/bin/ssh -tvf rodmant@hera:/tmp/bar.tar -rw-r--r-- rodmant/staff 3893 2009-08-20 08:10:58 foo Replace /tmp/bar.tar above w/remote host's tape drive. The --rsh-command= is supported by GNU tar; is documented in 'info tar'. -- Wed 19 Aug 2009 -- trivial m4 example Ex /tmp $ cat _date_here.m4 m4_divert(-1) above divert throws away all m4 output m4_define(_date_here,m4_esyscmd(date|tr -d \\n )) The 'tr -d \\n' is needed to remove the trailing new line. Notice xx_esyscmd macro is passing it's argument to the shell. xx_divert below restores m4 output to STDOUT. The trailing xx_dnl prevents an unwanted newline. m4_divert(0)m4_dnl /tmp $ cat foo.m4 hi/_date_here/ho bye /tmp $ m4 -P _date_here.m4 foo.m4 hi/Wed Aug 19 08:53:45 CDT 2009/ho bye -- 'info m4' snip (note that m4 quotes are *not* redefined tho): `-P' `--prefix-builtins' Internally modify *all* builtin macro names so they all start with the prefix `m4_'. For example, using this option, one should write `m4_define' instead of `define', and `m4___file__' instead of `__file__'. Tue 18 Aug 2009 -- revision control for UNIX config files One of the first tips I was given from a stern, elder UNIX system administrator over 20 years ago was to use SCCS revision control for all the config files on our SUN Sparc II workstations. I've long since switched to RCS, but have held myself to his rule to this day with no regrets. why version control for your system config files?: run rcsdiff on each change you make to double check your edits before 'committing' straightforward back outs you may add comments for each revision at check in you always have the original 'as shipped/out of the box' version use rlog and rcsdiff to show the changes as a history; as system problems arise you can look back at the time and date stamped change history and spot a correlation (if any) imp: you can write a script to locate and backup all your modified files based on a search for the ',v' RCS archive files. Typically this archive is amazingly small. once every year or two, some how, a file is deleted; no problem since you are using revison control This same approach works on Windows, under Cygwin, using RCS, provided that you're careful to write a wrapper around ci and co, so that the existing file permissions (and timestamps) do not have to be impacted by a check in. -- Sat 15 Aug 2009 -- 1 liners for analyzing ~full disk http://trodman.com/cgi-bin/lualu?@dae4e:di Fri 14 Aug 2009 a bit dry, and a couple of years old, still I plan to listen again, FSF lawyer Ebon Moglen on GPL2 and GPL3: http://twit.cachefly.net/FLOSS-013.mp3 Thu 13 Aug 2009 -- reverse command line args order in bash Works for args containing spaces. # temp var x & array y used (y must be unset or empty at start) if test $# -gt 0 then # reverse order of args for x do eval y=\(\"$x\"${y+\ \"\$\{y[@]\}\"}\) #prepend #$y apparently is 1st element in array done set "${y[@]}" unset y x fi #-- Ex ~ $ unset y ~ $ set hi "hello there" greetings "best regards" ~ $ for x > do > eval y=\(\"$x\"${y+\ \"\$\{y[@]\}\"}\) > done ~ $ ~ $ set "${y[@]}" ~ $ unset y x ~ $ for f;do echo "/$f/";done /best regards/ /greetings/ /hello there/ /hi/ Ex dumb but fun earlier attempt: ~ $ set fee fi fo fum ~ $ set $(rev <<<"$*") ~ $ echo $* muf of if eef ~ $ Ex $y vs ${y[0]}: ~ $ unset y; echo /$y/ // ~ $ y=("1st entry" "second array entry" last) ~ $ echo "/$y/" /1st entry/ ~ $ echo ${y[2]} last -- Mon 10 Aug 2009 -- linux recovery hardcopy notes I print this out in a tiny font and tape it near my monitor. It's intended to fit on 1 page - cryptic notes on what to do in an emergency, in single user mode when you have a corrupted file system, disk i/o errors, a boot problem or .. : http://trodman.com/cgi-bin/lualu?@e603d3:rv find bad soft links in a tree find . -type l |while read f;do test -e "$f" || echo $f;done # below CWD -- Sun 09 Aug 2009 -- my disk recovery tags www.connotea.org/user/zfyarpe/tag/ddrescue www.connotea.org/user/zfyarpe/tag/disk www.connotea.org/user/zfyarpe/tag/recovery www.connotea.org/user/zfyarpe/tag/backup www.connotea.org/user/zfyarpe/tag/mbr saving your delicious bookmarks to xml www.shell-fu.org/lister.php?id=843 Ex /tmp $ cygcheck -f /usr/bin/wget wget-1.11.4-3 /tmp $ wget --user=johndoe --no-check-certificate --password=XXXX https://api.del.icio.us/v1/posts/all -O bookmarks.xml &>/tmp/log /tmp $ ls -l bookmarks.xml /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 2395 Aug 9 11:55 /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 1138749 Aug 9 11:55 bookmarks.xml /tmp $ wc -l bookmarks.xml 3225 bookmarks.xml /tmp $ "bookmarks.xml" is one line per URL, it's easy to grep. Sat 08 Aug 2009 Apr 29 2009 Randal Schwartz "Dynamic Returns": www.cincomsmalltalk.com/audio/2009/industry%5Fmisinterpretations135.mp3 refering link: www.cincomsmalltalk.com/blog/b..ynamic_Returns&entry=3419405760 related: http://therning.org/magnus/archives/620 michaelgalloy.com/2009/05/14/r..z-talk-about-dynamic-languages.html -- Fri 07 Aug 2009 -- debugging interactive shell bash startup sequence Where was that alias, function or env var definition?: http://trodman.com/cgi-bin/lualu?@474e0:e To help debugging I add lines to the startup files as hinted: ~ $ head ~/.bashrc |grep login_seq : login_seq-starting: ~/.bashrc ~ $ tail ~/.bashrc |grep login_seq : login_seq-EOF ~/.bashrc ~ $ -- Is your shell interactive? Programmatic check. http://trodman.com/cgi-bin/lualu?@8cd98f:i #safe# two line prompt for system admin work Ever pasted your terminal clip board into a root shell session by mistake? After I paste a large number of lines, I try to nearly empty the clipboard, by putting a single space char into the clipboard (I use putty as a terminal). This prompt starts with a shell comment char '#', so it can limit the damage of an mistaken paste: /etc/local/team/mke/bash $ cat prompt # ==================================================================== # set up prompt # ==================================================================== case $USER in root)prompt_char='#' ;; *) prompt_char='$' ;; esac PS1="# \t \D{%a %y%m%d} \jj \l $$ \w\n# \h \u ${prompt_char} " # \t the current time in 24-hour HH:MM:SS format # \D see 'man bash|col -b|less +/strftime; man 3 strftime ## ' # \d the date in "Weekday Month Date" format (e.g.,"Tue May 26") # \j the number of jobs currently managed by the shell # \l the basename of the shell's terminal device name # $$ PID for current shell # \w the current working directory # \h the hostname up to the first `.' # \u the username of the current user /etc/local/team/mke/bash $ source prompt /etc/local/team/mke/bash $ -- Not sure what's in your clip board, or you want to "park it" somewhere? Here's an alias I use for that: alias _e='(stty -echo cbreak;cat)' Type '_e<enter>' then safely paste your terminal clipboard; ^C to get your prompt back. -- Tue 04 Aug 2009 Idiom for copying directories The trailing "/." is crucial: cp -af foo/. bar # Dir 'bar' will have same files and subdirs as dir 'foo'. # Does not matter if bar/ pre-exists. mnemonic- "slashdot" Ex /tmp $ mkdir -p foo/a/b/c/d /tmp $ ls bar ls: bar: No such file or directory /tmp $ command cp -a foo/. bar /tmp $ diff -qr foo bar; echo $? # no diffs 0 /tmp $ command cp -af foo/. bar # bar/ pre-exists, hence the -f /tmp $ diff -qr foo bar; echo $? 0 The -a preserves timestamps and permissions, the -f deals with preexisting destination files and dirs. Sun 02 Aug 2009 rounding idiom for bash: printf %.0f $YOURNUMBER Ex ~ $ printf "%.0f\n" 0.5 0 ~ $ printf "%.0f\n" 1.5 2 ~ $ printf "%.0f\n" 2.5 2 ~ $ printf "%.0f\n" 3.5 4 above is 'unbiased rounding' (evens down, odds up): www.gnu.org/manual/gawk/html_n../gawk/html_node/Round-Function.html -- manually validating a podcast link, before subscribing - ie checking for fresh mp3s: I made up a grep like bash function - a wrapper for wget: ~ $ which wgrep wgrep is a function wgrep () { : supports a global array 'wgrep_sw' used for egrep switches; local regex=$1; shift; local TMP=$(mktemp /tmp/$FUNCNAME.wget-out2.XXXXXXX); local site wget_stat; for site in "$@"; do if test -n "${wgrep_sw[*]:-}"; then wget -O - "$site" 2>$TMP | egrep "${wgrep_sw[@]}" "$regex"; wget_stat=${PIPESTATUS[0]}; else wget -O - "$site" 2>$TMP | egrep -i "$regex"; wget_stat=${PIPESTATUS[0]}; fi; if ! test "$wget_stat" = 0; then { echo -e "\nwget STDERR:"; sed -e 's~^~ ~' $TMP; echo } 1>&2; fi; done } example run: ~ $ wgrep 'pubdate|link.*mp3' http://leoville.tv/podcasts/floss.xml|head -3 <pubDate>Sat, 01 Aug 2009 15:11:30 -0400</pubDate> <link>http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-080.mp3</link> <pubDate>Sat, 01 Aug 2009 14:55:43 -0400</pubDate> -- Thu 30 Jul 2009 Ruby on Rails founder David Heinemeier interviewed by Randal Schwartz: http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-079.mp3 -- Sun 19 Jul 2009 notes on 'patch', patching a whole tree of scripts: http://trodman.com/cgi-bin/lualu?:@7a7b22:p -- Wed 15 Jul 2009 idioms for setting defaults in bash scripts, bash 'Parameter Expansion': http://trodman.com/cgi-bin/lualu?:parameter%20expansion bash startup notes: http://trodman.com/cgi-bin/lualu?:login%20sequence -- Mon 13 Jul 2009 GNU find examples (a work in progress): http://trodman.com/cgi-bin/lualu?@7boJHe:f -- Sat 11 Jul 2009 One way to check your backups is to re-read the entire tape file you just wrote, here are some recent test notes on Linux mt command: http://trodman.com/cgi-bin/lualu?@Se7Ysf:d -- Mon 06 Jul 2009 FLOSS interview on Arduino (open source hardware) www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-061.mp3 http://www.arduino.cc -- various Tom Rodman accounts Study and work related bookmarks: www.connotea.org/user/zfyarpe -- twitter: http://twitter.com/xriorb -- gtalk, and aim accounts - pls email me for them: www.trodman.com/cgi-bin/showTSRemail -- about www.trodman.com/blog Short notes on Linux and UNIX system administration, and scripting in bash and perl. Posts arise when I need to refer to my 15+ years of plain text notes - I have time for this now because I'm actively looking for a job. To help me find a job please share these links: resume for Tom Rodman: www.trodman.com/cv contact info: www.trodman.com Tom Rodman's blog: www.trodman.com/blog Thank-you!
Tips on the versatile GNU date command: time zones, time zone conversions, scheduling 'at' jobs..
Ex date --date "$(date --date 'next month' '+%m/1/%Y') -1 day" # last day in month Ex echo rm -f /tmp/foo|at $(date -d "1am +3 weeks" '+%H:%M %D') # 'at' command likes above date output format Ex TZ=America/Chicago \ date -d \ "1970-01-01 UTC $(TZ=Asia/Calcutta date -d "Jun 8 7:20:06" '+%s') sec"
The best way to understand the notes is to try the examples shown: http://trodman.com/cgi-bin/lualu?@3ywfmg
Ex /tmp $ ssh rodmant@hera date #hera is another linux box Thu Aug 20 08:12:45 CDT 2009 /tmp $ which ssh ssh is /usr/bin/ssh /tmp $ ssh rodmant@hera ls /tmp/bar.tar ls: cannot access /tmp/bar.tar: No such file or directory /tmp $ tar --rsh-command=/usr/bin/ssh -cf rodmant@hera:/tmp/bar.tar foo /tmp $ ssh rodmant@hera ls -l /tmp/bar.tar -rw-r--r-- 1 rodmant staff 10240 2009-08-20 08:15 /tmp/bar.tar /tmp $ tar --rsh-command=/usr/bin/ssh -tvf rodmant@hera:/tmp/bar.tar -rw-r--r-- rodmant/staff 3893 2009-08-20 08:10:58 foo
Replace /tmp/bar.tar above w/remote host's tape drive.
The --rsh-command= is supported by GNU tar; is documented in 'info tar'.
Ex /tmp $ cat _date_here.m4 m4_divert(-1) above divert throws away all m4 output m4_define(_date_here,m4_esyscmd(date|tr -d \\n )) The 'tr -d \\n' is needed to remove the trailing new line. Notice xx_esyscmd macro is passing it's argument to the shell. xx_divert below restores m4 output to STDOUT. The trailing xx_dnl prevents an unwanted newline. m4_divert(0)m4_dnl /tmp $ cat foo.m4 hi/_date_here/ho bye /tmp $ m4 -P _date_here.m4 foo.m4 hi/Wed Aug 19 08:53:45 CDT 2009/ho bye -- 'info m4' snip (note that m4 quotes are *not* redefined tho): `-P' `--prefix-builtins' Internally modify *all* builtin macro names so they all start with the prefix `m4_'. For example, using this option, one should write `m4_define' instead of `define', and `m4___file__' instead of `__file__'.
One of the first tips I was given from a stern, elder UNIX system administrator over 20 years ago was to use SCCS revision control for all the config files on our SUN Sparc II workstations. I've long since switched to RCS, but have held myself to his rule to this day with no regrets.
why version control for your system config files?:
This same approach works on Windows, under Cygwin, using RCS, provided that you're careful to write a wrapper around ci and co, so that the existing file permissions (and timestamps) do not have to be impacted by a check in.
http://trodman.com/cgi-bin/lualu?@dae4e:di
a bit dry, and a couple of years old, still I plan to listen again, FSF lawyer Ebon Moglen on GPL2 and GPL3: http://twit.cachefly.net/FLOSS-013.mp3
Works for args containing spaces.
# temp var x & array y used (y must be unset or empty at start) if test $# -gt 0 then # reverse order of args for x do eval y=\(\"$x\"${y+\ \"\$\{y[@]\}\"}\) #prepend #$y apparently is 1st element in array done set "${y[@]}" unset y x fi #-- Ex ~ $ unset y ~ $ set hi "hello there" greetings "best regards" ~ $ for x > do > eval y=\(\"$x\"${y+\ \"\$\{y[@]\}\"}\) > done ~ $ ~ $ set "${y[@]}" ~ $ unset y x ~ $ for f;do echo "/$f/";done /best regards/ /greetings/ /hello there/ /hi/ Ex dumb but fun earlier attempt: ~ $ set fee fi fo fum ~ $ set $(rev <<<"$*") ~ $ echo $* muf of if eef ~ $ Ex $y vs ${y[0]}: ~ $ unset y; echo /$y/ // ~ $ y=("1st entry" "second array entry" last) ~ $ echo "/$y/" /1st entry/ ~ $ echo ${y[2]} last
-- Mon 10 Aug 2009 -- linux recovery hardcopy notes I print this out in a tiny font and tape it near my monitor. It's intended to fit on 1 page - cryptic notes on what to do in an emergency, in single user mode when you have a corrupted file system, disk i/o errors, a boot problem or .. : http://trodman.com/cgi-bin/lualu?@e603d3:rv find bad soft links in a tree find . -type l |while read f;do test -e "$f" || echo $f;done # below CWD -- Sun 09 Aug 2009 -- my disk recovery tags www.connotea.org/user/zfyarpe/tag/ddrescue www.connotea.org/user/zfyarpe/tag/disk www.connotea.org/user/zfyarpe/tag/recovery www.connotea.org/user/zfyarpe/tag/backup www.connotea.org/user/zfyarpe/tag/mbr saving your delicious bookmarks to xml www.shell-fu.org/lister.php?id=843 Ex /tmp $ cygcheck -f /usr/bin/wget wget-1.11.4-3 /tmp $ wget --user=johndoe --no-check-certificate --password=XXXX https://api.del.icio.us/v1/posts/all -O bookmarks.xml &>/tmp/log /tmp $ ls -l bookmarks.xml /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 2395 Aug 9 11:55 /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 1138749 Aug 9 11:55 bookmarks.xml /tmp $ wc -l bookmarks.xml 3225 bookmarks.xml /tmp $ "bookmarks.xml" is one line per URL, it's easy to grep. Sat 08 Aug 2009 Apr 29 2009 Randal Schwartz "Dynamic Returns": www.cincomsmalltalk.com/audio/2009/industry%5Fmisinterpretations135.mp3 refering link: www.cincomsmalltalk.com/blog/b..ynamic_Returns&entry=3419405760 related: http://therning.org/magnus/archives/620 michaelgalloy.com/2009/05/14/r..z-talk-about-dynamic-languages.html -- Fri 07 Aug 2009 -- debugging interactive shell bash startup sequence Where was that alias, function or env var definition?: http://trodman.com/cgi-bin/lualu?@474e0:e To help debugging I add lines to the startup files as hinted: ~ $ head ~/.bashrc |grep login_seq : login_seq-starting: ~/.bashrc ~ $ tail ~/.bashrc |grep login_seq : login_seq-EOF ~/.bashrc ~ $ -- Is your shell interactive? Programmatic check. http://trodman.com/cgi-bin/lualu?@8cd98f:i #safe# two line prompt for system admin work Ever pasted your terminal clip board into a root shell session by mistake? After I paste a large number of lines, I try to nearly empty the clipboard, by putting a single space char into the clipboard (I use putty as a terminal). This prompt starts with a shell comment char '#', so it can limit the damage of an mistaken paste: /etc/local/team/mke/bash $ cat prompt # ==================================================================== # set up prompt # ==================================================================== case $USER in root)prompt_char='#' ;; *) prompt_char='$' ;; esac PS1="# \t \D{%a %y%m%d} \jj \l $$ \w\n# \h \u ${prompt_char} " # \t the current time in 24-hour HH:MM:SS format # \D see 'man bash|col -b|less +/strftime; man 3 strftime ## ' # \d the date in "Weekday Month Date" format (e.g.,"Tue May 26") # \j the number of jobs currently managed by the shell # \l the basename of the shell's terminal device name # $$ PID for current shell # \w the current working directory # \h the hostname up to the first `.' # \u the username of the current user /etc/local/team/mke/bash $ source prompt /etc/local/team/mke/bash $ -- Not sure what's in your clip board, or you want to "park it" somewhere? Here's an alias I use for that: alias _e='(stty -echo cbreak;cat)' Type '_e<enter>' then safely paste your terminal clipboard; ^C to get your prompt back. -- Tue 04 Aug 2009 Idiom for copying directories The trailing "/." is crucial: cp -af foo/. bar # Dir 'bar' will have same files and subdirs as dir 'foo'. # Does not matter if bar/ pre-exists. mnemonic- "slashdot" Ex /tmp $ mkdir -p foo/a/b/c/d /tmp $ ls bar ls: bar: No such file or directory /tmp $ command cp -a foo/. bar /tmp $ diff -qr foo bar; echo $? # no diffs 0 /tmp $ command cp -af foo/. bar # bar/ pre-exists, hence the -f /tmp $ diff -qr foo bar; echo $? 0 The -a preserves timestamps and permissions, the -f deals with preexisting destination files and dirs. Sun 02 Aug 2009 rounding idiom for bash: printf %.0f $YOURNUMBER Ex ~ $ printf "%.0f\n" 0.5 0 ~ $ printf "%.0f\n" 1.5 2 ~ $ printf "%.0f\n" 2.5 2 ~ $ printf "%.0f\n" 3.5 4 above is 'unbiased rounding' (evens down, odds up): www.gnu.org/manual/gawk/html_n../gawk/html_node/Round-Function.html -- manually validating a podcast link, before subscribing - ie checking for fresh mp3s: I made up a grep like bash function - a wrapper for wget: ~ $ which wgrep wgrep is a function wgrep () { : supports a global array 'wgrep_sw' used for egrep switches; local regex=$1; shift; local TMP=$(mktemp /tmp/$FUNCNAME.wget-out2.XXXXXXX); local site wget_stat; for site in "$@"; do if test -n "${wgrep_sw[*]:-}"; then wget -O - "$site" 2>$TMP | egrep "${wgrep_sw[@]}" "$regex"; wget_stat=${PIPESTATUS[0]}; else wget -O - "$site" 2>$TMP | egrep -i "$regex"; wget_stat=${PIPESTATUS[0]}; fi; if ! test "$wget_stat" = 0; then { echo -e "\nwget STDERR:"; sed -e 's~^~ ~' $TMP; echo } 1>&2; fi; done } example run: ~ $ wgrep 'pubdate|link.*mp3' http://leoville.tv/podcasts/floss.xml|head -3 <pubDate>Sat, 01 Aug 2009 15:11:30 -0400</pubDate> <link>http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-080.mp3</link> <pubDate>Sat, 01 Aug 2009 14:55:43 -0400</pubDate> -- Thu 30 Jul 2009 Ruby on Rails founder David Heinemeier interviewed by Randal Schwartz: http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-079.mp3 -- Sun 19 Jul 2009 notes on 'patch', patching a whole tree of scripts: http://trodman.com/cgi-bin/lualu?:@7a7b22:p -- Wed 15 Jul 2009 idioms for setting defaults in bash scripts, bash 'Parameter Expansion': http://trodman.com/cgi-bin/lualu?:parameter%20expansion bash startup notes: http://trodman.com/cgi-bin/lualu?:login%20sequence -- Mon 13 Jul 2009 GNU find examples (a work in progress): http://trodman.com/cgi-bin/lualu?@7boJHe:f -- Sat 11 Jul 2009 One way to check your backups is to re-read the entire tape file you just wrote, here are some recent test notes on Linux mt command: http://trodman.com/cgi-bin/lualu?@Se7Ysf:d -- Mon 06 Jul 2009 FLOSS interview on Arduino (open source hardware) www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-061.mp3 http://www.arduino.cc -- various Tom Rodman accounts Study and work related bookmarks: www.connotea.org/user/zfyarpe -- twitter: http://twitter.com/xriorb -- gtalk, and aim accounts - pls email me for them: www.trodman.com/cgi-bin/showTSRemail -- about www.trodman.com/blog Short notes on Linux and UNIX system administration, and scripting in bash and perl. Posts arise when I need to refer to my 15+ years of plain text notes - I have time for this now because I'm actively looking for a job. To help me find a job please share these links: resume for Tom Rodman: www.trodman.com/cv contact info: www.trodman.com Tom Rodman's blog: www.trodman.com/blog Thank-you!
I print this out in a tiny font and tape it near my monitor. It's intended to fit on 1 page - cryptic notes on what to do in an emergency, in single user mode when you have a corrupted file system, disk i/o errors, a boot problem or .. : http://trodman.com/cgi-bin/lualu?@e603d3:rv
find . -type l |while read f;do test -e "$f" || echo $f;done # below CWD
www.shell-fu.org/lister.php?id=843
Ex
/tmp $ cygcheck -f /usr/bin/wget wget-1.11.4-3 /tmp $ wget --user=johndoe --no-check-certificate --password=XXXX https://api.del.icio.us/v1/posts/all -O bookmarks.xml &>/tmp/log /tmp $ ls -l bookmarks.xml /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 2395 Aug 9 11:55 /tmp/log -rw-rw-r-- 1 adm_tsr 7rq_staff 1138749 Aug 9 11:55 bookmarks.xml /tmp $ wc -l bookmarks.xml 3225 bookmarks.xml /tmp $
"bookmarks.xml" is one line per URL, it's easy to grep.
Apr 29 2009 Randal Schwartz "Dynamic Returns": www.cincomsmalltalk.com/audio/2009/industry%5Fmisinterpretations135.mp3
-- Fri 07 Aug 2009 -- debugging interactive shell bash startup sequence Where was that alias, function or env var definition?: http://trodman.com/cgi-bin/lualu?@474e0:e To help debugging I add lines to the startup files as hinted: ~ $ head ~/.bashrc |grep login_seq : login_seq-starting: ~/.bashrc ~ $ tail ~/.bashrc |grep login_seq : login_seq-EOF ~/.bashrc ~ $ -- Is your shell interactive? Programmatic check. http://trodman.com/cgi-bin/lualu?@8cd98f:i #safe# two line prompt for system admin work Ever pasted your terminal clip board into a root shell session by mistake? After I paste a large number of lines, I try to nearly empty the clipboard, by putting a single space char into the clipboard (I use putty as a terminal). This prompt starts with a shell comment char '#', so it can limit the damage of an mistaken paste: /etc/local/team/mke/bash $ cat prompt # ==================================================================== # set up prompt # ==================================================================== case $USER in root)prompt_char='#' ;; *) prompt_char='$' ;; esac PS1="# \t \D{%a %y%m%d} \jj \l $$ \w\n# \h \u ${prompt_char} " # \t the current time in 24-hour HH:MM:SS format # \D see 'man bash|col -b|less +/strftime; man 3 strftime ## ' # \d the date in "Weekday Month Date" format (e.g.,"Tue May 26") # \j the number of jobs currently managed by the shell # \l the basename of the shell's terminal device name # $$ PID for current shell # \w the current working directory # \h the hostname up to the first `.' # \u the username of the current user /etc/local/team/mke/bash $ source prompt /etc/local/team/mke/bash $ -- Not sure what's in your clip board, or you want to "park it" somewhere? Here's an alias I use for that: alias _e='(stty -echo cbreak;cat)' Type '_e<enter>' then safely paste your terminal clipboard; ^C to get your prompt back. -- Tue 04 Aug 2009 Idiom for copying directories The trailing "/." is crucial: cp -af foo/. bar # Dir 'bar' will have same files and subdirs as dir 'foo'. # Does not matter if bar/ pre-exists. mnemonic- "slashdot" Ex /tmp $ mkdir -p foo/a/b/c/d /tmp $ ls bar ls: bar: No such file or directory /tmp $ command cp -a foo/. bar /tmp $ diff -qr foo bar; echo $? # no diffs 0 /tmp $ command cp -af foo/. bar # bar/ pre-exists, hence the -f /tmp $ diff -qr foo bar; echo $? 0 The -a preserves timestamps and permissions, the -f deals with preexisting destination files and dirs. Sun 02 Aug 2009 rounding idiom for bash: printf %.0f $YOURNUMBER Ex ~ $ printf "%.0f\n" 0.5 0 ~ $ printf "%.0f\n" 1.5 2 ~ $ printf "%.0f\n" 2.5 2 ~ $ printf "%.0f\n" 3.5 4 above is 'unbiased rounding' (evens down, odds up): www.gnu.org/manual/gawk/html_n../gawk/html_node/Round-Function.html -- manually validating a podcast link, before subscribing - ie checking for fresh mp3s: I made up a grep like bash function - a wrapper for wget: ~ $ which wgrep wgrep is a function wgrep () { : supports a global array 'wgrep_sw' used for egrep switches; local regex=$1; shift; local TMP=$(mktemp /tmp/$FUNCNAME.wget-out2.XXXXXXX); local site wget_stat; for site in "$@"; do if test -n "${wgrep_sw[*]:-}"; then wget -O - "$site" 2>$TMP | egrep "${wgrep_sw[@]}" "$regex"; wget_stat=${PIPESTATUS[0]}; else wget -O - "$site" 2>$TMP | egrep -i "$regex"; wget_stat=${PIPESTATUS[0]}; fi; if ! test "$wget_stat" = 0; then { echo -e "\nwget STDERR:"; sed -e 's~^~ ~' $TMP; echo } 1>&2; fi; done } example run: ~ $ wgrep 'pubdate|link.*mp3' http://leoville.tv/podcasts/floss.xml|head -3 <pubDate>Sat, 01 Aug 2009 15:11:30 -0400</pubDate> <link>http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-080.mp3</link> <pubDate>Sat, 01 Aug 2009 14:55:43 -0400</pubDate> -- Thu 30 Jul 2009 Ruby on Rails founder David Heinemeier interviewed by Randal Schwartz: http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-079.mp3 -- Sun 19 Jul 2009 notes on 'patch', patching a whole tree of scripts: http://trodman.com/cgi-bin/lualu?:@7a7b22:p -- Wed 15 Jul 2009 idioms for setting defaults in bash scripts, bash 'Parameter Expansion': http://trodman.com/cgi-bin/lualu?:parameter%20expansion bash startup notes: http://trodman.com/cgi-bin/lualu?:login%20sequence -- Mon 13 Jul 2009 GNU find examples (a work in progress): http://trodman.com/cgi-bin/lualu?@7boJHe:f -- Sat 11 Jul 2009 One way to check your backups is to re-read the entire tape file you just wrote, here are some recent test notes on Linux mt command: http://trodman.com/cgi-bin/lualu?@Se7Ysf:d -- Mon 06 Jul 2009 FLOSS interview on Arduino (open source hardware) www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-061.mp3 http://www.arduino.cc -- various Tom Rodman accounts Study and work related bookmarks: www.connotea.org/user/zfyarpe -- twitter: http://twitter.com/xriorb -- gtalk, and aim accounts - pls email me for them: www.trodman.com/cgi-bin/showTSRemail -- about www.trodman.com/blog Short notes on Linux and UNIX system administration, and scripting in bash and perl. Posts arise when I need to refer to my 15+ years of plain text notes - I have time for this now because I'm actively looking for a job. To help me find a job please share these links: resume for Tom Rodman: www.trodman.com/cv contact info: www.trodman.com Tom Rodman's blog: www.trodman.com/blog Thank-you!
Where was that alias, function or env var definition?: http://trodman.com/cgi-bin/lualu?@474e0:e
To help debugging I add lines to the startup files as hinted:
~ $ head ~/.bashrc |grep login_seq : login_seq-starting: ~/.bashrc ~ $ tail ~/.bashrc |grep login_seq : login_seq-EOF ~/.bashrc ~ $
http://trodman.com/cgi-bin/lualu?@8cd98f:i
Ever pasted your terminal clip board into a root shell session by mistake? After I paste a large number of lines, I try to nearly empty the clipboard, by putting a single space char into the clipboard (I use putty as a terminal).
This prompt starts with a shell comment char '#', so it can limit the damage of an mistaken paste:
/etc/local/team/mke/bash $ cat prompt # ==================================================================== # set up prompt # ==================================================================== case $USER in root)prompt_char='#' ;; *) prompt_char='$' ;; esac PS1="# \t \D{%a %y%m%d} \jj \l $$ \w\n# \h \u ${prompt_char} " # \t the current time in 24-hour HH:MM:SS format # \D see 'man bash|col -b|less +/strftime; man 3 strftime ## ' # \d the date in "Weekday Month Date" format (e.g.,"Tue May 26") # \j the number of jobs currently managed by the shell # \l the basename of the shell's terminal device name # $$ PID for current shell # \w the current working directory # \h the hostname up to the first `.' # \u the username of the current user /etc/local/team/mke/bash $ source prompt /etc/local/team/mke/bash $
Not sure what's in your clip board, or you want to "park it" somewhere? Here's an alias I use for that:
alias _e='(stty -echo cbreak;cat)'
Type '_e<enter>' then safely paste your terminal clipboard; ^C to get your prompt back.
The trailing "/." is crucial:
cp -af foo/. bar # Dir 'bar' will have same files and subdirs as dir 'foo'. # Does not matter if bar/ pre-exists. mnemonic- "slashdot" Ex /tmp $ mkdir -p foo/a/b/c/d /tmp $ ls bar ls: bar: No such file or directory /tmp $ command cp -a foo/. bar /tmp $ diff -qr foo bar; echo $? # no diffs 0 /tmp $ command cp -af foo/. bar # bar/ pre-exists, hence the -f /tmp $ diff -qr foo bar; echo $? 0
The -a preserves timestamps and permissions, the -f deals with preexisting destination files and dirs.
rounding idiom for bash:
printf %.0f $YOURNUMBER
Ex ~ $ printf "%.0f\n" 0.5 0 ~ $ printf "%.0f\n" 1.5 2 ~ $ printf "%.0f\n" 2.5 2 ~ $ printf "%.0f\n" 3.5 4
above is 'unbiased rounding' (evens down, odds up): www.gnu.org/manual/gawk/html_n../gawk/html_node/Round-Function.html
manually validating a podcast link, before subscribing - ie checking for fresh mp3s:
I made up a grep like bash function - a wrapper for wget:
~ $ which wgrep wgrep is a function wgrep () { : supports a global array 'wgrep_sw' used for egrep switches; local regex=$1; shift; local TMP=$(mktemp /tmp/$FUNCNAME.wget-out2.XXXXXXX); local site wget_stat; for site in "$@"; do if test -n "${wgrep_sw[*]:-}"; then wget -O - "$site" 2>$TMP | egrep "${wgrep_sw[@]}" "$regex"; wget_stat=${PIPESTATUS[0]}; else wget -O - "$site" 2>$TMP | egrep -i "$regex"; wget_stat=${PIPESTATUS[0]}; fi; if ! test "$wget_stat" = 0; then { echo -e "\nwget STDERR:"; sed -e 's~^~ ~' $TMP; echo } 1>&2; fi; done }
example run:
~ $ wgrep 'pubdate|link.*mp3' http://leoville.tv/podcasts/floss.xml|head -3 <pubDate>Sat, 01 Aug 2009 15:11:30 -0400</pubDate> <link>http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-080.mp3</link> <pubDate>Sat, 01 Aug 2009 14:55:43 -0400</pubDate>
Ruby on Rails founder David Heinemeier interviewed by Randal Schwartz: http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-079.mp3
notes on 'patch', patching a whole tree of scripts: http://trodman.com/cgi-bin/lualu?:@7a7b22:p
idioms for setting defaults in bash scripts, bash 'Parameter Expansion':
bash startup notes:
-- Mon 13 Jul 2009 GNU find examples (a work in progress): http://trodman.com/cgi-bin/lualu?@7boJHe:f -- Sat 11 Jul 2009 One way to check your backups is to re-read the entire tape file you just wrote, here are some recent test notes on Linux mt command: http://trodman.com/cgi-bin/lualu?@Se7Ysf:d -- Mon 06 Jul 2009 FLOSS interview on Arduino (open source hardware) www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-061.mp3 http://www.arduino.cc -- various Tom Rodman accounts Study and work related bookmarks: www.connotea.org/user/zfyarpe -- twitter: http://twitter.com/xriorb -- gtalk, and aim accounts - pls email me for them: www.trodman.com/cgi-bin/showTSRemail -- about www.trodman.com/blog Short notes on Linux and UNIX system administration, and scripting in bash and perl. Posts arise when I need to refer to my 15+ years of plain text notes - I have time for this now because I'm actively looking for a job. To help me find a job please share these links: resume for Tom Rodman: www.trodman.com/cv contact info: www.trodman.com Tom Rodman's blog: www.trodman.com/blog Thank-you!
GNU find examples (a work in progress): http://trodman.com/cgi-bin/lualu?@7boJHe:f
One way to check your backups is to re-read the entire tape file you just wrote, here are some recent test notes on Linux mt command:
FLOSS interview on Arduino (open source hardware) www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/FLOSS-061.mp3
Study and work related bookmarks:
-- twitter:
-- gtalk, and aim accounts - pls email me for them:
www.trodman.com/cgi-bin/showTSRemail
-- about www.trodman.com/blog Short notes on Linux and UNIX system administration, and scripting in bash and perl. Posts arise when I need to refer to my 15+ years of plain text notes - I have time for this now because I'm actively looking for a job. To help me find a job please share these links: resume for Tom Rodman: www.trodman.com/cv contact info: www.trodman.com Tom Rodman's blog: www.trodman.com/blog Thank-you!
Short notes on Linux and UNIX system administration, and scripting in bash and perl. Posts arise when I need to refer to my 15+ years of plain text notes - I have time for this now because I'm actively looking for a job.
To help me find a job please share these links:
Thank-you!