Created
January 31, 2016 19:28
-
-
Save illucent/50dc51fd48d55f9ebb05 to your computer and use it in GitHub Desktop.
Bash Utilities
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| (( 0 )) && { # | |
| echo | |
| } | |
| (( 1 )) && { # | |
| # Something of a shot in the dark, but when we had a server with a high | |
| # load average where nothing obvious was causing it, it turned out to be | |
| # multiple df cmds hanging on a stale nfs mount. This command helped us id it: | |
| top -b -n 1 | awk | |
| ' | |
| { if (NR <=7) print; else if ($8 == "D") {print; count++} } | |
| END | |
| {print "Total status D: "count} | |
| ' | |
| } | |
| (( 0 )) && { # entropy stats. WHOLE NUMBERS ONLY | |
| for F in /data/ja/logs/entropy.black | |
| do | |
| TALLY=$(cat ${F} |wc -l) | |
| echo "Tally of entries: ${TALLY}" | |
| CUM=0 | |
| SUM=$(cut -d' ' -f10 ${F} |while read N; do CUM=$((CUM + N)); echo $CUM; done |tail -n 1) | |
| echo "Sum of entries: ${SUM}" | |
| AVG=$((SUM / TALLY)) | |
| echo "Average of entries: ${AVG}" | |
| # just use the values | |
| G=${F}.values | |
| cut -d' ' -f10 ${F} > ${G} | |
| # Standard Deviation | |
| while read N | |
| do | |
| DIFF=$((AVG - N)) # difference between mean and data point | |
| DIFSQ=$((DIFF * DIFF)) # DIFF squared. | |
| SUM2=$((SUM2 + DIFSQ)) # sum of squares. | |
| done < ${G} | |
| AVG2=$((SUM2 / TALLY)) # average of sum of squares. | |
| SDEV=$(echo "scale=3; sqrt($AVG2)" |bc) | |
| echo "Standard Deviation: $SDEV" | |
| done | |
| } | |
| (( 0 )) && { # simulate typing the text in a file. | |
| SLEEP=0.05 | |
| head -n 7 /data/ja/temp/spread/free_exchange.txt |while read LINE | |
| do | |
| #echo "$L" | |
| LEN=${#LINE} # length of line | |
| LEN=$((LEN - 1)) # the substring command is zero-based. | |
| for N in $(seq 0 $LEN) | |
| do | |
| echo -n "${LINE:$N:1}" # substring starting at $N of lenght 1. $N is zero-based. | |
| sleep ${SLEEP} | |
| done | |
| echo | |
| done | |
| } | |
| (( 0 )) && { # identify credit card payment for the last 120 days. Useful for new credit card number. | |
| # Sign-on to usaa site; goto credit card page; select 'last 120 days'; copy-paste data to new text document. | |
| # eg F=/data/ja/temp/spread/usaa.last.120.txt | |
| cd /data/ja/temp/spread/ | |
| sort usaa.last.120.txt |uniq |grep '^[A-Z][A-Z]' |grep -Ev '^PAYMENT|^PENDING' > usaa.1 | |
| # usaa.1 will contain 1-time charges and recurring charges. there may be minor duplicates in usaa.1 | |
| # tentatively, the following are recurring: | |
| # | |
| # AT&T *436097291116 08003310500 GA | |
| # AT&T*BILL PAYMENT 08003310500 TX | |
| # CLARK PEST CONTROL 209-3687152 CA | |
| # NETFLIX.COM NETFLIX.COM CA | |
| # WWW.1AND1.COM TEL8774612631PA | |
| } | |
| (( 0 )) && { # create an md5sum for the files in a dir. ? detect bit-rot | |
| find -type f -not -name md5sum.txt -print0 \ | |
| |xargs -0 md5sum \ | |
| >> md5sum.txt | |
| } | |
| (( 0 )) && { # get disk info by path, uuid, id, | |
| for P in path uuid id | |
| do | |
| ls -l /dev/disk/by-$P/ |sed -e 's;^total.*; ;' | |
| done | |
| } | |
| (( 0 )) && { # which services do NOT have a lock file? | |
| # look in each init script for a line like: ^LOCK /var/lock/subsys. | |
| # if not found, then the script does not manage lock files. Bad script, bad script. | |
| for i in /etc/init.d/* | |
| do | |
| grep -q /var/lock/subsys $i || echo "$i@Does not manage lock files." | |
| done |column -ts@ # nice formatting! | |
| } | |
| (( 0 )) && { # parse config.rh6.functions. use an array to hold line numbers of functions. | |
| # NB: this avoids the use of 'while read' which removes spaces, tabs, etc. | |
| # this requires a manual edit of config.rh6.functions.sh to remove all except the functions. | |
| cd /data/ja/bin/config/rh6 | |
| F=l.config.just.functions | |
| [ ! -f $F ] && echo "Not a file: $F" && return | |
| TALLY=$(wc -l $F |cut -d' ' -f1) | |
| ARR=( $(cat -n $F |grep '(){' |tr -s ' ' |sed -e 's;^ ;;' -e 's;\t.*;;') ) # store the line numbers as an array. | |
| LAST=$(( ${#ARR[@]} - 1)) | |
| for i in $(seq 0 ${LAST}) | |
| #for i in $(seq 0 2) | |
| do | |
| #echo "${ARR[$i]}" | |
| DIF=$((${ARR[$i+1]} - ${ARR[$i]})) # Line number diffs between consecutive functions | |
| [ $DIF -lt 0 ] && TT=$((TALLY - ${ARR[$i]})) # ${ARR[$i+1]} does not exist. => zero => dif is negative. so, redo dif. | |
| [ $DIF -gt 0 ] && TT=$DIF # there is a function body, => dif is positive. | |
| #echo "${ARR[$i]} $TT" # qc print: line-number of function, number of lines in the function. | |
| tail -n +${ARR[$i]} $F |head -n $TT > ttt # extract the function to temp file. | |
| FN=$(head -n 1 ttt |sed -e 's;..{.*;;') # grab the function name | |
| ( | |
| echo '#!/bin/bash' | |
| echo | |
| cat ttt |sed -e 's;^.*(){;do_it(){;' # replace function name with do_it | |
| echo | |
| echo 'do_it' # call do_it | |
| echo 'exit 0' | |
| echo "# Previously this code was function $FN in config.rh6.functions" | |
| echo | |
| ) > $FN | |
| done | |
| [ -f ttt ] && rm ttt | |
| } | |
| (( 0 )) && { # get info from a CD or DVD. | |
| blocksize=` isoinfo -d -i /dev/sr0 | grep "^Logical block size is:" | cut -d " " -f 5` | |
| blockcount=`isoinfo -d -i /dev/sr0 | grep "^Volume size is:" | cut -d " " -f 4` | |
| echo " Blocksize: $blocksize" | |
| echo " Blockcount: $blockcount" | |
| } | |
| (( 0 )) && { # process a file with spaces in some lines. | |
| T=/data/ja/temp/TTT | |
| echo -e "Line_one\nLine two\nLine_three\nLine four" > "${T}" | |
| while read L; do echo "${L}"; done < "${T}" # works. | |
| } | |
| (( 0 )) && { # show progress within the 'less' pager. see 1 below. | |
| VISUAL=0 # provide visual feedback to screen. | |
| for N in {0..202} | |
| do | |
| VISUAL=$((VISUAL + 1)) | |
| [ $((VISUAL % 20)) -eq 0 ] && printf "Count: %3d\n" "$VISUAL" | |
| done | |
| printf "Count: %3d\n" "$VISUAL" | |
| } | |
| (( 0 )) && { # show progress at the cli. NB: using 'less' will not work. | |
| echo -n ' ' # 3 spaces | |
| for N in {0..11} | |
| do | |
| printf "\b\b\b%d" "$N" | |
| sleep 1 | |
| done | |
| } | |
| (( 0 )) && { # sort on character position. Use fixed width, with WITH spaces. | |
| T=$(mktemp /tmp/sorting.XXXXXXXXXX) | |
| cat > $T <<-ENDOFSORTLIST; | |
| 1134 0 1250 | |
| 1233 0 1240 | |
| 1332 0 1230 | |
| 1431 0 1220 | |
| 1530 0 1210 | |
| 1124 0 0160 | |
| 1223 0 0150 | |
| 1322 0 0140 | |
| 1421 0 0130 | |
| 1520 0 0120 | |
| ENDOFSORTLIST | |
| echo -e "\n===== Numeric sort" | |
| sort -n $T | |
| echo -e "\n===== Numeric sort on positions 3-4" | |
| sort -n -k1.3,1.4 $T # works. | |
| echo -e "\n===== Numeric sort on positions 1-2" | |
| sort -n -k1.1,1.2 $T | |
| echo -e "\n===== Numeric sort on positions 1-2 and 9-10" | |
| sort -k1.1,1.2n -k3.3,3.4n $T # does not work. | |
| echo -e "\n===== Numeric sort on field 1, 1-2 and field 3, 3-4" | |
| sort -t' ' -k1.1,1.2n -k3.3,3.4n $T # Works. Note -t is a space. | |
| echo -e "\n===== Numeric sort on positions 1-2 and 10-11" | |
| sort -t \& -k1.1,1.2n -k1.10,1.11n $T # Works. Note -t is a ampersand. | |
| } | |
| (( 0 )) && { # sort on character position. Use fixed width, with NO spaces. | |
| T=$(mktemp /tmp/sorting.XXXXXXXXXX) | |
| cat > $T <<-ENDOFSORTLIST; | |
| 113401250 | |
| 123301240 | |
| 133201230 | |
| 143101220 | |
| 153001210 | |
| 112400160 | |
| 122300150 | |
| 132200140 | |
| 142100130 | |
| 152000120 | |
| ENDOFSORTLIST | |
| echo -e "\n===== Numeric sort" | |
| sort -n $T | |
| echo -e "\n===== Numeric sort on positions 3-4" # Works | |
| sort -n -k1.3,1.4 $T | |
| echo -e "\n===== Numeric sort on positions 1-2" | |
| sort -n -k1.1,1.2 $T | |
| echo -e "\n===== Numeric sort on positions 1-2 and 8-9" # Works. | |
| sort -k1.1,1.2n -k1.8,1.9n $T | |
| # NB: the above data is ALL ONE FIELD. So, use 1.1, 1.2, 1.8, 1.9 with a numeric for each sort key. | |
| } | |
| (( 0 )) && { # have a delay. | |
| # sleep delay-in-seconds. | |
| echo $(($(date +%S)*3)) # seconds x 3. 0 thru 177 seconds. | |
| # | |
| echo $(($RANDOM % 45)) # 0 thru 44. | |
| } | |
| (( 0 )) && { # Delete control characters in a file. | |
| # from: https://snipt.net/rqsall/delete-control-characters-in-a-file/ | |
| tr -cd '[:print:]\n' < filename > newfile | |
| # Thanks to "command line magic" on twitter, follow 'im. | |
| } | |
| (( 0 )) && { # install or update calibre. does NOT use Distribution update mechanism. | |
| echo | |
| # get prompted for the install dir. | |
| #python -c "import sys; py3 = sys.version_info[0] > 2; u = __import__('urllib.request' if py3 else 'urllib', fromlist=1); exec(u.urlopen('http://status.calibre-ebook.com/linux_installer').read()); main()" | |
| # specify the /opt dir: | |
| # python -c "import sys; py3 = sys.version_info[0] > 2; u = __import__('urllib.request' if py3 else 'urllib', fromlist=1); exec(u.urlopen('http://status.calibre-ebook.com/linux_installer').read()); main(install_dir='/opt')" | |
| } | |
| (( 0 )) && { # Is a drive USB? | |
| for DEV in ls /dev/sd[a-z] | |
| do | |
| echo | |
| echo $D | |
| udevadm info --query=all --name=$D |grep BUS=; | |
| done | |
| } | |
| (( 0 )) && { # reserved space in file system. | |
| RBC=$(tune2fs -l /dev/sdb1 |grep '^Reserved block count' |awk '{print $4}') | |
| BC=$( tune2fs -l /dev/sdb1 |grep '^Block count' |awk '{print $3}') | |
| echo $RBC/$BC |bc -l |xargs printf "%1.2f\n" | |
| # prints: 0.05 | |
| # ie: 5% | |
| } | |
| (( 0 )) && { # Notes on locate and its configs. | |
| # /etc/cron.daily/mlocate.cron gets a list of 'nodevs': nodevs=$(< /proc/filesystems awk '$1 == "nodev" { print $2 }') | |
| # on CentOS 6.3 there are 26 items in the list, including devtmpfs. | |
| # /etc/updatedb.conf has 4 variables that specify different ways to prune the 'locate' process. | |
| # the PRUNEFS variable contains 'nodev' name, like nfs or nfs4 or tmpfs; a total of 46 items. | |
| # some items are on both lists, eg: tmpfs proc nfsd fuse | |
| # some items are on only 1 list, eg: nfs4, nfs, iso9660, ecryptfs, ... | |
| # those singletons come from both lists, so, both lists are needed to fully specify the exclussions. | |
| echo | |
| } | |
| (( 0 )) && { # from http://www.catonmat.net/blog/tcp-port-scanner-in-bash/ | |
| scan() { | |
| if [[ -z $1 || -z $2 ]]; | |
| then | |
| echo "Usage: $0 <host> <port, ports, and/or port-range>" | |
| return | |
| fi | |
| host=$1 | |
| ports=() | |
| case $2 in | |
| *-*) IFS=- read start end <<< "$2" # This might be useful. | |
| for ((port=start; port <= end; port++)); | |
| do | |
| ports+=($port) | |
| done | |
| ;; | |
| *,*) IFS=, read -ra ports <<< "$2" # Ditto. | |
| ;; | |
| *) ports+=($2) | |
| ;; | |
| esac | |
| # NB, peter uses /dev/tcp which is not available on CentOS | |
| for port in "${ports[@]}"; do | |
| alarm 1 "echo >/dev/tcp/$host/$port && echo \"port $port is open\"" || echo "port $port is closed" | |
| done | |
| } | |
| } | |
| (( 0 )) && { # Monitor network connections. Assumes raw data file exists. | |
| # Raw data file generated: | |
| # eg: date ; time for X in {1..7200} ; do ss -apt >> raw.N ; sleep 1; done | |
| # or: date ; time for X in {1..7200} ; do netstat -tp >> raw.N ; sleep 1; done | |
| DIR=/data/ja/logs/ss | |
| REV=4 | |
| RAW=${DIR}/raw.${REV} | |
| LOCAL=${DIR}/local_addresses.${REV} # Local IP address | |
| REMOTE=${DIR}/remote_addresses.${REV} # Remote IP addresses | |
| GROOMED=${DIR}/groomed.${REV} | |
| EXCLUDE=${DIR}/exclude.${REV} # Exclude these remote ip address, since this are known local processes. | |
| > ${EXCLUDE} # truncate $EXCLUDE | |
| egrep -v 'LISTEN|^State|:ssh|:nfs' "${RAW}" |uniq |awk '{print $5}' |cut -d: -f1 |sort |uniq > ${REMOTE} | |
| echo | |
| echo "There are $(cat ${REMOTE} |wc -l) remote ip addresses." | |
| # for each remote address, look at unique connections. | |
| #cat ${REMOTE} |while read IP; do echo; echo $IP; host $IP; grep $IP "${RAW}" |sort |uniq ; done | |
| # this would let me filter out some remove IPs | |
| # Or, change column order: 1,2,3,4,5,6 --> 4,5,6,1,2,3 and then sort on local ip address. | |
| cat ${REMOTE} |while read IP; | |
| do | |
| echo; | |
| echo $IP; | |
| host $IP; | |
| grep $IP "${RAW}" |awk '{print $4 " " $5 " " $6 " " $1 " " $2 " " $3}' |sed -e 's;^192.168.1.20:;;' |sort |uniq > ${GROOMED} | |
| N=$(cat ${GROOMED} |wc -l) | |
| echo "There are $N instances of this remote ip address in ${RAW}:" | |
| cat ${GROOMED} | |
| # Can this remote ip address be excluded? | |
| #grep -q 'check_access.pl' ${GROOMED} && case $N in | |
| case $N in | |
| 1) grep -q 'check_access.pl' ${GROOMED} && echo $IP >> ${EXCLUDE} | |
| ;; | |
| 2) # if both instances have check_access.pl, then add $IP to exclude list. | |
| [ $(grep -c 'check_access.pl' ${GROOMED}) -eq 2 ] && echo $IP >> ${EXCLUDE} | |
| # if only one instance has check_access, AND the local port numbers are consecutive, then add $IP to exclude list. | |
| PORT1=$(head -n 1 ${GROOMED} |cut -d' ' -f1) | |
| PORT2=$(tail -n 1 ${GROOMED} |cut -d' ' -f1) | |
| echo "Port 1: ${PORT1}" | |
| echo "Port 2: ${PORT2}" | |
| DIF=$((PORT2 - PORT1)) | |
| [ $(grep -c 'check_access.pl' ${GROOMED}) -eq 1 ] && [ ${DIF} -eq 1 ] && echo $IP >> ${EXCLUDE} | |
| ;; | |
| *) # if any of these instances match 'clock-applet' then exclude this remote ip address. | |
| echo "clock" | |
| grep clock-applet ${GROOMED} | |
| echo "clock 2" | |
| grep -q clock-applet ${GROOMED} && echo $IP >> ${EXCLUDE} | |
| ;; | |
| esac | |
| echo "Exclude these remote ip addresses:" | |
| cat ${EXCLUDE} | |
| done | |
| } | |
| (( 0 )) && { # Put a message at the top of a file, then save to another filename. | |
| cat - "$repo" > "$repo".disabled <<EOF | |
| # This is a yum repository file that was disabled by | |
| # ${0##*/}, a script to convert CentOS to Oracle Linux. | |
| # Please see $yum_url for more information. | |
| EOF | |
| # Or, for a short msg: | |
| echo "Whatever" |cat - $somefile > $somefile.new.version | |
| } | |
| (( 0 )) && { # Heading above the results of: /usr/bin/diff --side-by-side --width 160 | |
| OLD=/data/ja/temp/etc.sysctl.conf.1 | |
| NEW=/data/ja/temp/etc.sysctl.conf.2 | |
| for n in $(seq 1 ${#OLD}); do EQOLD="${EQOLD}="; done | |
| for n in $(seq 1 ${#NEW}); do EQNEW="${EQNEW}="; done | |
| WIDTH=160 | |
| HALF=$((WIDTH / 2)) | |
| printf "%-${HALF}s%-${HALF}s\n" "${OLD}" "${NEW}" | |
| printf "%-${HALF}s%-${HALF}s\n" "${EQOLD}" "${EQNEW}" | |
| /usr/bin/diff --side-by-side --width ${WIDTH} ${OLD} ${NEW} | |
| } | |
| (( 0 )) && { # Where are the biggest increases in Raw Read Error Rate ? | |
| # Use raw data, before grooming. | |
| # This has 5 minute intervals, so it may not seem to corrolate with the line chart, which used 1 houe intervals. | |
| F=/data/ja/logs/smart.oman.raw.read.error.rate | |
| T=/tmp/T | |
| grep -v ^# $F |uniq > $T # remove comments | |
| PrevRaw=$(head -n 1 $T |cut -d' ' -f3) # start with Prev equal to first Raw. | |
| #echo "PrevRaw: $PrevRaw" | |
| while read DATE SSE RAW | |
| do | |
| echo "$((RAW - PrevRaw)) $DATE $SSE $RAW" | |
| PrevRaw=$RAW | |
| done < $T |sort -rn |head -n 23 # the top 23 are GT 10m, FOR NOW. | |
| } | |
| (( 0 )) && { # sar. system accounting reporter. | |
| # Thanks: http://www.thegeekstuff.com/2011/03/sar-examples/ | |
| # cpu usage. | |
| sar -u # Displays CPU usage for the current day that was collected until that point. | |
| sar -u 1 3 # Displays real time CPU usage every 1 second for 3 times. | |
| sar -u ALL # Same as “sar -u” but displays additional fields. | |
| sar -u ALL 1 3 # Same as “sar -u 1 3″ but displays additional fields. | |
| sar -u -f /var/log/sa/sa10 # Displays CPU usage for the 10day of the month from the sa10 file. | |
| # cpu usage by core. | |
| sar -P ALL # Displays CPU usage broken down by all cores for the current day. | |
| sar -P ALL 1 3 # Displays real time CPU usage for ALL cores every 1 second for 3 times (broken down by all cores). | |
| sar -P 1 # Displays CPU usage for core number 1 for the current day. | |
| sar -P 1 1 3 # Displays real time CPU usage for core number 1, every 1 second for 3 times. | |
| sar -P ALL -f /var/log/sa/sa10 # Displays CPU usage broken down by all cores for the 10day day of the month from sa10 file. | |
| # memory free and used. | |
| sar -r | |
| sar -r 1 3 | |
| sar -r -f /var/log/sa/sa10 | |
| # swap space used. | |
| sar -S | |
| sar -S 1 3 | |
| sar -S -f /var/log/sa/sa10 | |
| # Overall I/O activities | |
| sar -b | |
| # Individual block devices | |
| sar -d # dev53-1 means a block device with 53 as major number, and 1 as minor number. | |
| sar -p -d # -p means display the actual device name, eg: sda | |
| # report network stats. | |
| sar -n KEYWORD # where KEYWORK is one of the following: | |
| # DEV – Displays network devices vital statistics for eth0, eth1, etc., | |
| # EDEV – Display network device failure statistics | |
| # NFS – Displays NFS client activities | |
| # NFSD – Displays NFS server activities | |
| # SOCK – Displays sockets in use for IPv4 | |
| # IP – Displays IPv4 network traffic | |
| # EIP – Displays IPv4 network errors | |
| # ICMP – Displays ICMPv4 network traffic | |
| # EICMP – Displays ICMPv4 network errors | |
| # TCP – Displays TCPv4 network traffic | |
| # ETCP – Displays TCPv4 network errors | |
| # UDP – Displays UDPv4 network traffic | |
| # SOCK6, IP6, EIP6, ICMP6, UDP6 are for IPv6 | |
| # ALL – This displays all of the above information. The output will be very long. | |
| # Start time | |
| sar -s 10:00:01 # starts at 10 am rather that midnight. | |
| } | |
| (( 0 )) && { # Compare each character of the password hashes for root, ja, elh, guest. | |
| # Hashes for each user. | |
| ROOT=$(grep '^root' /etc/shadow |cut -d: -f2) | |
| JA=$(grep '^ja' /etc/shadow |cut -d: -f2) | |
| ELH=$(grep '^elh' /etc/shadow |cut -d: -f2) | |
| GUEST=$(grep '^guest' /etc/shadow |cut -d: -f2) | |
| echo -e " Root: $ROOT\n Ja: $JA\n Elh: $ELH\nGuest: $GUEST" | |
| LEN=${#ROOT} # length of hash. | |
| LEN=$((LEN -1)) # will be zero-based. | |
| for N in $(seq 0 $LEN); | |
| do | |
| # If each corresponding character is equal, then print the four characters. | |
| [ ${ROOT:$N:1} == ${JA:$N:1} -a ${JA:$N:1} == ${ELH:$N:1} -a ${ELH:$N:1} == ${GUEST:$N:1} ] \ | |
| && echo -e "Position: $N\t${ROOT:$N:1}${JA:$N:1}${ELH:$N:1}${GUEST:$N:1}" | |
| done |less | |
| # prints: | |
| # Position: 0 $$$$ | |
| # Position: 1 6666 | |
| # Position: 2 $$$$ | |
| # Position: 19 $$$$ | |
| # | |
| # So, position 19 probably marks the end of the salt. ie: the salt has a length of 20. | |
| } | |
| (( 0 )) && { # analyze recent selinux events. | |
| # thanks: Daniel J Walsh on CentOS list. | |
| # search thru audit.log for avc events that happened recently. save to file. | |
| ausearch -m avc -ts recent > /tmp/mylog | |
| # analyze file. This is similar to 'selinux -a /var/log/audit/audit.log' | |
| sealert -a /tmp/mylog | |
| } | |
| (( 0 )) && { # find the cube root of a number. Round to nearest integer. | |
| for N in 1 2 3 4 5 6 7 8 9 | |
| do | |
| echo | |
| echo "N: $N" | |
| A=$((N*N*N)) | |
| echo "Cubed: $A" | |
| B=$(eval "echo 'e(l($A)/3)' |bc -l") | |
| echo "Cube root: $B" | |
| echo -n "Integer: " | |
| eval "printf '%0.f\n' $B" | |
| done | |
| } | |
| (( 0 )) && { # load monitor | |
| # thanks: John Doe, [email protected] CentOS list. | |
| while : | |
| do | |
| LOAD=`cat /proc/loadavg | cut -f1 -d'.'` | |
| if [ $LOAD -gt 3 ] | |
| then ps auxfw > /tmp/ps.`date +"%s"`; sleep 60 | |
| fi | |
| sleep 10 | |
| done | |
| } | |
| (( 0 )) && { # Stop the Caps Lock key. | |
| # the nested command prints "us" | |
| setxkbmap -layout "$(setxkbmap -print | awk -F + '/xkb_symbols/ {print $2}')" -option ctrl:nocaps | |
| } | |
| (( 0 )) && { # Use the basename of a script as part of the tempfile or tempdir basename. | |
| for N in $0 | |
| do | |
| TEMPFILE=$(mktemp "/tmp/$(basename $0).XXXXXXXXXX"); echo "Temp: $TEMPFILE" | |
| done | |
| } | |
| (( 0 )) && { # get filesystem info, including superblock locations. ext2 and ext3. | |
| # thanks: [email protected] on CentOS list. | |
| dumpe2fs /dev/sda1 |grep superblock | |
| # then use one of the backup superblocks: | |
| #e2fsfsck -b <number from above> /dev/VolGroup00/<logical volume> | |
| } | |
| (( 0 )) && { # nmcli = network manager at cli. Works on CentOS6 | |
| man nmcli | |
| nmcli nm status | |
| nmcli con status | |
| nmcli con list | |
| nmcli dev list | |
| nmcli dev status | |
| } | |
| (( 0 )) && { # 2 cols of info. combine eg: admin ankush, amit | |
| # Sample input file. | |
| INFILE=~ja/temp/TTTT | |
| cat <<EOTx > $INFILE | |
| admin ankush | |
| admin amit | |
| powerusers dinesh | |
| powerusers jitendra | |
| EOTx | |
| # Process input file. | |
| OUTFILE=$INFILE.out | |
| awk '{print $1 ": "}' $INFILE | uniq > $OUTFILE | |
| for GROUP in `cat $OUTFILE | cut -d ':' -f 1` | |
| do | |
| for NAME in `cat $INFILE | grep $GROUP | awk '{print $2}'` | |
| do | |
| sed -i "s/^$GROUP: /&$NAME,\ /" $OUTFILE | |
| done | |
| done | |
| } | |
| (( 0 )) && { # generate a set of numbers | |
| sets= | |
| a=0 | |
| b=0 | |
| while [ $a -lt 2 ] # 20 processes (and pipes) | |
| do | |
| while [ $b -lt 10 ] | |
| do | |
| sets="${sets}${sets:+ }$a$b" # ${sets:+ } will add a space, if $sets exists and is non-null. | |
| echo $sets | |
| b=$(($b+1)) | |
| done | |
| b=0 | |
| a=$(($a+1)) | |
| done | |
| echo $sets | |
| # prints: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | |
| } | |
| (( 0 )) && { # For arin database only, | |
| # from: http://itools.com/tool/arin-whois-domain-search | |
| whois -h whois.arin.net n + 64.64.64.64 | |
| } | |
| (( 0 )) && { # phone related. | |
| # take samsung contacts export, remove photo info, then store as *.minus.images.vcf | |
| F=~ja/etc/var/contacts/Samsung/2011.08.13 ; grep ^[A-Z] $F.vcf |grep -v ^PHOTO > $F.minus.images.vcf | |
| # get full name (FN) and look for duplicates. | |
| F=~ja/etc/var/contacts/Samsung/2011.08.13.minus.images.vcf ; grep -h ^FN: $F |sort |uniq -c |sort -rn |less | |
| echo | |
| } | |
| (( 0 )) && { # kill X server | |
| # by default, Control-Alt-Backspace will NOT kill X in RHEL6 and clones. | |
| # from [email protected] on Scientific Linux list. | |
| echo "setxkbmap -option terminate:ctrl_alt_bksp" >> ~/.profile | |
| # not tried yet. | |
| # Or, Using GNOME | |
| # - Get to the System->Preferences->Keyboard menu. | |
| # - Select the “Layouts” tab and click on the “Layout Options” button. | |
| # - Then select “Key sequence to kill the X server” and enable “Control + Alt + Backspace”. | |
| } | |
| (( 0 )) && { # From rkhunter list, after finding hidden ports. | |
| # From Yago Jesus, developer of Unhide. | |
| # Warning: Hidden ports found: | |
| # ? ? ? ? Port number: 45812 | |
| # ? ? ? ? Port number: 895 | |
| # ? ? ? ? Port number: 900 | |
| # First, to discover if it is a false positive, bind in the ports using necat | |
| nc -l 900 | |
| nc -l 895 | |
| # If you can bind nc to the ports, probably could be a false positive. | |
| # Next, try: | |
| netstat -tanp | grep 900 | |
| # If you can't find it, is time to worry | |
| # Also, as root, try: | |
| lsof -i :900 # provides command, PID, user, ++ | |
| fuser -n tcp 900 # provides PID | |
| # Then, ps -p PID | |
| # Better, to get more info: | |
| ps aux |grep -E 'USER|<PID>' # provides user, PID, Start, Time, CommandName | |
| # the start time may be helpful. ?? | |
| # John Horne suggested using strace on one of the found PIDs. Eg: strace -p 900 | |
| # OP ran: | |
| strace -o traceout.txt -f unhide sys | |
| # which printed: | |
| # Found HIDDEN PID: 2446 | |
| # Command: /usr/java/jdk1.5.0_11/bin/java | |
| } | |
| (( 0 )) && { # use a hash to distribute many files over some dirs. | |
| # from R P Herrold on CentOS list. This is /bin/sh | |
| CANDIDATES="pix00001.jpg pix00002.jpg pix00003.jpg" | |
| for i in `echo "${CANDIDATES}"`; do | |
| HASH=`echo "$i" | md5sum - | awk {'print $1'}` | |
| echo "$i ${HASH}" | |
| done | |
| # A little simpler. | |
| echo | |
| CANDIDATES="pix00001.jpg pix00002.jpg pix00003.jpg" | |
| for i in ${CANDIDATES}; do | |
| HASH=`echo "$i" | md5sum - | awk {'print $1'}` | |
| echo "$i ${HASH}" | |
| done | |
| # from Marc Deop, [email protected], on CentOS list. This is /bin/bash. | |
| echo | |
| CANDIDATES=(pix00001.jpg pix00002.jpg pix00003.jpg) | |
| for i in "${CANDIDATES[@]}"; do | |
| MD5SUM=$(md5sum <(echo $i)) | |
| echo "$i ${MD5SUM% *}"; | |
| done | |
| } | |
| (( 0 )) && { # prevent firewall messages from being logged to the console | |
| # from [email protected] on CentOS list. | |
| # in sysctl.conf, set: | |
| kernel.printk = 3 4 1 7 | |
| } | |
| (( 0 )) && { # grep. factor out common parts of a string. | |
| # how to get data from log files for a specified range of days? i.e 19-30 June 2011 | |
| # from Owen Beckley on the CentOS list. | |
| grep -E '^Jun (19|2[0-9]|30) ' /var/log/messages | |
| # ja note. Note the parens. Its either/or within parens, but concatination outside parens. | |
| # man grep: | |
| # Repetition takes precedence over concatenation, | |
| # which in turn takes precedence over alternation. | |
| # A whole subexpression may be enclosed in parentheses | |
| # to override these precedence rules. | |
| } | |
| (( 0 )) && { # case statement with pattern matches. | |
| T=':::_and_more' | |
| T='::1:_and_more' | |
| case $T in | |
| :::* ) echo colons ;; | |
| abc* ) echo abc ;; | |
| ::1:* ) echo 'colon, colon, 1, colon' ;; | |
| * ) echo anything ;; | |
| esac | |
| exit | |
| } | |
| (( 0 )) && { # bash " = " vs. "=" vs. "==" | |
| # From: [email protected] on CentOS list. | |
| # With the spaces around the '=' and the dollar before the variable | |
| # name this actually is a test not an assignment. | |
| # But using double '=' is more clear. | |
| C="no" | |
| if [ $C = "yes" ]; then echo "1: $C"; fi | |
| if [ $C="yes" ]; then echo "2: $C"; fi | |
| # Print: "2: no" | |
| } | |
| (( 0 )) && { # Run all "unhide" stardard and elementary tests. | |
| # "standard" tests. the man page says that all elementary test are in the standard tests. | |
| for T in brute proc procall procfs quick reverse sys; | |
| do | |
| echo; | |
| echo Test: $T; | |
| ./unhide-linux26 $T |egrep -v '^Unhide|^http|^$'; | |
| done > log_of_unhide-linux26_standard_tests # log is in ~ja/temp/download/unhide/unhide-20110113/ | |
| # "elementary" tests. | |
| for T in checkbrute checkchdir checkgetaffinity checkgetparam checkgetpgid checkgetprio checkRRgetinterval checkgetsched checkgetsid checkkill checknoprocps checkopendir checkproc checkquick checkreaddir checkreverse checksysinfo checksysinfo2 ; | |
| do | |
| echo; | |
| echo Test: $T; | |
| ./unhide-linux26 $T |egrep -v '^Unhide|^http|^$'; | |
| done > log_of_unhide-linux26_elementary_tests # log is in ~ja/temp/download/unhide/unhide-20110113/ | |
| # Find hidden TCP/UDP ports | |
| ./unhide-tcp ; echo $? | |
| # NB: maybe it's better to dump unhide output to a file, | |
| # then check the return value, | |
| # then filter the files. | |
| } | |
| (( 0 )) && { # get a Short list of open files. | |
| lsof |egrep '^COMMAND|[0-9]w' |egrep '^COMMAND|/' # Includes column names. | |
| } | |
| (( 0 )) && { # Cronjob. A 65% chance of running. Then a random delay (LT 1 hour) before start. | |
| [ $(( $RANDOM \% 100 )) -lt 65 ] \ | |
| && sleep $(( $RANDOM \% 3600 )) \ | |
| && /path/to/climagic-poster.pl # posts msgs to twitter. | |
| } | |
| (( 0 )) && { # print the partition table. | |
| # Not easily readible but, | |
| #dd if=/dev/sda count=1 |od =tx1z # shows current state in mbr. Might have changed since last reboot. | |
| cat /proc/partitions # Shows the partitions, as of the last boot. | |
| } | |
| (( 0 )) && { # find artists w/o underscores. 1. | |
| # remove /data/mp3/, get artist name, get artist with the fewest tunes, | |
| # ignore artists with _ in name, limit to 10, matching UC anything UC | |
| for A in AbbyLincoln AdamFaith AfiaMala AlHibbler AlienSexFiend | |
| do | |
| echo "${A}" # Old name | |
| NEW=$(echo ${A} |sed -e 's;([a-z])([A-Z]);\1_\2;g') # replace lowerUPPER with lower_UPPER | |
| echo "${NEW}" | |
| echo | |
| done | |
| } | |
| (( 0 )) && { # find artists w/o underscores. 0. | |
| # remove /data/mp3/, get artist name, get artist with the fewest tunes, | |
| # ignore artists with _ in name, limit to 10, matching UC anything UC | |
| for A in $(find /data/mp3/ -type f -print \ | |
| |cut -b11- |cut -d'/' -f1 |sort |uniq -c |sort -n |grep -v '_' \ | |
| |head -n 10 |awk '{print $2}' |grep '[A-Z].*[A-Z]') | |
| do | |
| echo "${A}" # Old name | |
| done | |
| } | |
| (( 0 )) && { # Using the PIPESTATUS array to display exit statuses of commands in the pipe | |
| #grep MemTotal /proc/meminf | awk '{print $2}'; echo "EXIT STATUS = ${PIPESTATUS[0]}" | |
| # prints: grep: /proc/meminf: No such file or directory | |
| # prints: EXIT STATUS = 2 | |
| #grep MemTotal /proc/meminf | awk '{print $2}'; echo "EXIT STATUS = ${PIPESTATUS[1]}" | |
| # prints: grep: /proc/meminf: No such file or directory | |
| # prints: EXIT STATUS = 0} | |
| #grep MemTotal /proc/meminf | awk '{print $2}' | |
| #echo "grep STATUS = ${PIPESTATUS[0]}" | |
| #echo " awk STATUS = ${PIPESTATUS[1]}" | |
| # ${PIPESTATUS[1]} is empty. | |
| # Save PIPESTATUS array to a string. | |
| grep MemTotal /proc/meminf | awk '{print $2}' | |
| # echo -e " Element 0: ${PIPESTATUS[0]}\n Element 1: ${PIPESTATUS[1]}" # works. | |
| # echo "${PIPESTATUS[@]}" # works. number space number. | |
| P="${PIPESTATUS[@]}" ; echo "${P}" # save as above | |
| for RETVAL in ${P} | |
| do | |
| echo " RetVal: ${RETVAL}" # works. | |
| done | |
| # Save PIPESTATUS array to another array. | |
| grep MemTotal /proc/meminf | awk '{print $2}' | |
| SAVE=( "${PIPESTATUS[@]}" ) | |
| for N in $(seq 0 $(( ${#SAVE[@]} - 1)) ) | |
| do | |
| echo " Key: $N Value: ${SAVE[$N]}" | |
| done | |
| ## Apparently, the PIPESTATUS array must be used immediately. | |
| ## IE, before another command overwrites it. | |
| } | |
| (( 0 )) && { # Create a new array by removing elements from an existing array | |
| # Create an array | |
| A=( abe bob carl darla ellen fanny ) | |
| LAST=$(( ${#A[@]} - 1)) | |
| echo " Last: ${LAST}" | |
| # Copy array A to array B and print each array. | |
| B=( "${A[@]}" ) | |
| for i in $(seq 0 ${LAST}) | |
| do | |
| echo " A sub $i: ${A[$i]}" | |
| echo " B sub $i: ${B[$i]}" | |
| echo | |
| done | |
| # Remove an element and print each array. | |
| unset B[1] # ie unset bob | |
| for i in $(seq 0 ${LAST}) | |
| do | |
| echo " A sub $i: ${A[$i]}" | |
| echo " B sub $i: ${B[$i]}" | |
| echo | |
| done | |
| # Remove another element and print each array. | |
| unset B[4] # ie unset ellen | |
| for i in $(seq 0 ${LAST}) | |
| do | |
| echo " A sub $i: ${A[$i]}" | |
| echo " B sub $i: ${B[$i]}" | |
| echo | |
| done | |
| # print just the existing elements in B. | |
| for EL in "${B[@]}"; do echo ${EL}; done | |
| } | |
| (( 0 )) && { # Remove elements from an array | |
| # Create an array | |
| A=( abe bob carl darla ellen fanny ) | |
| LAST=${#A[@]} | |
| echo " Last: ${LAST}" | |
| # print array | |
| STR='' | |
| for i in $(seq 0 ${LAST}) | |
| do | |
| if [[ ! -z ${STR} ]]; then STR="${STR} ${A[i]}"; else STR=${A[i]}; fi | |
| done | |
| echo " Str: $STR" # prints: "abe bob carl darla ellen fanny" | |
| # Remove an element and print array. | |
| unset A[1] # ie unset bob | |
| STR='' | |
| for i in $(seq 0 ${LAST}) | |
| do | |
| if [[ ! -z ${STR} ]]; then STR="${STR} ${A[i]}"; else STR=${A[i]}; fi | |
| done | |
| echo " Str: $STR" # prints: "abe carl darla ellen fanny" | |
| # Remove an element and print array. | |
| unset A[4] # ie unset ellen | |
| STR='' | |
| for i in $(seq 0 ${LAST}) | |
| do | |
| if [[ ! -z ${STR} ]]; then STR="${STR} ${A[i]}"; else STR=${A[i]}; fi | |
| done | |
| echo " Str: $STR" # prints: "abe carl darla ellen fanny" | |
| } | |
| (( 0 )) && { # Host discovery | |
| # ifconfig/ping method. May not work if hosts do not accept pings. | |
| # | |
| # BroadcastAddress=$(ifconfig eth0 |grep Bcast |awk '{print $3}' |cut -d: -f2) | |
| # Could replace ifconfig above: ip addr show eth0 |grep 'inet ' |grep brd |tr -s ' ' |cut -d' ' -f5 | |
| BroadcastAddress=192.168.1.255 | |
| # -b allow pinging a broadcast address | |
| # -c count | |
| # -i interval to wait. | |
| ping -b -c 3 -i 20 ${BroadcastAddress} # does NOT work on home LAN, as root or non-root. | |
| # nmap method. | |
| nmap -sP 192.168.1.1-254 # works for root. non-root did not get all hosts. | |
| nmap -sP 192.168.1.* # works for root. | |
| # arping method | |
| for N in 1 10 11 16; do arping -c 1 192.168.1.${N} |grep reply; done # works for root. | |
| } | |
| (( 0 )) && { # wireshark cli. | |
| # -i is capture interface | |
| # -k is start capture session immediately | |
| # -f is capture filter | |
| wireshark -i eth0 -k | |
| wireshark -i eth0 -k -f "not arp" # filter out arp. | |
| wireshark -i eth0 -k -f "not tcp" # filter out tcp. | |
| wireshark -i eth0 -k -f "host 192.168.1.11" # just from baffin. CUPS, ARP, NFS, TCP, | |
| wireshark -i eth0 -k -f "host 192.168.1.11 and not tcp" # CUPS and ARP only. No TCP or NFS. | |
| wireshark -i eth0 -k -f "host 192.168.1.11 and arp" # just ARP. | |
| wireshark -i eth0 -k -f "host 192.168.1.11 and port 631" # just CUPS | |
| wireshark -i eth0 -k -f "host 192.168.1.11 and cups" # did NOT work. | |
| wireshark -i eth0 -k -f "host 192.168.1.11 and arp and port 631" # did NOT work. | |
| wireshark -r /full/path/to/capture-file # eg /root/wireshark/1.cap | |
| # after wireshark starts, various "display" filters are possible. | |
| # !(udp.port == 631) and !tcp and !dns and !arp # filters out these packets. | |
| # After wireshark has started, set capture filter for Ktorrent: | |
| # Capture > Options > filter: port 6881 | |
| # Capture > Options > file: eg: 2011.01.31_port_6881_ver_1.cap | |
| # Then start the capture. When done: | |
| # File > Export > Plain text: Packet summary and/or Packet details | |
| } | |
| (( 0 )) && { # Use xargs to do parallel ssh. | |
| # put each host on it's own line. the use xargs in parrallel. | |
| # note "sh -c" is used to allow to build a full command line. | |
| echo baffin hudson pacific \ | |
| |tr ' ' "\n" \ | |
| |xargs -n1 -P3 -I"HOST" sh -c "ssh HOST uptime |sed -e 's;^;HOST: ;'" | |
| # from Leonard den Ottolander on CentOS list. | |
| # Backup a directory using tar, but separate tarballs for each subdir. | |
| # $ find <dir> -mindepth 1 -maxdepth 1 -type d -exec tar cz {} -f {}.tgz \; | |
| # from Nico Kadel-Garcia: You'll want quotes: "{}" | |
| } | |
| (( 0 )) && { # Setting LC_COLLATE='C' permits [A-Z]* for /bin/ls or shell ls. | |
| # use /bin/ls. | |
| [ja@hudson ~]$ /bin/ls -d [A-Z]* | |
| bin Desktop etc public temp verify | |
| # use shell ls. | |
| [ja@hudson ~]$ ls -d [A-Z]* | |
| bin Desktop etc public temp verify | |
| # set LC_COLLATE='C'. then use shell ls. | |
| [ja@hudson ~]$ LC_COLLATE='C' ; ls -d [A-Z]* | |
| Desktop | |
| # now use /bin/ls. | |
| [ja@hudson ~]$ LC_COLLATE='C' ; /bin/ls -d [A-Z]* | |
| Desktop | |
| } | |
| (( 0 )) && { # Thanks: http://www.arrfab.net/blog/?p=246 | |
| # The man page has an example but what I do is using ssh itself as a ProxyCommand. Just an example : suppose you need to reach HostB (not reachable from where you are) but that you can reach HostA (and that HostA can reach HostB). You can configure your ~/.ssh/config like this : | |
| Host HostB | |
| Hostname the.known.fqdn.as.resolvable.by.HostA | |
| User arrfab | |
| ForwardAgent yes | |
| Port 22 | |
| ProxyCommand ssh [email protected] nc %h %p | |
| # And what if you need to reach HostC, which itself is only reachable by HostB ? Let’s just define a new Host section in the ~/.ssh/config and another ProxyCommand ! | |
| Host HostC | |
| Hostname the.known.fqdn.as.resolvable.by.HostB | |
| User arrfab | |
| ForwardAgent yes | |
| Port 22 | |
| ProxyCommand ssh remoteuser@HostB nc %h %p | |
| # You can now directly use the `ssh HostC` from your laptop/workstation and have a direct shell on HostC even if it has to open a connection to HostA and from there to HostB to finish to HostC.That works also for scp/sftp so you can directly copy/retrieve files to/from HostC instead of copy from one host to the next hop. More informations about those features and the correct syntax in `man ssh_config`. | |
| } | |
| (( 0 )) && { # PAM. pam authentication modules. List frequently specified modules. | |
| # grep out comments and blank lines. | |
| # replace [...] with a placeholder | |
| # get the third field | |
| # view most frequently specified. | |
| egrep -v '^#|^$' * |sed -e 's;\[.*\];placeholder;' |column -t |awk '{ print $3 }' |sort |uniq -c |sort -rn | |
| } | |
| (( 0 )) && { # If you use AES, then you can use a key of length up to 32 bytes | |
| # Generate like: | |
| DDIF='if=/dev/random' # code folding vs. kate | |
| dd status=noxfer $DDIF bs=16 count=1 \ | |
| | od --width=16 -t x2 |head -1 \ | |
| |cut -f2- -d' ' |tr -d ' ' \ | |
| > MyKey | |
| } | |
| (( 0 )) && { # Q from CentOS list: "is the areca 1100 raid controller supported by CentOS?" | |
| # Probably need to be root. | |
| # find a likely .ko file | |
| cd /lib/modules/2.6.18-194.8.1.el5PAE/kernel/drivers/scsi | |
| for F in $(find . -type f -name '*.ko'); | |
| do | |
| printf "%35s %s \n" "$F" "$(strings $F |grep ^description |tr "\n" "\t")" | |
| done |grep -i areca | |
| # prints: ./arcmsr/arcmsr.ko description=ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID HOST Adapter | |
| # cd into ./arcmsr and then get module info | |
| cd arcmsr | |
| modinfo arcmsr | |
| } | |
| (( 0 )) && { # SUID and SGID. 2 | |
| # from: http://www.standalone-sysadmin.com/blog/2010/06/setting-unix-file-permissions-numerically/ | |
| : <<-MYCOMMENTS | |
| 0 is nothing | |
| 1 is sticky bit | |
| 2 is SGID | |
| 3 is SGID and sticky bit | |
| 4 is SUID | |
| 5 is SUID and sticky bit | |
| 6 is SUID and SGID | |
| 7 is SUID, SGID, and sticky bit | |
| MYCOMMENTS | |
| touch ttt | |
| echo ' Note the Upper Case "S" and "T"' | |
| for PERM in {0..7} | |
| do | |
| echo -n " $PERM " ; chmod ${PERM}000 ttt \ | |
| && ls -l ttt | awk '{print $1}' | |
| done | |
| echo ' Note the Lower Case "s" and "t"' | |
| for PERM in {0..7} | |
| do | |
| echo -n " $PERM " ; chmod ${PERM}111 ttt \ | |
| && ls -l ttt | awk '{print $1}' | |
| done | |
| chmod 700 ttt ; rm ttt | |
| } | |
| (( 0 )) && { # SUID and SGID. 1 | |
| # from CentOS list. by Silviu Hutanu | |
| # SUID Octal perm : 4000 (chmod +s ) | |
| # Other users execute this file as owner of file | |
| # GUID Octal perm: 2000 (chmod +g ) | |
| # Other users execute this as group of the file/dir (It can be applyied to directories ) | |
| # Octal perm: 1000 | |
| # Sticky bit (Ensuring that users cannot delete other users files in a directory) | |
| chmod u+s file # SUID | |
| chmod u+g dir # GUID | |
| chmod u+f file/dir # Sticky bit | |
| } | |
| (( 0 )) && { # sqlite3 play 2. From: http://souptonuts.sourceforge.net/readme_sqlite_tutorial.html | |
| sqlite3 test.db < trigger1 | |
| sqlite3 test.db "insert into t1 (data,num) values ('Number six.',8);" | |
| sqlite3 test.db "select * from t1;" # shows a date in 'timeEnter'. | |
| } | |
| (( 0 )) && { # get a brief understanding of an sqlite database. | |
| # the yum sqlite database. | |
| ls /var/cache/yum/x86_64/6/updates/ | |
| # Prints: cachecookie e3bbabf1b23dcb92bf8dae78a86f62d8be1661b00efb809d356670534e3ee0c7-primary.sqlite mirrorlist.txt packages repomd.xml | |
| # save the dump. | |
| sqlite3 e3bbabf1b23dcb92bf8dae78a86f62d8be1661b00efb809d356670534e3ee0c7-primary.sqlite ".dump" > temp.dump | |
| # list table sizes and col headings. | |
| egrep '^CREATE TABLE|INSERT INTO' temp.dump |sed -e 's;VALUES.*;;' |sort |uniq -c |sort -rn |less | |
| # what tables are in the db? | |
| sqlite3 e3bbabf1b23dcb92bf8dae78a86f62d8be1661b00efb809d356670534e3ee0c7-primary.sqlite ".table" | |
| # Prints: conflicts db_info files obsoletes packages provides requires | |
| # look at column headers for the packages table. | |
| sqlite3 e3bbabf1b23dcb92bf8dae78a86f62d8be1661b00efb809d356670534e3ee0c7-primary.sqlite ".dump" |grep '^CREATE TABLE packages' |less | |
| # look at a few examples from the packages table. Note, line insertion may include newline characters, or not. | |
| sqlite3 e3bbabf1b23dcb92bf8dae78a86f62d8be1661b00efb809d356670534e3ee0c7-primary.sqlite ".dump" |grep -A10 '^CREATE TABLE packages' |tail -n +2 |less | |
| } | |
| (( 0 )) && { # sqlite3 play 1. From: http://souptonuts.sourceforge.net/readme_sqlite_tutorial.html | |
| cat << 'ENDOFTRIGGER' > ~/temp/sqlite/trigger1 | |
| -- ******************************************************************** | |
| -- Creating a trigger for timeEnter | |
| -- Run as follows: | |
| -- $ sqlite3 test.db < trigger1 | |
| -- ******************************************************************** | |
| CREATE TRIGGER insert_t1_timeEnter AFTER INSERT ON t1 | |
| BEGIN | |
| UPDATE t1 SET timeEnter = DATETIME('NOW') WHERE rowid = new.rowid; | |
| END; | |
| -- ******************************************************************** | |
| ENDOFTRIGGER | |
| } | |
| (( 0 )) && { # sqlite3 play 0. From: http://souptonuts.sourceforge.net/readme_sqlite_tutorial.html | |
| sqlite3 test.db | |
| sqlite3 test.db "create table t1 (t1key INTEGER PRIMARY KEY,data TEXT,num double,timeEnter DATE);" | |
| sqlite3 test.db "insert into t1 (data,num) values ('This is sample data',3);" | |
| sqlite3 test.db "insert into t1 (data,num) values ('More sample data',6);" | |
| sqlite3 test.db "insert into t1 (data,num) values ('And a little more',9);" | |
| sqlite3 test.db "insert into t1 (data,num) values ('Here is number four',8);" | |
| sqlite3 test.db "insert into t1 (data,num) values ('Here\'s number five',8);" | |
| sqlite3 test.db "insert into t1 (data,num) values ('Here is number five',8);" | |
| sqlite3 test.db "select * from t1 limit 2"; | |
| sqlite3 test.db "select * from t1"; | |
| sqlite3 test.db "select * from t1 offset 2"; # SQL error: near "2": syntax error | |
| sqlite3 test.db "select * from t1 order by t1key limit 1 offset 2"; | |
| sqlite3 test.db "select * from t1 order by t1key offset 2"; # SQL error: near "2": syntax error | |
| sqlite3 test.db .dump; | |
| sqlite3 test.db ".dump" |sed -e s/t1/t2/|sqlite3 test2.db | |
| } | |
| (( 0 )) && { # find private date in FF, after "clear private date" is run. sqlite3. | |
| # Setup: | |
| # 1. visit www.notbig.org, or some other site, to populate FF. | |
| # 2. Zoom in or out. ## specifically for | |
| # 3. in FF, Tools -> 'Clear private data' | |
| # 4. exit FF. | |
| # 5. run at cli: | |
| cd ~ja/.moz*/fire*/*.default | |
| for F in ./*.{sqlite,db,mfasl} | |
| do echo "===== $F"; strings $F |egrep 'notbig' ; echo -e "\n"; done |less | |
| # the above command identifies private data in: contents-prefs.sqlite and ybookmarks.sqlite | |
| for F in ./*.{js,txt,xml,ini,dat,rdf,log,cache} | |
| do echo "===== $F"; egrep 'notbig' $F ; echo -e "\n"; done |less | |
| # the above command does NOT identify any private date in these files. | |
| # FYI: | |
| #sqlite3 ./content-prefs.sqlite .dump |less # then search for 'notbig'. | |
| ( echo ' Files or Dirs not looked at. Should only be Dirs.' | |
| ls -d * |egrep -v \ | |
| '.original$|.sqlite$|.db$|.mfasl$|.js$|.txt$|.xml$|.ini$|.dat$|.rdf$|.log$|.cache$' ) \ | |
| |less | |
| # the above command lists only the sub-dirs. | |
| # ?? what about the sub-dirs ?? | |
| # | |
| # remove ./bookmarksbackups/* since it keeps url data. | |
| } | |
| (( 0 )) && { # logwatch services with output. | |
| # run logwatch with debug level 10 to list all possible services. | |
| # then see which services have any output. | |
| CAPTURE=0 | |
| echo ' ===== The following services have logwatch output =====' | |
| logwatch --service all --range 'since -7 days' --debug 10 2>/dev/null \ | |
| |grep -v 'ReadConfigFile' \ | |
| |while read LINE | |
| do | |
| [[ ${CAPTURE} -eq 1 ]] && echo ${LINE} | |
| [[ ${LINE} =~ 'Services that will be processed:' ]] && CAPTURE=1 # turn on capture. | |
| [[ ${LINE} =~ 'All LogFile Data:' ]] && CAPTURE=0 # turn off. | |
| done |egrep -v '^$|^All LogFile Data' |cut -d' ' -f3 \ | |
| |while read S; | |
| do | |
| OUT=$(/usr/sbin/logwatch --service ${S} --range 'since -7 days' --print) | |
| # [ ! -z "$OUT" ] && echo " Service ${S} output:" && echo "===== $OUT =====" && echo && echo | |
| [ ! -z "$OUT" ] && echo " ${S}" | |
| done | |
| # prints: | |
| : <<-MYCOMMENTS | |
| ===== The following services have logwatch output ===== | |
| secure | |
| sudo | |
| sshd | |
| xntpd | |
| zz-disk_space | |
| zz-network | |
| zz-sys | |
| automount | |
| pam_unix | |
| yum | |
| MYCOMMENTS | |
| # my choice: secure sudo sshd automount pam_unix | |
| # cli: logwatch --service secure --service sudo --service sshd --service automount --service pam_unix --range 'since -7 days' --print | |
| # Or: /usr/sbin/logwatch --service all \ | |
| # --service -xntpd --service -zz-disk_space --service -zz-network --service -zz-sys --service -yum \ | |
| # --range 'since -7 days' --print | |
| } | |
| (( 0 )) && { # aide fun. Not. | |
| #SINGLES=(p i n u g s b m a c acl selinux xattrs S md5 sha1 sha256 sha512 rmd160 tiger haval gost crc32 whirlpool) # But, ignore some of the singles. | |
| SINGLES=(p i n u g s b m a c acl selinux xattrs S md5 sha1 sha256 sha512 rmd160 tiger) | |
| # groups | |
| R='p+i+n+u+g+s+m+c+acl+selinux+xattrs+md5' | |
| # ignore for now: | |
| #L='p+i+n+u+g+acl+selinux+xattrs' | |
| #E= Empty group | |
| #>= Growing logfile p+u+g+i+n+S+acl+selinux+xattrs | |
| # customs | |
| #ALLXTRAHASHES = sha1+rmd160+sha256+sha512+tiger # ignore for now. | |
| #EVERYTHING = R+ALLXTRAHASHES # ignore for now. | |
| #NORMAL = R+rmd160+sha256 | |
| #DIR = p+i+n+u+g+acl+selinux+xattrs | |
| #PERMS = p+i+u+g+acl+selinux | |
| #LOG = > # ignore for now. | |
| #LSPP = R+sha256 | |
| #DATAONLY = p+n+u+g+s+acl+selinux+xattrs+md5+sha256+rmd160+tiger | |
| CONF='/etc/aide.conf.original' | |
| grep ^[A-Z] ${CONF} |egrep -v '^ALLXTRAHASHES|^EVERYTHING|^LOG' \ | |
| |while read LINE | |
| do | |
| KEY=$(echo "${LINE}" |sed -e 's; *= *.*$;;') | |
| VAL=$(echo "${LINE}" |sed -e 's;^.*= *;;') | |
| echo " Line: ${LINE}" | |
| echo " Key: ${KEY}" | |
| echo " Val: ${VAL}" | |
| #VAL=$(echo "${VAL}" |sed -e 's;R;$R\+;') | |
| #VAL=$(eval ${VAL}) | |
| VAL=$(echo "${VAL}" |sed -e 's;R;YouShitFace+;') | |
| echo " Val: ${VAL}" | |
| echo | |
| done | |
| } | |
| (( 0 )) && { # One-liners | |
| man 7 ascii # ascii table | |
| ssh -t reachable_host ssh unreachable_host | |
| # This one-liner creates an ssh connection to unreachable_host via reachable_host. | |
| # -t allocates a pseudo-tty, necessary for working interactively in the second ssh | |
| } | |
| (( 0 )) && { # Minimum example of how ssh ControlMaster interfeers with my fsck script. | |
| # | |
| for HOST in baffin hudson pacific | |
| do | |
| for PART in /dev/sda1 /dev/mapper/VolGroup00-LogVol00 | |
| do | |
| ssh -tt ${HOST} "sudo /sbin/tune2fs -l ${PART}" \ | |
| > /tmp/min.fsck.${HOST}.$(basename ${PART}) & | |
| done | |
| done | |
| wait | |
| ls -l /tmp/min.fsck.* | |
| } | |
| (( 0 )) && { # Get the PID and Return Status of background processes. | |
| # start bg processes and collect PIDs | |
| ls /bin/k* & | |
| PIDA=$! | |
| du -sh /bin & | |
| PIDB=$! | |
| ls /bumperonni & | |
| PIDC=$! | |
| # wait for each PID to finish, then print return code. | |
| wait $PIDA | |
| RCA=$? ; echo " Return Code A: $RCA" | |
| wait $PIDB | |
| RCB=$? ; echo " Return Code B: $RCB" | |
| wait $PIDC | |
| RCC=$? ; echo " Return Code C: $RCC" | |
| } | |
| (( 0 )) && { # Find the unique words in a text file. | |
| cd ~/temp/ | |
| grep -v ^match nmap-service-probes > a | |
| while read L | |
| do | |
| M=$(echo "$L" |tr ' ' "\n") | |
| echo "$M" | |
| done < a >b | |
| cat b |sort -u |grep ^[a-zA-Z] |grep -v ^http > c | |
| cat c |tr 'A-Z' 'a-z' |sort -u > d | |
| } | |
| (( 0 )) && { # See which hosts are available, then use just those. | |
| for HOST in $HOSTS | |
| do | |
| if ! ping -W 1 -c 1 $HOST &>/dev/null | |
| then | |
| echo " Host not available: $HOST" && continue | |
| fi | |
| HOSTS_AVAIL="${HOSTS_AVAIL} $HOST" | |
| done | |
| echo " Hosts available: ${HOSTS_AVAIL}" | |
| } | |
| (( 0 )) && { # System Info | |
| /usr/sbin/dmidecode | |
| /usr/sbin/biosdecode | |
| } | |
| (( 0 )) && { # Something works OR (echo error message && exit 1) | |
| TEMPFILE=$(mktemp /home/ja/some.name.XXXXXXXXXX) \ | |
| || ( echo "this is an error message" && exit 1 ) | |
| # creates file, as expected. | |
| TEMPFILE=$(mktemp /root/some.name.XXXXXXXXXX) \ | |
| || ( echo "this is an error message. error code: $?" && exit 49000 ) | |
| # does NOT create file, as expected. displayes $? as 1. | |
| # at cli, "echo $?" => 1 | |
| # Why did it not display 49000 ??? | |
| TEMPFILE=$(mktemp /root/some.name.XXXXXXXXXX) \ | |
| [ ! -f ${TEMPFILE} ] && echo "this is another error message. Error code: $?" && exit 49001 | |
| # does NOT display the echo. | |
| # $? is 1. | |
| } | |
| (( 0 )) && { # one-liners from: http://www.catonmat.net/blog | |
| $ > file.txt # either empties file.txt or creates a new file.txt. | |
| } | |
| (( 0 )) && { # get wireless access point info. there is some duplication. See also: iwconfig. | |
| # runs on netbook, but not desktop. | |
| for ARG in scan freq chan rate key power txpower retry peers event auth wpakeys genie modulation | |
| do | |
| echo -e "\n$ARG\n" | |
| sudo iwlist ra0 $ARG | |
| done | |
| } | |
| (( 0 )) && { # Compare an app output over time. version 1 | |
| # something may be lost between diffs. | |
| LOG=/tmp/log_of_netstat_pltn | |
| SLEEP=3 # seconds. | |
| ( | |
| echo " ===== Netstat -pltn, as of $(date +"%F--%T")" | |
| netstat -pltn | |
| echo | |
| sleep $SLEEP | |
| for X in {1..3} | |
| do | |
| echo " ===== Netstat -pltn DIFF, as of $(date +"%F--%T")" | |
| diff <(netstat -pltn) <(sleep $SLEEP; netstat -pltn) | |
| echo | |
| done | |
| ) > $LOG | |
| echo " Kindly check logfile at $LOG" | |
| } | |
| (( 0 )) && { # Compare an app output over 10 seconds. | |
| diff <(netstat -pltn) <(sleep 10; netstat -pltn) | |
| } | |
| (( 0 )) && { # Compare an apps open files over 10 seconds. | |
| LSOF=/usr/sbin/lsof | |
| PID=2238 | |
| diff <($LSOF -p $PID) <(sleep 10; $LSOF -p $PID) | |
| } | |
| (( 0 )) && { # display a process tree. May be convenient for finding multiple processes for same app. | |
| # u=show uid transitions | |
| # p=show PIDs | |
| pstree -up | |
| } | |
| (( 0 )) && { # VGA Resolution Codes for GRUB and Lilo. Add to grub boot line. | |
| : <<-MYCOMMENTS | |
| --- Depth -- | |
| Colors bits 640x480 800×600 1024×768 1152×864 1280×1024 1600×1200 | |
| 256 8 vga=769 vga=771 vga=773 vga=353 vga=775 vga=796 | |
| 32000 ? vga=784 vga=787 vga=790 vga= ? vga=793 vga= ? | |
| 65000 16 vga=785 vga=788 vga=791 vga=355 vga=794 vga=798 | |
| 16.7M 24 vga=786 vga=789 vga=792 ? vga=795 vga=799 | |
| MYCOMMENTS | |
| } | |
| (( 0 )) && { # find the longest words without using some letters. | |
| # without using any letters with tails or stalks?". | |
| # from: http://www.openfusion.net/linux/the_joy_of_scripting | |
| echo COULD NOT DUPLICATE | |
| #egrep -v '[A-Zbdfghjklpqty]' /usr/share/dict/words | \ | |
| #perl -nle 'chomp; push @words, $_; | |
| # END { @words = sort { length($b) cmp length($a) } @words; | |
| # print join "\n", @words[0 .. 9] }' | |
| # Prints: | |
| # noncarnivorousness | |
| # nonceremoniousness | |
| # overcensoriousness | |
| # carnivorousnesses | |
| # noncensoriousness | |
| # nonsuccessiveness | |
| # overconsciousness | |
| # semiconsciousness | |
| # unacrimoniousness | |
| # uncarnivorousness | |
| } | |
| (( 0 )) && { # Get an english word list from <file> | |
| #cat <file> | tr -sc A-Za-z '\012' # '\012' is a newline. | |
| # -s = squeeze | |
| # -c = compliment | |
| # So, tr -c A-Za-z will replace all non-letters with '\012' | |
| # Then '\012' will be squeezed. | |
| # | |
| # Could replace '\012' with "\n" | |
| cat vim_notes | tr -sc A-Za-z "\n" | |
| } | |
| (( 0 )) && { # Indirect variable expansion in bash. | |
| test.function() | |
| { | |
| if [ -n "$1" ] | |
| then echo "value of [${1}] is: [${!1}]" | |
| else echo "Null parameter passed to this function" | |
| fi | |
| } | |
| Variable="My.Darling.String" | |
| test.function Variable | |
| #prints: value of [Variable] is: [My.Darling.String] | |
| # If the first character of parameter is an "!", a level of variable indirection is introduced. | |
| # Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion. | |
| } | |
| (( 0 )) && { # run a program at 2:35 at the first Saturday of each odd month. | |
| # from: [email protected] on CentOS list. | |
| 35 2 1-7 1,3,5,7,9,11 * [ "$(date '+\%a')" == "Sat" ] && some.command | |
| # Or, for readability: | |
| 35 2 1-7 Jan,Mar,May,Jul,Sep,Nov * [ "$(date '+\%a')" == "Sat" ] && some.command | |
| } | |
| (( 0 )) && { # cron job to run every other week on Saturday (NOT first and third week ). 1. | |
| # from CentOS list, Jan 6, 2010: John R Pierce | |
| # [ $(( ($(date +"%s") / 86400) % 14)) -eq 9 ] | |
| # where %s is seconds since 1970-01-01 00:00:00 UTC, which was a Wednesday here (PST). | |
| # ja notes: | |
| # - modulo 14 yields 0..13 | |
| # - Running the code below on a Wednesday yields a modulo of 13. IE: wed=13 | |
| # - So, backing up to Saturday means a modulo of 9 | |
| echo " $(date)" | |
| SecSinceEpoch=$(date +"%s") | |
| DaysSinceEpoch=$(( $SecSinceEpoch / 86400 )) | |
| DaysMod14=$(( $DaysSinceEpoch % 14 )) | |
| printf " SSE: %-15s DSE: %-8s DM14: %-4s \n" "$SecSinceEpoch" "$DaysSinceEpoch" "$DaysMod14" | |
| echo | |
| # ja note: both poposed solutions seem to ignore months, just doing every other Sat thru/out the year. | |
| } | |
| (( 0 )) && { # cron job to run every other week on Saturday (NOT first and third week ). 0. | |
| # from CentOS list, Jan 6, 2010. | |
| for D in {1..31}; do echo $(($D%14)); done # prints 1..13, 0..13, 0..3 | |
| # date yields digits for day of the month. eg: 06 for Jan 6. | |
| # So, this seems to work: 0 0 * * 6 [ $((`date +"%d"`%14)) -ge 8 ] && script.sh | |
| } | |
| (( 0 )) && { # play with "command blocks" and failure. | |
| # this works. | |
| #cd wxyz || { echo " The cd command failed" ; exit 1 | |
| #} | |
| # this fails. | |
| #cd wxyz || { echo " The cd command failed" ; exit 1 } | |
| # this only exits the sub-shell. | |
| cd wxyz || ( echo " The cd command failed" ; exit 1 ) | |
| # Darn. I guess I'll have to skip the echo part. Like in man mktemp | |
| echo " This line is printed if the above command does not exit." | |
| #TEMPDIR=$(mktemp -d /tmp/t.XXXXXXXXXX) | |
| } | |
| (( 0 )) && { # given a table of values, space filled, see if all values in a line are equal. | |
| # NB: all 3 ways yield the same result. The last is more versetile. | |
| F=/tmp/TTTT.$$ | |
| cat << _BOINK_ > $F | |
| 1 1 1 1 | |
| 2 1 1 1 | |
| 1 2 1 1 | |
| 1 1 2 1 | |
| 1 1 1 2 | |
| _BOINK_ | |
| declare -a HITS | |
| while read LINE | |
| do | |
| HITS=($LINE) | |
| for i in "${HITS[@]}"; do echo $i; done | |
| COUNT=${#HITS[@]} # prints: 4 | |
| echo " Number of elements in array HITS: $COUNT" | |
| [ ${HITS[0]} -ne ${HITS[1]} ] && echo NotTheSame01 | |
| [ ${HITS[1]} -ne ${HITS[2]} ] && echo NotTheSame12 | |
| [ ${HITS[2]} -ne ${HITS[3]} ] && echo NotTheSame23 | |
| for i in 0 1 2 | |
| do | |
| j=$((i + 1)) | |
| [ ${HITS[$i]} -ne ${HITS[$j]} ] && echo NotTheSame$i$j | |
| done | |
| UPPER=$((COUNT-2)) ; echo " Upper: $UPPER" | |
| for i in $(seq 0 $UPPER) | |
| do | |
| j=$((i + 1)) | |
| [ ${HITS[$i]} -ne ${HITS[$j]} ] && echo NotTheSame$i$j | |
| done | |
| echo | |
| done < $F | |
| } | |
| (( 0 )) && { # compare chkconfig, ps, ... Probably not too helpful. | |
| # Maybe compare processes across hosts. See ~ja/bin/table_processes_all_hosts | |
| # Maybe see where each process comes from. ie, user started, init started, kernel thread, ... | |
| TEMPDIR=$(mktemp -d /tmp/compare.chkconfig.ps.XXXXXXXXXX) | |
| # list services that are "on" for some runlevels. | |
| /sbin/chkconfig --list |grep ':on' |awk '{print $1}' > ${TEMPDIR}/services | |
| # Some processes have a trailing colon ":". Remove it. | |
| ps -eo cmd |egrep -v '^CMD|^\[' |awk '{print $1}' |sed -e 's;\:$;;' > ${TEMPDIR}/ps1 | |
| # groom the list of processes. ie: basename and unique. | |
| while read NAME | |
| do | |
| echo "$(/bin/basename -- "$NAME")" | |
| done < ${TEMPDIR}/ps1 |sort -u > ${TEMPDIR}/ps2 | |
| # which services are processes? | |
| while read S | |
| do | |
| while read P | |
| do | |
| if [ "$P" == "$S" ] | |
| then printf " S: %-20s P: %-20s \n" "$S" "$P" >> ${TEMPDIR}/match | |
| elif echo "$P" |grep -q "$S" | |
| then | |
| printf " S: %-20s P: %-20s \n" "$S" "$P" \ | |
| >> ${TEMPDIR}/match.some1 | |
| # This is a partial match. eg: cups/cupsd | |
| # or cups/eggcups or syslog/syslogd. | |
| # So, test for a trailing 'd' and report. | |
| [ "${P}" == "${S}d" ] \ | |
| && printf " S: %-20s P: %-20s \n" "$S" "$P" \ | |
| >> ${TEMPDIR}/match | |
| else printf " S: %-20s P: %-20s \n" "$S" "$P" >> ${TEMPDIR}/match.no | |
| fi | |
| done < ${TEMPDIR}/ps2 | |
| done < ${TEMPDIR}/services | |
| chown -R ja:ja ${TEMPDIR} | |
| exit 0 | |
| } | |
| (( 0 )) && { # Using tmpfs. (ramdisk) | |
| # Thanks: http://kevin.vanzonneveld.net/techblog/article/create_turbocharged_storage_using_tmpfs/ | |
| # copy a file to ramdisk. | |
| cp -af /root/100mb.bin /dev/shm/ # Now it's in your RAM! | |
| # Maybe the limit of half of your physical RAM is not sufficient. | |
| mount -o remount,size=4G /dev/shm | |
| # Create a new volume | |
| # Create a tmpfs instance on /var/www/www.mysite.com/ramdrive with a max of 500MB RAM, | |
| # that can only be changed by root, but accessed by everyone (like Apache): | |
| mkdir -p /var/www/www.mysite.com/ramdrive | |
| mount -t tmpfs -o size=500M,mode=0744 tmpfs /var/www/www.mysite.com/ramdrive | |
| # Add the following line to your /etc/fstab: | |
| tmpfs /var/www/www.mysite.com/ramdrive tmpfs size=500M,mode=0777 0 0 | |
| # change mode 0777 to a suitable umask. | |
| # ja note: maybe for temp files or temp dirs: | |
| TEMPDIR=$(mktemp -d /dev/shm/script.name.XXXXXXXXXX) | |
| } | |
| (( 0 )) && { # convert a street address to lat/lon | |
| # thanks: http://www.linuxjournal.com/article/10589 (whereis.sh) | |
| URL='http://api.maps.yahoo.com/ajax/geocode' | |
| ARGS='?appid=onestep&qt=1&id=m&qs=' | |
| ADDR="$(echo $* | sed 's/ /+/g')" | |
| curl -s "${URL}${ARGS}${ADDR}" | cut -d\" -f13,15 | sed 's/[^0-9\.\,\-]//g;s/,$//' | |
| } | |
| (( 0 )) && { # convert a street address to lat/lon. Thanks: linuxjournal.com | |
| URL='http://api.maps.yahoo.com/ajax/geocode' | |
| ARGS='?appid=onestep&qt=1&id=m&qs=' | |
| ADDR="$(echo $* | sed 's/ /+/g')" | |
| curl -s "${URL}${ARGS}${ADDR}" | cut -d\" -f13,15 | sed 's/[^0-9\.\,\-]//g;s/,$//' | |
| # Take the lat/lon above from the standard input. | |
| # Convert to Degrees/Minutes format and figure out whether it is a N/S lat and E/W lon. | |
| # Then loops through the JPEGg images in the current directory and sets the lat/lon, using exiv2 | |
| ##### NOT TESTED. | |
| IFS="," | |
| read lat long | |
| # If sign is negative, we have to change reference | |
| latRef="N"; | |
| latSign=$(echo $lat | cut -c 1) | |
| if [ "X$latSign" = "X-" ] | |
| then # Delete minus from beginning | |
| lat=$(echo $lat | sed s/^-//) | |
| latRef="S" | |
| fi | |
| lonRef="E"; | |
| lonSign=$(echo $long | cut -c 1) | |
| if [ "X$lonSign" = "X-" ] | |
| then | |
| long=$(echo $long | sed s/^-//) | |
| lonRef="W" | |
| fi | |
| # Calculate lat/lon degrees and minutes | |
| latDeg=$( echo "scale=0; $lat/1" | bc ) | |
| latMin=$( echo "scale=2; m=($lat-$latDeg) *100/ 0.016666;scale=0;m/1" | bc ) | |
| lonDeg=$( echo "scale=0; $long/1" | bc ) | |
| lonMin=$( echo "scale=2; m=($long-$lonDeg)*100/0.016666;scale=0;m/1" | bc ) | |
| echo Picture location will be: $latDeg $latMin\' $latRef , $lonDeg $lonMin\' $lonRef | |
| for fil in *.jpg # Also try *.JPG | |
| do | |
| echo Updating $fil .... | |
| exiv2 -M"set Exif.GPSInfo.GPSLatitude $latDeg/1 $latMin/100 0/1" \ | |
| -M"set Exif.GPSInfo.GPSLatitudeRef $latRef" \ | |
| -M"set Exif.GPSInfo.GPSLongitude $lonDeg/1 $lonMin/100 0/1" \ | |
| -M"set Exif.GPSInfo.GPSLongitudeRef $lonRef" \ | |
| $fil | |
| done | |
| } | |
| (( 0 )) && { # symbolic links and 'readlink -f' | |
| D=/home/ja/temp/t-readlink | |
| mkdir -p $D | |
| cd $D | |
| # link to a dir on host's /tmp | |
| [ ! -L tmp1 ] && ln -s /tmp ./tmp1 # if tmp1 does not exist, or is not a symlink, create it. | |
| ls -l tmp1 | |
| # prints: lrwxrwxrwx 1 ja ja 4 Nov 30 09:36 tmp1 -> /tmp | |
| readlink -f tmp1 | |
| # prints: /tmp | |
| # link to another file within the mount point. | |
| [ ! -L tmp2 ] && ln -s ../vim_notes ./tmp2 | |
| ls -l tmp2 | |
| # prints: lrwxrwxrwx 1 ja ja 12 Nov 30 09:46 tmp2 -> ../vim_notes | |
| readlink -f tmp2 | |
| # prints: /mnt/fundy/ja/temp/vim_notes | |
| # link to a non-existant file within the mount point. | |
| [ ! -L tmp3 ] && ln -s ../i-am-not-here ./tmp3 | |
| ls -l tmp3 | |
| # prints: lrwxrwxrwx 1 ja ja 16 Nov 30 09:50 tmp3 -> ../i-am-not-here | |
| readlink -f tmp3 | |
| # prints: /mnt/fundy/ja/temp/i-am-not-here | |
| # So, we can link to a file or dir, existing or not, on the host or on a mount point. | |
| # In each case, 'readlink' reports the correct "real path". | |
| # link to a file through a non-existing dir. | |
| [ ! -L tmp4 ] && ln -s ../i-am-not-here/me-too ./tmp4 | |
| ls -l tmp4 | |
| # prints: lrwxrwxrwx 1 ja ja 23 Nov 30 09:55 tmp4 -> ../i-am-not-here/me-too | |
| readlink -f tmp4 | |
| # NO output. | |
| # NB: the links to non-existent dirs or files are shown in red within a terminal listing. | |
| } | |
| (( 0 )) && { # version 1 of *parsing* an RPM filename into NAME, VER, REL, FROM, ARCH | |
| # elsewhere we see which RPMS to update. | |
| #DIR=/share/CentOS/5.4/os/i386/CentOS | |
| DIR=/share/CentOS/5.4/updates/i386/RPMS | |
| cd ${DIR} || exit 1 | |
| ls |sed -e 's;\.rpm$;;' |while read R | |
| do | |
| # Parse recent additions to the *local* updates repo. | |
| ARCH=''; REST=''; FROM=''; RES2=''; REL=''; RES3=''; VER=''; NAME='' | |
| ARCH=".${R##*.}" ; REST=${R%.*} | |
| if echo $REST |grep -q '\.el5' | |
| then | |
| FROM=$(echo $REST |sed -e 's;.*\.el5;.el5;') | |
| RES2=${R%.el5*} | |
| elif echo $REST |grep -q '\.fc6' | |
| then | |
| FROM=$(echo $REST |sed -e 's;.*\.fc6;.fc6;') | |
| RES2=${R%.fc6*} | |
| else RES2=$REST | |
| fi | |
| REL="-${RES2##*-}" ; RES3=${RES2%-*} | |
| VER="-${RES3##*-}" ; NAME=${RES3%-*} | |
| printf " %-65s %-50s %-15s %-20s %-20s %-12s \n" \ | |
| "$R" "$NAME" "$VER" "$REL" "$FROM" "$ARCH" | |
| done | |
| } | |
| (( 0 )) && { # version 0 of parsing an RPM filename into NAME, VER, REL, FROM, ARCH | |
| # grep ^RPMS ~ja/bin/support/logs/repo.updates* \ | |
| #DIR=/share/CentOS/5.4/updates/i386/RPMS | |
| DIR=/share/CentOS/5.4/os/i386/CentOS | |
| [ ! -d ${DIR} ] && echo " Not a dir: ${DIR}" && exit 1 | |
| ls -l ${DIR}/* \ | |
| |sed -e 's;^.*RPMS/;;' -e 's;^.*i386/CentOS/;;' -e 's;\.rpm$;;' \ | |
| |while read R | |
| do | |
| # Parse recent additions to the *local* updates repo. | |
| ARCH=''; REST=''; FROM=''; RES2=''; REL=''; RES3=''; VER=''; NAME='' | |
| ARCH=".${R##*.}" | |
| REST=${R%.*} | |
| if echo $REST |grep -q '\.el5' | |
| then | |
| FROM=$(echo $REST |sed -e 's;.*\.el5;.el5;') | |
| RES2=${R%.el5*} | |
| elif echo $REST |grep -q '\.fc6' | |
| then | |
| FROM=$(echo $REST |sed -e 's;.*\.fc6;.fc6;') | |
| RES2=${R%.fc6*} | |
| else RES2=$REST | |
| fi | |
| REL="-${RES2##*-}" | |
| RES3=${RES2%-*} | |
| VER="-${RES3##*-}" | |
| NAME=${RES3%-*} | |
| printf " %-65s %-50s %-15s %-20s %-20s %-12s \n" \ | |
| "$R" "$NAME" "$VER" "$REL" "$FROM" "$ARCH" | |
| continue | |
| # Compare recent additions to current rpm database. | |
| OUT=$(rpm -q $NAME) # output | |
| echo " RPM: $R" | |
| echo " Name: $NAME" | |
| echo " Out: $OUT" | |
| # if already installed, do nothing. | |
| [ "$OUT" == "$R" ] && echo && continue | |
| # if not installed, do nothing. | |
| [[ "$OUT" =~ "is not installed" ]] && echo && continue | |
| # if installed but different from $R, then update | |
| [ "$OUT" != "$R" ] && echo " Kindly update $NAME" | |
| echo | |
| done | |
| } | |
| (( 0 )) && { # ? Change file associations. | |
| echo /usr/share/applications/defaults.list | |
| } | |
| (( 0 )) && { # Look for duplicates in trees. | |
| # SIZER=' -size +10240k' # look at all files GT 10240K | |
| SIZER=' -size +0' # look at all files GT 0 | |
| # SIZER="" # do not consider size | |
| # DIRS=". " # look in current dir. | |
| DIRS='/home/ja/temp/downloads/perl/Template-Toolkit-2.15/ /home/ja/temp/RPM/' | |
| # --check-chars=32 will only look at the first 32 characters. | |
| # --all-repeated=prepend | |
| find $DIRS -type f $SIZER -print0 |xargs -0 md5sum |sort \ | |
| |uniq --check-chars=32 --all-repeated=prepend | |
| } | |
| (( 0 )) && { # Test parts of /usr/bin/ldd | |
| printf "Copyright (C) %s Free Software Foundation, Inc. | |
| This is free software; see the source for copying conditions. There is NO | |
| warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
| " "2006" | |
| printf "Written by %s and %s. | |
| " "Roland McGrath" "Ulrich Drepper" | |
| echo | |
| printf $"Copyright (C) %s Free Software Foundation, Inc. | |
| This is free software; see the source for copying conditions. There is NO | |
| warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
| " "2006" | |
| printf $"Written by %s and %s. | |
| " "Roland McGrath" "Ulrich Drepper" | |
| # NO difference in output. | |
| # 2 minor differences: 1) leading $ is not needed. 2) use of a real newline vs. use of \n. | |
| } | |
| (( 0 )) && { # Immutable files | |
| # Even root cannot delete the files. | |
| chattr +i test_file # set immutable flag. | |
| chattr -i test_file # unset | |
| lsattr test_file # see attr properties | |
| # prints: ----i-------- test_file | |
| } | |
| (( 0 )) && { # mtr = "My TraceRoute" | |
| # must be root to run | |
| # i=interval in seconds between ICMP ECHO requests | |
| # /usr/sbin/mtr -i5 74.208.24.115 | |
| /usr/sbin/mtr -i5 www.notbig.org | |
| } | |
| (( 0 )) && { # See when or who changes a file. | |
| # Thanks: http://kbase.redhat.com/faq/docs/DOC-10108 | |
| # make sure auditd is running. | |
| /sbin/chkconfig --list |grep -i 'audit' | |
| service auditd start | |
| # test file. | |
| touch /root/audit-test | |
| # add a "watch" | |
| # -w=watch-file. -p=permissions-to-check. -k=key-name(for easy access, 31 bytes max) | |
| auditctl -w /root/audit-test -p a -k hosts-file | |
| # change the test file. | |
| touch /root/audit-test | |
| # see what audit search says | |
| # -ts=time-start(when to start searching) | |
| ausearch -ts today -k hosts-file | |
| # ---- | |
| # time->Fri Oct 9 08:19:16 2009 | |
| # type=CONFIG_CHANGE msg=audit(1255101556.462:4): auid=4294967295 op=remove rule key="hosts-file" list=4 res=1 | |
| # ---- | |
| # time->Fri Oct 9 08:19:41 2009 | |
| # type=CONFIG_CHANGE msg=audit(1255101581.281:6): auid=4294967295 op=add rule key="hosts-file" list=4 res=1 | |
| auditctl -W /root/audit-test | |
| # got error msg: | |
| # Error sending delete rule data request (No such file or directory) | |
| # ??? | |
| service auditd stop | |
| } | |
| (( 0 )) && { # Peru: expand highlight filename to include full dirname. | |
| for F in /data/oat_2009/stills-03/highlights-peru/*.jpg | |
| do | |
| DN=$(dirname $F) | |
| BN=$(basename $F) | |
| # printf " %-60s %-60s %-10s \n" "$F" "$DN" "$BN" | |
| FN=$(find /data/oat_2009/stills-03/peru -iname "*$BN" -type f) | |
| DN2=$(dirname $FN) | |
| DN3=$(echo $DN2 |sed -e 's;^.*stills-03/;;' -e 's;/;-;g') | |
| # printf " %-60s %-60s %-60s \n" "$FN" "$DN2" "$DN3" | |
| NEWFN="$DN/$DN3-$BN" | |
| # echo " $NEWFN" | |
| echo " Moving from: $F" | |
| echo " to: $NEWFN" | |
| echo | |
| mv "$F" "$NEWFN" | |
| done | |
| } | |
| (( 0 )) && { # Ecuador: expand highlight filename to include full dirname. | |
| for F in /data/oat_2009/stills-03/highlights-ecuador/*.jpg | |
| do | |
| DN=$(dirname $F) | |
| BN=$(basename $F) | |
| # printf " %-60s %-60s %-10s \n" "$F" "$DN" "$BN" | |
| FN=$(find /data/oat_2009/stills-03/ecuador -iname "*$BN" -type f) | |
| DN2=$(dirname $FN) | |
| DN3=$(echo $DN2 |sed -e 's;^.*stills-03/;;' -e 's;/;-;g') | |
| # printf " %-60s %-60s %-60s \n" "$FN" "$DN2" "$DN3" | |
| NEWFN="$DN/$DN3-$BN" | |
| # echo " $NEWFN" | |
| echo " Moving from: $F" | |
| echo " to: $NEWFN" | |
| echo | |
| mv "$F" "$NEWFN" | |
| done | |
| } | |
| (( 0 )) && { # convert filenames from digitdigit-text to letter-text | |
| # eg: 01-blah to a-blah, 02-blah to b-blah, ..., thru 26-blah to z-blah. | |
| # Plan: convert 01 to 1 to a. IE: remove leading zero, then access an array. | |
| CHARS=([1]=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) | |
| TEMPDIR=$(mktemp -d /tmp/filename-convert-test.XXXXXXXXXX) | |
| # Create filenames for testing. | |
| for C in $(seq --format=%02.f 1 21) | |
| do | |
| touch "${TEMPDIR}/${C}-blah" | |
| done | |
| # List before and after filenames. | |
| for F in ${TEMPDIR}/* | |
| do | |
| DN=$(dirname $F) # get dirname | |
| BN=$(basename $F) # get basename | |
| TWO=$(echo $BN |cut -b1-2) # get first 2 characters of basename | |
| TWO2=${TWO#0} # remove leading zero, if exists. | |
| REST=$(echo $BN |cut -b3-) # get third and remaining characters of basename. | |
| NEW="${DN}/${CHARS[$TWO2]}${REST}" | |
| printf " %-50s %2s %2s %2s %50s \n" "$F" "$TWO" "$TWO2" "${CHARS[$TWO2]}" "$NEW" | |
| done | |
| rm ${TEMPDIR}/* | |
| rmdir ${TEMPDIR} | |
| # ToDo | |
| # test for other filenames in dir. | |
| # test for LT 27 filenames. | |
| # test for first two being digits. | |
| # ? | |
| } | |
| (( 0 )) && { # Fetch the front page from Google | |
| exec 3<>/dev/tcp/www.google.com/80 | |
| echo -e "GET / HTTP/1.1\r\nhost: http://www.google.com\r\nConnection: close\r\n\r\n" >&3 | |
| cat <&3 | |
| # The first line causes file descriptor 3 to be opened | |
| # for reading and writing on the specified TCP/IP socket. | |
| # | |
| # This is a special form of the exec statement. From the bash man page: | |
| # exec [-cl] [-a name] [command [arguments]] | |
| # ... If command is not specified, | |
| # any redirections take effect in the current shell, | |
| # and the return status is 0. | |
| # In third line, we read the response out of the socket using cat <&3, | |
| # which reads the response and prints it out. | |
| # The response being the main HTML page from Google. | |
| } | |
| (( 0 )) && { # Using here documments for tests in sed or grep | |
| # In these examples, first) grep non-empty lines and second) del empty lines. | |
| cat <<-EOF | grep . | |
| linha com algo | |
| outra lnha com algo | |
| EOF | |
| # apagando linhas em branco com o sed | |
| cat <<-EOF | sed '/^$/d' | |
| asdfa | |
| asdfa | |
| EOF | |
| } | |
| (( 0 )) && { # Date. Test for last day of the month. | |
| # Might be useful in cronjobs. | |
| [ $(date --date='next day' +'%B') == $(date +'%B') ] \ | |
| || echo 'Today is the last day of this month.' | |
| } | |
| (( 0 )) && { # bash test suite example | |
| # From: http://code.google.com/p/shunit2/wiki/HOWTO_TestAbsolutePathFn | |
| shlib_relToAbsPath() | |
| { | |
| shlib_path_=$1 | |
| # prepend current directory to relative paths | |
| echo "${shlib_path_}" |grep '^/' >/dev/null 2>&1 \ | |
| || shlib_path_="`pwd`/${shlib_path_}" | |
| # clean up the path. if all seds supported true regular expressions, then | |
| # this is what it would be: | |
| shlib_old_=${shlib_path_} | |
| while true; do | |
| shlib_new_=`echo "${shlib_old_}" |sed 's/[^/]*\/\.\.\/*//g;s/\/\.\//\//'` | |
| [ "${shlib_old_}" = "${shlib_new_}" ] && break | |
| shlib_old_=${shlib_new_} | |
| done | |
| echo "${shlib_new_}" | |
| unset shlib_path_ shlib_old_ shlib_new_ | |
| } | |
| testRelToAbsPath() | |
| { | |
| parent=`dirname ${PWD}` | |
| # save stdin and redirect it from an in-line file | |
| exec 9<&0 <<EOF | |
| abc ${PWD}/abc | |
| abc/def ${PWD}/abc/def | |
| abc/def/ghi ${PWD}/abc/def/ghi | |
| abc/./def ${PWD}/abc/def | |
| abc/../def ${PWD}/def | |
| abc/../def/../ghi ${PWD}/ghi | |
| /abc /abc | |
| /abc/def /abc/def | |
| /abc/def/ghi /abc/def/ghi | |
| /abc/def/../../ghi /ghi | |
| /abc/def/ghi/../../jkl /abc/jkl | |
| /abc/../def /def | |
| /abc/../def/../ghi /ghi | |
| ./abc ${PWD}/abc | |
| ../abc ${parent}/abc | |
| ../abc/def ${parent}/abc/def | |
| EOF | |
| while read relPath absPath; do | |
| # ja test | |
| # echo " relPath: $relPath absPath: $absPath" | |
| # printf " relPath: %-25s %s \n" "$relPath" "$absPath" | |
| # continue | |
| # ignore comment and blank lines | |
| echo "${relPath}" |egrep -v "^(#|$)" >/dev/null || continue | |
| # test the function | |
| newPath=`shlib_relToAbsPath "${relPath}"` | |
| # assertEquals "${relPath}" "${absPath}" "${newPath}" | |
| printf " %-35s %-35s %s \n" "${relPath}" "${absPath}" "${newPath}" | |
| done | |
| exec 0<&9 9<&- | |
| } | |
| testRelToAbsPath | |
| } | |
| (( 0 )) && { # get sdparms from attached portable hdd used for backups | |
| DIR=/media/disk | |
| # How many portable hdd devices are attached? | |
| COUNT=$(mount |grep -c "${DIR}") | |
| [ $COUNT -ne 1 ] \ | |
| && echo " There are $COUNT attached portable hdd devices. Kindly investigate. Exiting!" \ | |
| && exit 1 | |
| # Only 1 is attached. Verify it holds a copy of the backups. | |
| [ ! -d "${DIR}/backups/ja" ] \ | |
| && echo ' Dir not found: ${DIR}/backups/ja' \ | |
| && exit 1 | |
| # Get drive name, eg: /dev/sdb; not partition name, eg: /dev/sdb1. | |
| NAME=$(mount |grep "${DIR}" |cut -d' ' -f1 |sed -e 's;[0-9]*$;;') | |
| # Print timestamp, mount options, and sdparms. | |
| echo " =========== Mount options and sdparms for attached portable usb hdd used for backups." | |
| echo " =========== $(date)" | |
| echo | |
| echo " $(mount |grep "${DIR}")" | |
| echo | |
| /usr/bin/sdparm --all --long --long ${NAME} | |
| echo | |
| } | |
| (( 0 )) && { # Read or Change portable HDD parms with sdparms | |
| /usr/bin/sdparm -a # read all | |
| /usr/bin/sdparm --all --long --long /dev/sdb | |
| /usr/bin/sdparm --enumerate --all --long --long /dev/sdb | |
| /usr/bin/sdparm --get=STANDBY /dev/sdb | |
| /usr/bin/sdparm --get=STANDBY=1 /dev/sdb | |
| /usr/bin/sdparm --get=STANDBY --long /dev/sdb | |
| /usr/bin/sdparm --get=STANDBY --long --long /dev/sdb | |
| /usr/bin/sdparm --command=capacity /dev/sdb | |
| /usr/bin/sdparm --inquiry /dev/sdb | |
| /usr/bin/sdparm --inquiry /dev/sdb | |
| /usr/bin/sdparm --page=po /dev/sdb | |
| } | |
| (( 0 )) && { # Notes on changing Seagate hdd parms. | |
| ### After some period of time, the Seagate FreeAgent Go portable hdd goes read-only. | |
| ### 3000 of the 100ms. => 300s, => 5m | |
| ### Messing with the Seagate hdd parms is not enough to easily go from ro to rw on an ad-hoc basis. | |
| ### time passes, ... | |
| ### The process of unmount, then mount, then maybe some hdd parm commands, | |
| ### is more trouble than it is worth. Simpler to use mouse to right-click unmount, | |
| ### then physically remove usb plug, then re-insert usb plug and let the system automount it. | |
| ### | |
| ## But, it might just be easier to turn off the Seagate hdd parm for energy saving. | |
| ## That is: turn of "STANDBY" timer. | |
| ### time passes, ... | |
| (plug-in usb portable hdd) | |
| [root@fundy ~]# date ; touch /media/disk/Sync/test-rw-mount ; ll /media/disk/Sync/test-rw-mount | |
| Mon Sep 28 13:05:23 PDT 2009 | |
| -rw-r--r-- 1 root root 0 Sep 28 13:05 /media/disk/Sync/test-rw-mount | |
| [root@fundy ~]# /usr/bin/sdparm --command=start /dev/sdb; EC=$?; echo " Error Code: $EC" | |
| /dev/sdb: Seagate FreeAgent Go 102D | |
| Error Code: 0 | |
| [root@fundy ~]# /usr/bin/sdparm --clear STANDBY -6 /dev/sdb; EC=$?; echo " Error Code: $EC" | |
| /dev/sdb: Seagate FreeAgent Go 102D | |
| Error Code: 0 | |
| [root@fundy ~]# /usr/bin/sdparm -a /dev/sdb; EC=$?; echo " Error Code: $EC" | |
| /dev/sdb: Seagate FreeAgent Go 102D | |
| Power condition mode page: | |
| IDLE 0 [cha: n, def: 0, sav: 0] | |
| STANDBY 0 [cha: n, def: 1, sav: 0] | |
| ICT 0 [cha: n, def: 0, sav: 0] | |
| SCT 0 [cha: n, def:3000, sav: 0] | |
| Error Code: 0 | |
| [root@fundy ~]# date ; touch /media/disk/Sync/test-rw-mount ; ll /media/disk/Sync/test-rw-mount | |
| Mon Sep 28 13:09:32 PDT 2009 | |
| -rw-r--r-- 1 root root 0 Sep 28 13:09 /media/disk/Sync/test-rw-mount | |
| } | |
| (( 0 )) && { # bashrc for multi-user accounts from remote host. | |
| TTY=`ps |head -n 2|tail -n 1|awk '{print $2}'` | |
| # eg: 3534 pts/5 and-so-on | |
| RIP=`w|grep $TTY|awk '{print $3}'` # remote IP or FQDN, eg fundy.brc.localn | |
| # eg: ja pts/5 fundy.brc.localn and-so-on | |
| # yields: fundy.brc.localn | |
| # NB: the "FROM" column is truncated. Better not match on full name. | |
| case $RIP in | |
| 10.0.100.162 ) export EDITOR=joe ;; | |
| * ) export EDITOR=nano ;; | |
| esac | |
| } | |
| (( 0 )) && { # Text to wave or spoken. | |
| echo "Four score and seven years ago" | /usr/bin/text2wave | aplay 2>/dev/null | |
| } | |
| (( 0 )) && { # Random password generator by Antek Sawicki <[email protected]>, | |
| # From: http://snipt.net/voyeg3r/script-para-gerar-senhas | |
| MATRIX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | |
| # ==> Password will consist of alphanumeric characters. | |
| LENGTH="8" | |
| # ==> May change 'LENGTH' for longer password. | |
| while [ "${n:=1}" -le "$LENGTH" ] | |
| # ==> Recall that := is "default substitution" operator. | |
| # ==> So, if 'n' has not been initialized, set it to 1. | |
| do | |
| PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}" | |
| # ==> Very clever, but tricky. | |
| # ==> Starting from the innermost nesting... | |
| # ==> ${#MATRIX} returns length of array MATRIX. | |
| # ==> $RANDOM%${#MATRIX} returns random number between 1 | |
| # ==> and [length of MATRIX] - 1. | |
| # ==> ${MATRIX:$(($RANDOM%${#MATRIX})):1} | |
| # ==> returns expansion of MATRIX at random position, by length 1. | |
| # ==> See {var:pos:len} parameter substitution in Chapter 9. | |
| # ==> and the associated examples. | |
| # ==> PASS=... simply pastes this result onto previous PASS (concatenation). | |
| # ==> To visualize this more clearly, uncomment the following line | |
| echo "$PASS" | |
| # ==> to see PASS being built up, | |
| # ==> one character at a time, each iteration of the loop. | |
| let n+=1 | |
| # ==> Increment 'n' for next pass. | |
| done | |
| echo "$PASS" # ==> Or, redirect to a file, as desired. | |
| exit 0 | |
| } | |
| (( 0 )) && { # This script creates a web gallery from specified images | |
| #! /bin/sh # Filename: imggallery.sh | |
| # Version: 0.1 | |
| # Date: Thu Feb 12 21:21:28 PST 2009 | |
| # Author: Ian MacGregor (aka ardchoille) | |
| # License: GPL | |
| echo "<html>" > index.html | |
| echo "<head>" >> index.html | |
| echo "<title>My Images</title>" >> index.html | |
| echo "</head>" >> index.html | |
| echo "<body>" >> index.html | |
| echo "<h1> My Images</h1>" >> index.html | |
| for img in *.jpg | |
| do | |
| echo $img convert -scale 120 $img thumb-$img mogrify -scale 640 $img | |
| echo "<a href=\"$img\"><img src=\"thumb-$img\"></a>" >> index.html | |
| done | |
| echo "</body>" >>index.html | |
| echo "</html>" >>index.html | |
| } | |
| (( 0 )) && { # A script from Ted Tso. | |
| # From: Theodore Tso. https://www.redhat.com/archives/ext3-users/2008-January/msg00032.html | |
| # On Tue, Jan 22, 2008 at 02:34:35PM -0800, Valerie Henson wrote: | |
| # > ... the ext3 defaults for forcing a file system check are a little | |
| # > too conservative for many modern use cases. ... | |
| # Yeah. To the extent that people are using devicemapper/LVM | |
| # everywhere, there is a much better solution: | |
| # e2croncheck | |
| VG=closure | |
| VOLUME=root | |
| SNAPSIZE=100m | |
| EMAIL=tytso mit edu | |
| TMPFILE=`mktemp -t e2fsck.log.XXXXXXXXXX` # Use user’s TMPDIR env var if set, else, use /tmp. | |
| set -e | |
| START="$(date +'%Y%m%d%H%M%S')" | |
| lvcreate -s -L ${SNAPSIZE} -n "${VOLUME}-snap" "${VG}/${VOLUME}" | |
| if nice logsave -as $TMPFILE e2fsck -p -C 0 "/dev/${VG}/${VOLUME}-snap" && \ | |
| nice logsave -as $TMPFILE e2fsck -fy -C 0 "/dev/${VG}/${VOLUME}-snap" | |
| then | |
| echo 'Background scrubbing succeeded!' | |
| tune2fs -C 0 -T "${START}" "/dev/${VG}/${VOLUME}" | |
| else | |
| echo 'Background scrubbing failed! Reboot to fsck soon!' | |
| tune2fs -C 16000 -T "19000101" "/dev/${VG}/${VOLUME}" | |
| if test -n "EMAIL"; then | |
| mail -s "E2fsck of /dev/${VG}/${VOLUME} failed!" $EMAIL < $TMPFILE | |
| fi | |
| fi | |
| lvremove -f "${VG}/${VOLUME}-snap" | |
| rm $TMPFILE | |
| } | |
| (( 0 )) && { # get a handle on links. | |
| # how many? Dirs or files? | |
| # do all resolve to a non-link destination | |
| # any other questions? | |
| # How many? Run as root. | |
| # echo ; for D in /bin /boot /etc /lib /root /sbin /selinux /usr /var ; do echo -n " $D "; find $D -type l |wc -l; done ; echo | |
| # prints: | |
| # /bin 19 | |
| # /boot 1 | |
| # /etc 687 | |
| # /lib 88 | |
| # /root 0 | |
| # /sbin 29 | |
| # /selinux 0 | |
| # /usr 13268 | |
| # /var 3 | |
| # find /usr -type l |while read LINK; do [ -d $LINK ] && ls -ld $LINK ; done |wc -l | |
| # prints: 245 | |
| # find /usr -type l |while read LINK; do [ -f $LINK ] && ls -ld $LINK ; done |wc -l | |
| # prints: 13022 | |
| # find /usr -type l |while read LINK; do [ ! -f $LINK ] && [ ! -d $LINK ] && ls -ld $LINK ; done |wc -l | |
| # prints: 1 | |
| # 245 + 13022 + 1 --> 13268 # So, the link is either broken or to a file or to a dir. | |
| # How many of the links point to a dir? | |
| for DIR in /bin /boot /etc /lib /sbin /usr /var ; do find $DIR -type l |while read LINK; do [ -d $LINK ] && echo " Dir: $LINK"; done ; done |wc -l | |
| # prints: 277 | |
| # So, of the ~14100 links, 277 links point to dirs, the rest point to normal files or are broken. | |
| } | |
| (( 0 )) && { # Setup user id and pw. | |
| # NB, in example 1, the -p option requires the encrypted passwd | |
| # In example 2, the password is in plain text. | |
| # example 1 | |
| PWD=`mkpasswd -l 8 -s 2`; export PWD | |
| echo "user = $1 password = $PWD" | |
| /usr/sbin/useradd -c "$2" -m -k /home/skeleton -n -p $PWD $1 | |
| echo $PWD| passwd --stdin $1 | |
| # example 2 | |
| for user in user1 user2 user3 ; do useradd $user ; | |
| echo "password" |passwd --stdin $user ; done | |
| } | |
| (( 0 )) && { # Hash a filename, use first 4 characters of hash to be dir structure for storage of file. | |
| # To put example.txt into a hashed file structure: | |
| echo -n example.txt |md5sum | |
| # prints: e76faa0543e007... - | |
| # Store file at .../e/7/6/f/example.txt | |
| # Or at .../e7/6f/example.txt | |
| # Use a benchmark to see which is better. | |
| } | |
| (( 0 )) && { # 2-dim arrays ## This WORKS! ## But, it is more like "nested arrays", not 2-dim arrays. | |
| # from <[email protected]> on CentOS list. | |
| myArray=("First" "Second" "Third") | |
| First=("Monday" "Tuesdays" "Wednesday") | |
| Second=("One" "Two" "Three") | |
| Third=("A" "B" "C") | |
| for i in ${myArray[@]} | |
| do | |
| echo "$i" | |
| for k in ${i} | |
| do | |
| echo "$i" | |
| eval TMP=\${$k[@]} | |
| echo ${TMP} | |
| done | |
| done | |
| } | |
| (( 0 )) && { # Install CentOS on a USB key. Not complete. | |
| # from John Doe <[email protected]>, CentOS mailing list | |
| # Here's how I did my USB key (minus the kickstart part) but you need a linux (in a VM or from the live CD)...And you will have to change devices names! | |
| # 1. Create a small VFAT partition, then a big linux one: | |
| # fdisk /dev/sdg | |
| # | |
| # Device Boot Start End Blocks Id System | |
| # /dev/sdg1 * 1 3 23126 6 FAT16 | |
| # /dev/sdg2 4 1023 7873380 83 Linux | |
| mkfs.vfat -n BOOT /dev/sdg1 | |
| mkfs.ext2 -m 0 -b 4096 -L DATA /dev/sdg2 | |
| # Unplug/plug => /media/BOOT and /media/DATA | |
| # 2. Install syslinux on the VFAT partition: | |
| syslinux -s /dev/sdg1 | |
| cd /media/BOOT | |
| cp -rv /mnt/cdrom/isolinux syslinux | |
| mv syslinux/isolinux.cfg syslinux/syslinux.cfg | |
| rm -f syslinux/isolinux.bin | |
| vi syslinux/syslinux.cfg | |
| # append method=hd:sda2:/centos | |
| # 3. Copy the CentOS ISOs to the linux partition (I had to use the CD ISOs because the DVD ones would get corrupt on my USB key for some reason): | |
| mkdir /media/DATA/centos | |
| for i in 1 2 3 4 5 6; | |
| do | |
| cp -v CentOS-5.3-i386-bin-${i}of6.iso /media/DATA/centos/; sync; | |
| done | |
| for i in 1 2 3 4 5 6; | |
| do | |
| diff /IOL/CENTOS_repo/CentOS-5.3-i386-bin-${i}of6.iso/ | |
| media/DATA/centos/CentOS-5.3-i386-bin-${i}of6.iso; | |
| done | |
| # 4. Optionaly (?), to be sure that it boots: | |
| # then: dd if=/usr/share/syslinux/mbr.bin of=/dev/sdg | |
| } | |
| (( 0 )) && { # Setup CHS geometry to best utilize device space. 1. | |
| # From: [email protected] | |
| restrk=0 | |
| if [ "$1" = -d ]; then | |
| restrk=1 | |
| echo "Loss due to DOS compatibility mode considered" | |
| shift | |
| fi | |
| if [ -z "$1" -o "$1" = "-h" -o "$1" = "--help" ]; then | |
| echo "Usage: ${0##*/} [-d] total_sectors" >&2 | |
| echo " (Integer expression allowed for total_sectors)" >&2 | |
| exit 1 | |
| fi | |
| tsec=$(( ($1) + 0 )) # Evaluate the input expression | |
| maxspcyl=$((63*255)) # Max possible sectors per cylinder | |
| mincyl=$(($tsec/$maxspcyl)) | |
| [ $mincyl -lt 1 ] && mincyl = 1 | |
| best_cap=0 | |
| cyl=$mincyl | |
| full= | |
| trap "echo \"Interrupted at cyl count = \$cyl\"; exit" 2 | |
| # echo " H * S * C for $tsec total sectors:" | |
| echo " Heads * Sec/trk * Cylinders = Sectors ( bytes)" | |
| # while [ $cyl -le $(($tsec/8)) ]; do | |
| while [ $cyl -le 1600 ]; do | |
| cylsize_p=$(($tsec/$cyl)) | |
| minspt=$(($cylsize_p/255)) | |
| [ $minspt -gt 63 ] && minspt=63 | |
| [ $minspt -lt 1 ] && minspt=1 | |
| spt=$minspt | |
| while [ $spt -le 63 ]; do | |
| hd=$(($cylsize_p/$spt)) # Heads | |
| [ $hd -gt 255 ] && hd=255 | |
| cap=$(($spt*$hd*$cyl)) | |
| pcap=$(($spt*($hd*$cyl - $restrk))) | |
| if [ $pcap -ge $best_cap ]; then | |
| best_cap=$pcap | |
| [ $best_cap = $tsec ] && full=" 100%" | |
| # echo "$hd * $spt * $cyl = $pcap ($(($pcap*512)))$full" | |
| printf " %5d * %7d * %9d = %d (%d)%s \n" "$hd" "$spt" "$cyl" "$pcap" $(($pcap*512)) "$full" | |
| fi | |
| spt=$(($spt+1)) | |
| done | |
| cyl=$((cyl+1)) | |
| done | |
| } | |
| (( 0 )) && { # Setup CHS geometry to best utilize device space. 0. | |
| #!/bin/bash | |
| ######## | |
| #Brute force searches for the CHS geometry that can best utilize a | |
| #device with a given total sector count. For each cylinder count, | |
| #starting with the minimum possible and continuing until the | |
| #cylinder size is reduced to just 8 sectors, it finds the best H | |
| #and S count. A line is written st stdout each time a geometry is | |
| #found that is at least as good as the best one seen so far. | |
| #(Sometimes a later geometry that yields the same sector count is | |
| #in some way "nicer".) | |
| # | |
| #The "-d" option adjusts the calculation to account for the track | |
| #that is wasted for the MBR in DOS compatibility mode. Sometimes a | |
| #smaller track size that wastes fewer sectors will be slightly | |
| #better, though the maximum savings is minimal (55 sectors). | |
| # | |
| #For a large device, you will probably want to interrupt this | |
| #before it runs to completion. Evaluating geometries with millions | |
| #of tiny cylinders can take hours, and those are not likely to be | |
| #considered desirable. | |
| # | |
| #Released to the public domain 15 June 2009 by Robert Nichols | |
| # AT comcast.net I am rnicholsNOSPAM | |
| # (Yes, NOSPAM really is part of my email address.) | |
| ######## | |
| restrk=0 | |
| if [ "$1" = -d ]; then | |
| restrk=1 | |
| echo "Loss due to DOS compatibility mode considered" | |
| shift | |
| fi | |
| if [ -z "$1" -o "$1" = "-h" -o "$1" = "--help" ]; then | |
| echo "Usage: ${0##*/} [-d] total_sectors" >&2 | |
| echo " (Integer expression allowed for total_sectors)" >&2 | |
| exit 1 | |
| fi | |
| tsec=$(( ($1) + 0 )) # Evaluate the input expression | |
| maxspcyl=$((63*255)) # Max possible sectors per cylinder | |
| mincyl=$(($tsec/$maxspcyl)) | |
| [ $mincyl -lt 1 ] && mincyl = 1 | |
| best_cap=0 | |
| cyl=$mincyl | |
| full= | |
| trap "echo \"Interrupted at cyl count = \$cyl\"; exit" 2 | |
| echo " H * S * C for $tsec total sectors:" | |
| while [ $cyl -le $(($tsec/8)) ]; do | |
| cylsize_p=$(($tsec/$cyl)) | |
| minspt=$(($cylsize_p/255)) | |
| [ $minspt -gt 63 ] && minspt=63 | |
| [ $minspt -lt 1 ] && minspt=1 | |
| spt=$minspt | |
| while [ $spt -le 63 ]; do | |
| hd=$(($cylsize_p/$spt)) | |
| [ $hd -gt 255 ] && hd=255 | |
| cap=$(($spt*$hd*$cyl)) | |
| pcap=$(($spt*($hd*$cyl - $restrk))) | |
| if [ $pcap -ge $best_cap ]; then | |
| best_cap=$pcap | |
| [ $best_cap = $tsec ] && full=" 100%" | |
| echo "$hd * $spt * $cyl = $pcap ($(($pcap*512)))$full" | |
| fi | |
| spt=$(($spt+1)) | |
| done | |
| cyl=$((cyl+1)) | |
| done | |
| } | |
| (( 0 )) && { # diff sort 2 files, w/o intermediate files. | |
| diff <(sort file1) <(sort file1) |less | |
| } | |
| (( 0 )) && { # take a snapshot of file state before an upgrade or change. | |
| find . -type f -execdir md5sum {} \; | sort > /tmp/previous | |
| # Do the same after with a different file name and use diff | |
| } | |
| (( 0 )) && { # debug keyboard and mouse events. | |
| echo | |
| # at cli: xev # X events | |
| # note key press event and key release event. | |
| # Use xmodmap to remap keys. | |
| } | |
| (( 0 )) && { # play with exec. Burp! Could not get to work. This does work. | |
| DIR=/home/ja/temp/test-exec | |
| mkdir -p $DIR | |
| LOG=$DIR/log | |
| [ -f $LOG ] && rm $LOG | |
| for X in {1..5} | |
| do | |
| echo "This is line $X of a log file." >> $LOG | |
| done | |
| log_header() { echo "Script started"; } | |
| log_footer() { echo "Script stopped"; } | |
| mail_logs() { cat ${LOG}; } | |
| ( | |
| log_header | |
| mail_logs | |
| log_footer | |
| ) | /bin/mail -s "My Mail Subject, 9" ja | |
| [ -f $LOG ] && rm $LOG | |
| [ -d $DIR ] && rmdir $DIR | |
| } | |
| (( 0 )) && { # another way to do "while read" | |
| # create a file where each row has "string space anotherString" | |
| find ~ja/temp/klm -type f -printf "%k %p\n" > ~ja/temp/klm.new | |
| if [ -f ~ja/temp/klm.old ]; then | |
| cat ~ja/temp/klm.old | while read LINE | |
| do | |
| set $LINE | |
| OLDSIZE=$1 | |
| OLDFILE=$2 | |
| NEWSIZE=`grep "$OLDFILE\$" ~ja/temp/klm.new | cut -d " " -f1` | |
| if [ -n "$NEWSIZE" -a "$OLDSIZE" != "$NEWSIZE" ]; then | |
| echo "$OLDFILE: $OLDSIZE => $NEWSIZE" | |
| fi | |
| done | |
| fi | |
| mv -f ~ja/temp/klm.new ~ja/temp/klm.old | |
| } | |
| (( 0 )) && { # flash-plugin diagnosis | |
| rpm -q flash-plugin | |
| ls -l /usr/lib/mozilla/plugins | |
| mozilla-plugin-config -l | |
| } | |
| (( 0 )) && { # play with the "select" builtin. | |
| echo | |
| echo "This script can make any of the files in this directory private." | |
| echo "Enter the number of the file you want to protect:" | |
| PS3="Your choice: " | |
| QUIT="QUIT THIS PROGRAM - I feel safe now." | |
| touch "$QUIT" | |
| # select FILENAME in *; # works. | |
| # select FILENAME in *.klm *.; # does NOT work. looks for a file "*.klm" | |
| select FILENAME in $(cd ~ja/temp/klm; ls *.klm *.) # does NOT work. | |
| do | |
| case "$FILENAME" in | |
| "$QUIT") echo "Exiting." | |
| break ;; | |
| *) echo "You picked $FILENAME ($REPLY)" | |
| chmod go-rwx "$FILENAME" ;; | |
| esac | |
| done | |
| rm "$QUIT" | |
| } | |
| (( 0 )) && { # traceroute + ping ~= mtr | |
| /usr/sbin/mtr -c 10 -r centos.org | |
| # prints: | |
| # hudson.brc.localnet Snt: 10 Loss% Last Avg Best Wrst StDev | |
| # 192.168.1.1 0.0% 0.5 0.5 0.4 1.0 0.2 | |
| # c-67-172-184-1.hsd1.ca.comcast.net 0.0% 6.1 7.7 6.1 9.2 1.0 | |
| # [...] | |
| # pod22e_aw.layeredtech.com 0.0% 55.5 57.4 55.2 67.7 3.7 | |
| # ??? 100.0 0.0 0.0 0.0 0.0 0.0 | |
| # 162.194.232.72.static.reverse.ltdomains.com 10.0% 56.4 55.9 55.2 56.8 0.6 | |
| # From CentOS list: If the trace gets beyond the "???", | |
| # that's sufficient to imply the packets get through, | |
| # since not all routers respond to the ICMP tests. | |
| } | |
| (( 0 )) && { # verify rkh | |
| gpg --verify rkhunter-1.3.2.tar.gz.asc rkhunter-1.3.2.tar.gz | |
| # prints: gpg: Signature made Wed 27 Feb 2008 18:17:49 SAST using RSA key ID 26447505 | |
| # use ID number | |
| gpg --keyserver subkeys.pgp.net --recv-keys 26447505 | |
| } | |
| (( 0 )) && { # convert postscript doc to ascii. | |
| /usr/bin/ps2ascii /usr/share/doc/iproute-2.6.18/ss.ps |less | |
| } | |
| (( 0 )) && { # Determine what changes an update caused. | |
| # From: Bill Campbell <[email protected]> | |
| # On Tue, Feb 24, 2009, Joseph L. Casale wrote: | |
| # >Is there anything I can use to take an inventory of the filesystem | |
| # >before and after some process to see what's changed? | |
| # I frequently do something like this: | |
| touch /tmp/copyctrl | |
| # do update here | |
| find / ! -type d -newer /tmp/copyctrl | sort > /tmp/changelist | |
| } | |
| (( 0 )) && { # Add sequential numbering as a prefix. | |
| # Given a dir with filenames that are sorted, | |
| # rename to add sequential numbering as a prefix. | |
| SEQ=0 | |
| DIR='/home/ja/public/in_work/Windows/test' | |
| for F in ${DIR}/*.jpg | |
| do | |
| G=$(basename $F) # 000_truck_1.jpg | |
| H=$(echo $G |sed -e 's;[0-9]*_;;') # truck_1.jpg | |
| SEQ=$((SEQ + 1)) # 1 or 23 or ... | |
| I=$(printf "%03d\n" "${SEQ}") # 001 or 023 or ... | |
| echo $F ; #echo $G ; echo $H ; echo "$I" | |
| echo "${DIR}/${I}_${H}" # dir/001_truck_1.jpg | |
| echo | |
| mv $F "${DIR}/${I}_${H}" | |
| done | |
| # 1. make the printf padding large enough to avoid an renaming problems. | |
| # 2. after this executes, remove any un-needed leading zeros. | |
| } | |
| (( 0 )) && { # when doing multiple grep commands, make it easy to change the "pattern" part. | |
| </data/playlists/fav.mplayer grep Maes | |
| # then use up arrow to recall last line; then change last word. | |
| </data/playlists/fav.mplayer grep Rondo | |
| } | |
| (( 0 )) && { # provide a "tree-like" view of dir structure from CURRENT DIR. | |
| # first sed expression replaces content between slashes, eg "/wxyz/" with " |" | |
| # second expr adds a dash in front of dir names. | |
| find . -type d |sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/" | |
| } | |
| (( 0 )) && { # Get the card and device numbers. | |
| # > card 0: NVidia [HDA NVidia], device 3: NVIDIA HDMI [NVIDIA HDMI] | |
| # > Subdevices: 1/1 | |
| # > Subdevice #0: subdevice #0 | |
| # > | |
| # > card 2: HDMI [HDA ATI HDMI], device 3: ATI HDMI [ATI HDMI] | |
| # > Subdevices: 0/1 | |
| # > Subdevice #0: subdevice #0 | |
| # From: John Doe <[email protected]> on CentOS list. | |
| echo " Output of aplay -l" | |
| aplay -l | |
| echo | |
| echo " The card and device numbers" | |
| # aplay -l | grep HDMI | tr ":," "\n" | grep "^card\|^ device" | awk ' { print $2 } ' | |
| # ^^^^ | |
| # the tr command breads the single line into multiple lines for easier access. Nice. | |
| # for my sound card, this works: | |
| aplay -l |grep ^card |tr ',:' "\n" |egrep '^card|^ device' |awk '{print $2}' | |
| # but the output is in a vertical format, which is not real handy. | |
| } | |
| (( 0 )) && { # Centos messages re failure of install at the partitioning part. | |
| echo | |
| # David Hrb?c wrote: are those disks totally empty or there are some partitions? | |
| # Try to look at them with fdisk. BTW sometimes Anaconda fails on disks with partitions. | |
| # Deleting partitions helps before install, sometimes I have to | |
| # "create a new empty DOS partition table" with fdisk | |
| # From: John R Pierce <[email protected]> | |
| # Subject: Re: [CentOS] getting Centos on "used" rackable systems 1U withdualOpteron 248 HE | |
| # or my old standby, boot the centos cd to single user mode, and execute | |
| # | |
| # dd if=/dev/zero of=/dev/sda bs=1024 count=1024 | |
| # | |
| # this zeros the first megabyte of the disk, wiping all traces of partition tables. | |
| # power cycle to clear the state of -everything-, *then* boot the installer... | |
| } | |
| (( 0 )) && { # compare the number of files in a tree on backup hdd to tree on main storage. | |
| # may need to do as root, depending on tree permissions. | |
| # Weed out ~/.<dirname> | |
| cd /media/disk/backups/ja | |
| find . -type f |grep -v '\./\.' |sort >/root/list_of_WD640GB | |
| cd ~ja | |
| find . -type f |grep -v '\./\.' |sort >/root/list_of_home_ja | |
| } | |
| (( 0 )) && { # convert seconds to human-readable. | |
| for SEC in 3 63 3603 90003 # 3sec, 1min3sec, 1hour3sec, 1day1hour3sec | |
| do | |
| ds=$((SEC % 60)) | |
| dm=$(((SEC / 60) % 60)) | |
| dh=$(((SEC / 3600) % 24)) | |
| dd=$((SEC / 86400)) | |
| printf ' Seconds: %8d \tDays Hours Minutes Seconds: %2d %02d %02d %02d\n' $SEC $dd $dh $dm $ds | |
| done | |
| } | |
| (( 0 )) && { # Measure the time taken by parts of a script. | |
| # Thanks: Mitch Frazier at http://www.linuxjournal.com/content/use-date-command-measure-elapsed-time | |
| function timer() | |
| { | |
| if [[ $# -eq 0 ]] | |
| then | |
| # No arguments. Print starting value. | |
| echo $(date '+%s') | |
| else | |
| # At least 1 argument. Print elapsed time. | |
| local stime=$1 | |
| etime=$(date '+%s') | |
| if [[ -z "$stime" ]]; then stime=$etime; fi | |
| dt=$((etime - stime)) | |
| ds=$((dt % 60)) | |
| dm=$(((dt / 60) % 60)) | |
| dh=$((dt / 3600)) | |
| printf '%d:%02d:%02d' $dh $dm $ds | |
| fi | |
| } | |
| t=$(timer) | |
| read -p ' Enter when ready...' p | |
| printf ' Elapsed time: %s\n' $(timer $t) | |
| } | |
| (( 0 )) && { # Convert standard time to unix time | |
| date --date="2009-06-18 18:57" +%s | |
| } | |
| (( 0 )) && { # note the arithmetic expression that controls the loop. | |
| for (( c=1; c<=5; c++ )); { echo " Hi, $c times"; } | |
| } | |
| (( 0 )) && { # setup test cases for files and dirs with embedded double-spaces. | |
| LOC=~ja/temp/test-cases | |
| rm -rf "${LOC}" | |
| mkdir "${LOC}" | |
| touch "${LOC}/a bb c" # verbally: a, space, b, b, space, space, c | |
| mkdir "${LOC}/a aa a" # verbally: a, space, a, a, space, space, a | |
| touch "${LOC}/a aa a/b bb b" # | |
| touch "${LOC}/a aa a/c cc c" # | |
| # When using the "find | while" construct, | |
| # double spaces are replaced by a single space. | |
| # | |
| find "${LOC}" -type f |while read -a F ### double spaces test code. | |
| do | |
| echo " F: ${F[*]}" | |
| [ -f "${F[*]}" ] && echo " IS a file" | |
| [ ! -f "${F[*]}" ] && echo " NOT a file" | |
| done | |
| echo | |
| # When using the "IFS, find" approach, | |
| # the double spaces are preserved. Root! Root! | |
| # | |
| SaveIFS=$IFS | |
| IFS='\ | |
| ' | |
| for G in $(find "${LOC}" -type f) | |
| do | |
| echo " G: $G" | |
| [ -f "$G" ] && echo " IS a file" | |
| [ ! -f "$G" ] && echo " NOT a file" | |
| done | |
| IFS=$SaveIFS | |
| echo | |
| # When using the "ls" approach, | |
| # | |
| ls -d "${LOC}/a aa a" # preserves double spaces. | |
| ls "${LOC}/a aa a" # preserves double spaces. | |
| echo | |
| ls -d "${LOC}/a aa a" |while read -a H; do echo "${H[*]}"; done # does NOT preserve double spaces. | |
| ls "${LOC}/a aa a" |while read -a H; do echo "${H[*]}"; done # does NOT preserve double spaces. | |
| echo | |
| } | |
| (( 0 )) && { # Transfer an entire filesystem from one machine to another. | |
| # (Thanks: http://www.linuxjournal.com/content/copying-filesystem-between-computers) | |
| # | |
| # For example, when you get a new computer, do the following steps. | |
| # 1) Boot both PCs with any Linux live CD (for example, Knoppix), and make sure they can access each other via the network. | |
| # 2) On the source machine, mount the partition containing the filesystem to be copied, and start the transfer using netcat and tar: | |
| # tar options: c=create, z=zip, p=perserve-permissions, s=same-order, f=file | |
| # pv options: b= | |
| cd /mnt/sda1 | |
| tar -czpsf - . | pv -b | nc -l 3333 | |
| # 3) On the destination machine, mount the partition to receive the filesystem, and start the process: | |
| cd /mnt/sda1 | |
| nc 192.168.10.101 3333 | pv -b | tar -xzpsf - | |
| # The nc (netcat) command is used for any kind of TCP connections between two hosts. | |
| # The pv (progress viewer) command is used to display the progress of the transfer. | |
| # tar is used to archive the files on the source machine and un-archive them on the destination. | |
| # Another, unrelated, example: | |
| tar zcf - user | pv /bin/gzip > /tmp/backup.tar.gz | |
| # 59.7kB 0:00:00 [ 223MB/s] [===========================================>] 100% | |
| # for doing what you expect, you need to do something like: | |
| cd /home | |
| size=`du -bs user | sed s/[[:space:]].*$//g` | |
| tar zcf - user | pv -s $size | gzip > /tmp/backup.tar.gz | |
| # 366MB 0:00:33 [ 11MB/s] [=================================>] 100% | |
| # And you will maybe get a “not so high” rate… | |
| } | |
| (( 0 )) && { # How to turn off error messages that are written to the console. | |
| # In a VC: | |
| setterm --msg off | |
| # I have NOT tried this yet. The nfs messages to console on fundy have stopped and I don't know why. | |
| # If the messages start again, try this. | |
| } | |
| (( 0 )) && { # Monitor /var/log/yum for changes. | |
| FILE=/var/log/yum.log | |
| RUN=/var/run/yum | |
| CONTROL=/home/ja/etc/var/control/yum.log.$(hostname -s) | |
| [ ! -f ${CONTROL} ] \ | |
| && touch -r ${FILE} ${CONTROL} \ | |
| && chown ja:ja ${CONTROL} | |
| ! [ ${FILE} -nt ${CONTROL} ] && exit 1 # If file is NOT newer than control, exit. | |
| [ -f ${RUN} ] && exit 1 # bailout if yum is running right now. | |
| touch -r $FILE $CONTROL | |
| echo -e "\tCarry out the required operations HERE." | |
| } | |
| (( 0 )) && { # Monitor a file for changes. | |
| [ $# -lt 1 ] && echo " Kindly specify a file to monitor" && exit 1 | |
| [ ! -f $1 ] && echo " NOT a file: $1" && exit 1 | |
| BN=$(basename $1) | |
| M="/home/ja/temp/filechanges/monitor-$BN" | |
| echo " BN: $BN M: $M" | |
| [ ! -f $M ] && echo " Creating monitor: $M" && touch -r $1 $M | |
| [ $1 -nt $M ] && echo -e "\t$1 is newer than $M. \n\tCarry out your required operations." | |
| touch -r $1 $M | |
| } | |
| (( 0 )) && { # Searching command history. | |
| : <<-MYCOMMENTS | |
| From: "Filipe Brandenburger" <[email protected]> | |
| > Which command I can only select "traceroute 192.168.0.5" to run? | |
| I would type "Ctrl-R" (interactive search history starting with more | |
| recent events), then type "trace", then type "Ctrl-R" again until I | |
| find the command I am looking for, in your case, 4 times. Once you | |
| start using "Ctrl-R" you will probably never want to use "history | | |
| grep ..." and "!..." again. | |
| More: | |
| ctrl-r Start reverse incremental history search mode | |
| When in reverse incremental history search mode: | |
| - type until the desired matching command is found | |
| Enter Retrieve and execute the command. | |
| ctrl-j or Esc Retrieve the command and allow command edit. | |
| ctrl-g Cancel, | |
| ctrl-c Cancel, | |
| From man bash: | |
| ! Start a history substitution, except when followed by a blank, | |
| newline, carriage return, = or ( (when the extglob shell option | |
| is enabled using the shopt builtin). | |
| !n Refer to command line n. | |
| !! Refer to the previous command. This is a synonym for ‘!-1’. | |
| !string | |
| Refer to the most recent command starting with string. | |
| !?string[?] | |
| Refer to the most recent command containing string. The trail- | |
| ing ? may be omitted if string is followed immediately by a newline. | |
| MYCOMMENTS | |
| } | |
| (( 0 )) && { # play with multiple concurrent reads. thanks: www.linuxjournal.com | |
| # have 2 files, with an equal number of lines each. | |
| # combine line 1 from file A with line 1 from file B. etc... | |
| A=~ja/temp/fileA.$$ | |
| echo -e "f1 1\nf1 2\nf1 3\nf1 4" >$A | |
| B=~ja/temp/fileB.$$ | |
| echo -e "f2 1\nf2 2\nf2 3\nf2 4" >$B | |
| while read f1 <&7 ## double spaces naf. | |
| do | |
| read f2 <&8 | |
| echo $f1 $f2 | |
| done \ | |
| 7<$A 8<$B | |
| # prints: | |
| # f1 1 f2 1 | |
| # f1 2 f2 2 | |
| # f1 3 f2 3 | |
| # f1 4 f2 4 | |
| rm $A $B | |
| } | |
| (( 0 )) && { # powertop recommends to disable dvd polling on hudson (F8): | |
| # hal-disable-polling --device /dev/scd0 | |
| # to enable: | |
| # hal-disable-polling --enable-polling --device /dev/scd0 | |
| # how to deterine scd0 or whatever ?? | |
| # dvddp = DVD Disable Polling | |
| alias dvddp hal-disable-polling --enable-polling --device /dev/scd0 | |
| } | |
| (( 0 )) && { # using "set -x" | |
| # prior to execution, set PS4 to a helpful value, eg: export PS4="DEBUG => " | |
| set -x | |
| # from man bash: | |
| # set -x | |
| # After expanding each simple command, for command, case command, select command, or | |
| # arithmetic for command, display the expanded value of PS4, followed by | |
| # the command and its expanded arguments or associated word list. | |
| # loop through and display some test statements | |
| _X=1 | |
| while [[ ${_X} -le 4 ]] | |
| do | |
| [[ ${_X} -lt 2 ]] && echo "X is less than 2!" | |
| _Y=`expr ${_X} + 1` | |
| if [[ ${_Y} -eq 3 ]] | |
| then | |
| echo "Y is now equal to ${_Y}" | |
| fi | |
| _X=${_Y} | |
| done | |
| : <<-MYCOMMENTS | |
| # Prints: | |
| + _X=1 | |
| + [[ 1 -le 4 ]] | |
| + [[ 1 -lt 2 ]] | |
| + echo 'X is less than 2!' | |
| X is less than 2! | |
| ++ expr 1 + 1 | |
| + _Y=2 | |
| + [[ 2 -eq 3 ]] | |
| + _X=2 | |
| + [[ 2 -le 4 ]] | |
| + [[ 2 -lt 2 ]] | |
| ++ expr 2 + 1 | |
| + _Y=3 | |
| + [[ 3 -eq 3 ]] | |
| + echo 'Y is now equal to 3' | |
| Y is now equal to 3 | |
| + _X=3 | |
| + [[ 3 -le 4 ]] | |
| + [[ 3 -lt 2 ]] | |
| ++ expr 3 + 1 | |
| + _Y=4 | |
| + [[ 4 -eq 3 ]] | |
| + _X=4 | |
| + [[ 4 -le 4 ]] | |
| + [[ 4 -lt 2 ]] | |
| ++ expr 4 + 1 | |
| + _Y=5 | |
| + [[ 5 -eq 3 ]] | |
| + _X=5 | |
| + [[ 5 -le 4 ]] | |
| + exit | |
| MYCOMMENTS | |
| exit | |
| } | |
| (( 0 )) && { # Is the current version of rrdtool LT or GT 1.2.7? | |
| # Scripts will fail!! | |
| CURR=$(rrdtool -h |head -n 1 |cut -d' ' -f2) | |
| [[ "$CURR" < "1.2.7" ]] && echo "The current version, $CURR, is less than 1.2.7" | |
| } | |
| (( 0 )) && { # play with RANDOM | |
| echo $(( $RANDOM )) # prints: 0 thru 32767 | |
| echo $(( 5 % 5 )) # prints: 0 | |
| echo $(( $RANDOM % 100 )) # prints: 0 thru 99 | |
| expr $(( $RANDOM % 100 )) + 1 # prints: 1 thru 100 | |
| # for X in {1..10000}; do V=$(expr $(( $RANDOM % 100 )) + 1); [ $V -eq 0 ] && echo $V; done ## 10,000 times. nothing prints. | |
| } | |
| (( 0 )) && { # Search the "man" pages for a keyword | |
| # man -k <keyword> | |
| man -k which |grep ^which | |
| } | |
| (( 0 )) && { # Split a file into parts, based on a pattern match of some lines. | |
| DIR=/home/ja/temp/csplit-test ; mkdir -p $DIR ; cd $DIR | |
| F=./source.txt | |
| cat <<- FILEBOUNDARY > $F | |
| xxx1 | |
| aaa,bbb,ccc,ddd | |
| aba,bab,cdc,dcd | |
| xxx2 | |
| eee,fff,ggg | |
| xxx3 | |
| hhh,iii | |
| xxx2 | |
| eef,ffg,gge,fff | |
| FILEBOUNDARY | |
| # Match on lines that start with "xxx" NB: there are 2 xxx2 parts. | |
| # spit out file parts. | |
| recsep='xxx[0-9]*' | |
| numrecs=$(grep -c "^${recsep}" $F) | |
| if [ ${numrecs} -le 1 ] | |
| then | |
| echo "Only one type of record, not splitting file." && exit 0 | |
| elif [ ${numrecs} -eq 2 ] | |
| then | |
| # %REGEXP%[OFFSET] means: skip to, but not including a matching line | |
| # /REGEXP/[OFFSET] means: copy up to but not including a matching line | |
| # csplit -skf data $F "%^${recsep}%" "/^${recsep}[0-9]*/" # the "[0-9]*" is not needed. always evals to no-match. | |
| csplit -skf data $F "%^${recsep}%" "/^${recsep}/" | |
| else | |
| splitcount=$(expr ${numrecs} - 2) | |
| # {INTEGER} means: repeat the previous pattern the specified number of times | |
| csplit -skf data $F "%^${recsep}%" "/^${recsep}/" \{${splitcount}\} | |
| fi | |
| # combine parts with the same pattern match. (eg: xxx2) | |
| for I in $(ls data*) | |
| do | |
| O=$(head -n 1 $I) | |
| grep -v $O $I >> $O | |
| done | |
| } | |
| (( 0 )) && { # Test an IP address for validity: | |
| function valid_ip() | |
| { | |
| local ip=$1 stat=1 | |
| if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] | |
| then | |
| OIFS=$IFS # save Internal Field Separator | |
| IFS='.' | |
| ip=($ip) # create array for ip parts. | |
| IFS=$OIFS | |
| [[ ${ip[0]} -le 255 \ | |
| && ${ip[1]} -le 255 \ | |
| && ${ip[2]} -le 255 \ | |
| && ${ip[3]} -le 255 ]] | |
| stat=$? # status of logical expr. | |
| fi | |
| return $stat # returns status of logical expr. | |
| } | |
| ips=' 4.2.2.2 a.b.c.d 192.168.1.1 | |
| 0.0.0.0 255.255.255.255 255.255.255.256 | |
| 192.168.0.1 192.168.0 1234.123.123.123 | |
| ' | |
| for ip in $ips | |
| do | |
| # valid_ip IP_ADDRESS | |
| # if [[ $? -eq 0 ]]; then echo good; else echo bad; fi | |
| if valid_ip $ip; then stat='good'; else stat='bad'; fi # check return status | |
| printf "%-20s: %s\n" "$ip" "$stat" | |
| done | |
| } | |
| (( 0 )) && { # Note relational expression. First parm MATCHES prog OR second parm EQUALS 4. | |
| rpcinfo -p |while read -a L # double spaces naf. | |
| do | |
| [[ ${L[0]} =~ prog || ${L[1]} -eq 4 ]] \ | |
| && printf "%10s %4s %5s %6s %s \n" ${L[*]} | |
| done | |
| } | |
| (( 0 )) && { # overwrite a file with random data. Do it 10 times. | |
| # First, find the number of bytes in the file. Eg, ll /root/Trash | |
| # Then use that value. Eg, bs=111110 | |
| # Options: | |
| # notrunc do not truncate the output file | |
| # noerror continue after read errors | |
| F=/root/Trash | |
| #for N in $(seq 10); do dd if=/dev/urandom of=$F bs=111110 count=1 conv=notrunc,noerror; done | |
| } | |
| (( 0 )) && { # play with bash built-in regular expression comparison operator "=~". | |
| # Thanks: http://www.linuxjournal.com/content/bash-regular-expressions | |
| # | |
| # Execute: $0 'aa(b{2,3}[xyz])cc' aabbxcc aabbcc | |
| # Prints: | |
| # regex: aa(b{2,3}[xyz])cc | |
| # aabbxcc matches | |
| # capture[1]: bbx | |
| # aabbcc does not match | |
| # Matches are assigned to an array BASH_REMATCH. | |
| # The entire match is assigned to BASH_REMATCH[0], the first sub-pattern to BASH_REMATCH[1], etc.. | |
| [ $# -lt 2 ] && echo "Usage: $0 PATTERN STRINGS..." && exit 1 | |
| regex=$1 | |
| echo -e "regex: $regex \n" | |
| shift | |
| for S in $@ | |
| do | |
| if [[ $S =~ $regex ]] | |
| then | |
| echo "$S matches" | |
| # for SubPattern in ${BASH_REMATCH[@]}; do echo " $SubPattern"; done | |
| N=${#BASH_REMATCH[*]} | |
| N=$((N-1)) | |
| for i in $( seq 0 $N ) ; do echo " capture[$i]: ${BASH_REMATCH[$i]}" ; done | |
| else | |
| echo "$S does not match" | |
| fi | |
| echo | |
| done | |
| } | |
| (( 0 )) && { # cli packet capture | |
| echo | |
| # tshark udp port 1234 | |
| # or | |
| # tcpdump -i <interface> udp port <port> | |
| # | |
| # or: tcpdump -i eth0 port 4957 -nn -vv | |
| # or: tcpdump -i ethX -p -s 0 -w /path/to/4957.trace.pcap port 4957 | |
| # tcpdump options: | |
| # -w=write packets to a file | |
| # -p=Do NOT put interface in promiscuous mode. | |
| # -s 0=snarf 0 bytes of data from each packet,rather than the default 68. see man page. | |
| # -n=Do NOT convert host addresses to names. Avoids dns lookup. | |
| # -nn=Do NOT convert protocol and port numbers to names either. | |
| # -vv=verbose level. | |
| # Other info from CentOS list. | |
| tcpdump -i eth0 -s 0 -w capture.cap # Creates file capture.cap. Read with wireshark. | |
| tcpdump -i eth0 -s 0 -w capture.cap not port 22 # will drop all SSH traffic | |
| # tcpdump -i eth0 -s 0 -w capture.cap not host <ip> # will drop traffic to/from <ip> | |
| } | |
| (( 0 )) && { # feed passwords to an app. | |
| # > It reads the first insertion, but asks for the second. | |
| (echo secret; echo secret) | pure-pw ... | |
| # Or: echo -e 'secret\nsecret' | pure-pw | |
| # Or: pure-pw <<EOF | |
| # secret | |
| # secret | |
| # EOF | |
| } | |
| (( 0 )) && { # find MAC addresses of hosts on local network. | |
| /sbin/arp -a # all hosts | |
| # prints: | |
| # fundy.brc.localnet (192.168.1.15) at 00:1A:4D:4A:92:59 [ether] on eth0 | |
| # ? (192.168.1.1) at 00:18:39:5B:75:C0 [ether] on eth0 | |
| # the "?" indicates that this host is not in /etc/hosts (at least, maybe more) | |
| nmap -sP -n 192.168.1.15 # run as root. | |
| # prints: | |
| # Starting Nmap 4.52 ( http://insecure.org ) at 2008-05-08 12:52 PDT | |
| # Host 192.168.1.15 appears to be up. | |
| # MAC Address: 00:1A:4D:4A:92:59 (Gigabyte Technology Co.) | |
| # Nmap done: 1 IP address (1 host up) scanned in 0.138 seconds | |
| cat /sys/class/net/eth0/address | |
| # On hudson, 2009.06.29, prints: | |
| # 00:1a:4d:56:7e:af | |
| } | |
| (( 0 )) && { # Copy a CD or DVD with dd, linux journal, April 18th, 2008 by Mitch Frazier | |
| echo | |
| # If you need to copy a CD to your hard drive: | |
| # prompt@shell$ dd if=/dev/cdrom of=/path/to/cdcopy.iso | |
| # For a DVD: | |
| # prompt@shell$ dd if=/dev/dvd of=/path/to/dvdcopy.iso | |
| } | |
| (( 0 )) && { # which cli commands are used most frequently ? | |
| history |awk '{a[$2]++} END{for(i in a){ printf "%5d\t%s \n",a[i],i}}' |sort -rn |head | |
| } | |
| (( 0 )) && { # LABEL and UUID | |
| cat /etc/fstab |grep LABEL # prints: LABEL=/boot /boot ext3 defaults 1 2 (squeezed spaces) | |
| findfs LABEL=/boot # prints: /dev/sda1 | |
| /lib/udev/vol_id /dev/sda1 # prints: | |
| # ID_FS_USAGE=filesystem | |
| # ID_FS_TYPE=ext3 | |
| # ID_FS_VERSION=1.0 | |
| # ID_FS_UUID=e7de78af-bee4-4c9a-a861-0c57c97eb0d0 | |
| # ID_FS_UUID_ENC=e7de78af-bee4-4c9a-a861-0c57c97eb0d0 | |
| # ID_FS_LABEL=/boot | |
| # ID_FS_LABEL_ENC=\x2fboot | |
| # ID_FS_LABEL_SAFE=boot | |
| # see also: /dev/disk/by-{id,label,path,uuid} on Fedora8. | |
| # using block id | |
| /sbin/blkid # prints: | |
| # /dev/mapper/VolGroup00-LogVol01: TYPE="swap" UUID="eb64262e-1824-450d-b8bd-720759851c2a" | |
| # /dev/mapper/VolGroup00-LogVol00: UUID="2946a991-25c5-49eb-97cf-572e8d89dfe2" SEC_TYPE="ext2" TYPE="ext3" | |
| # /dev/sda1: LABEL="/boot" UUID="e7de78af-bee4-4c9a-a861-0c57c97eb0d0" SEC_TYPE="ext2" TYPE="ext3" | |
| # /dev/VolGroup00/LogVol00: UUID="2946a991-25c5-49eb-97cf-572e8d89dfe2" SEC_TYPE="ext2" TYPE="ext3" | |
| # so, parse as needed. | |
| # or: | |
| tune2fs -l /dev/sda1 |egrep '^Filesystem UUID|^Filesystem volume' # prints: | |
| # Filesystem volume name: /boot | |
| # Filesystem UUID: e7de78af-bee4-4c9a-a861-0c57c97eb0d0 | |
| } | |
| (( 0 )) && { # play with seq | |
| echo $(seq 4) # prints: 1 2 3 4 | |
| echo $(seq 1 4) # prints: 1 2 3 4 | |
| echo $(seq 2 2 8) # prints: 2 4 6 8 | |
| echo $(seq --format='Num: %g, ' 4) # prints: Num: 1, Num: 2, Num: 3, Num: 4, | |
| echo $(seq --format=%003.f 1 12) # prints: 001 002 003 004 005 006 007 008 009 010 011 012 | |
| echo $(seq --separator=', ' 4) # prints: 1, 2, 3, 4 | |
| echo $(seq --equal-width 8 12) # prints: 08 09 10 11 12 | |
| } | |
| (( 0 )) && { # compare seq and {..} | |
| message='Test Message' | |
| # for n in $(seq 0 9); do echo -en "$n "; done; echo | |
| # for n in {0..9}; do echo -en "$n "; done; echo | |
| ### SAME output !! | |
| # for n in $(seq 0 $(expr ${#message} - 1)); do echo -en "$n "; done; echo | |
| # for n in {0..$(expr ${#message} - 1)}; do echo -en "$n "; done; echo | |
| ### NOT same !! | |
| # So, ... do NOT plan on any expansion / intrepretation within {..} construct. | |
| # Do NOT even use a variable. | |
| } | |
| (( 0 )) && { # Arguments with embedded spaces. | |
| # | |
| # from: Jacques B. jjrboucher at gmail.com | |
| # at: http://lists.centos.org/pipermail/centos/2008-February/095012.html | |
| # Invoke eg: ./scriptname one "two three" four "five;six\"" seven eight 'nine ten' | |
| E_BADARGS=65 | |
| [ ! -n "$1" ] && echo "Kindly specify an argument." && exit $E_BADARGS | |
| index=1 # Initialize count. | |
| echo -e "\nListing args with \$* (unquoted):" | |
| for arg in $* | |
| do | |
| echo "Arg #$index = $arg" | |
| let "index+=1" | |
| done | |
| echo "Breaks up args with embedded spaces." | |
| index=1 # Initialize count. | |
| echo -e "\nListing args with \"\$*\":" | |
| for arg in "$*" # Doesn't work properly if "$*" isn't quoted. | |
| do | |
| echo "Arg #$index = $arg" | |
| let "index+=1" | |
| done | |
| echo "Entire arg list seen as single word." | |
| index=1 # Initialize count. | |
| echo -e "\nListing args with \"\$@\":" | |
| for arg in "$@" | |
| do | |
| echo "Arg #$index = $arg" | |
| let "index+=1" | |
| done | |
| echo "Arg list correctly seen as separate words." | |
| echo ; exit 0 | |
| } | |
| (( 0 )) && { # filenames with embedded spaces. | |
| Dir=~ja/temp/spaces | |
| [ -d $Dir ] || mkdir -p $Dir | |
| cd $Dir | |
| touch "one" "two" "one two" "one two three" | |
| for F in *; do echo $F; done # prints 4 lines, as expected. | |
| for F in $(ls .); do echo $F; done # prints 7 lines. | |
| for F in $(ls .); do echo "$F"; done # prints 7 lines. | |
| for F in $(ls *); do echo "$F"; done # prints 7 lines. | |
| for F in $@; do echo $F; done # prints nothing | |
| for F in $*; do echo $F; done # prints nothing | |
| for F in "$@"; do echo $F; done # prints nothing | |
| } | |
| (( 0 )) && { # info on eth0 | |
| # must be root to run | |
| NIC=eth0 | |
| echo -e "\t\"ethtool\" info for $NIC \n\t===================== \n" | |
| # -a=pause settings -g=ring parms -i=driver info -k=offload settings and parms. -S=statistics. | |
| for OPTION in "" -a -g -i -k -S | |
| do | |
| echo -e "\n\n\t===== Option: $OPTION \n" | |
| /sbin/ethtool $OPTION $NIC | |
| done | |
| echo -e "\n\n\tFor more info, use iptraf." | |
| } | |
| (( 0 )) && { # check for 64 vs 32 | |
| echo -n "Running " | |
| RES=`uname -a | grep 64` | |
| if [ $? -eq 0 ] | |
| then echo -n "64-bit " | |
| else echo -n "32-bit " | |
| fi | |
| echo -n "operating system on a " | |
| RES=`cat /proc/cpuinfo | grep " lm "` # lm is one of the flags. | |
| if [ $? -eq 0 ] | |
| then echo -n "64-bit " | |
| else echo -n "32-bit " | |
| fi | |
| echo "machine" # machine =? cpu. | |
| } | |
| (( 0 )) && { # Is DPMS enabled as an extension in my setup? | |
| xdpyinfo |grep DPMS | |
| # Is DPMS currently on? | |
| xset q | |
| } | |
| (( 0 )) && { # find broken links. | |
| [ $# -lt 1 ] && echo -e "\tKindly specify a dir" && exit 1 | |
| [ ! -d $1 ] && echo -e "\tNOT a dir: $1" && exit 1 | |
| for i in $(find $1 -type l) # From: "Christian Volker" <[email protected]> on CentOS list. | |
| do # $1 directory to search | |
| file $i | grep -q broken # Exits with zero status if any match is found. | |
| if [ $? -eq 0 ] ; then echo "Broken link: $i"; fi | |
| done | |
| } | |
| (( 0 )) && { # list files as a quoted, comma-separated list. | |
| # m = full width with a comma separated list of entries. | |
| # Q = enclose entry names in double quotes. | |
| ls -Qm ~/bin/*.pl | |
| } | |
| (( 0 )) && { # remove duplicates but preserve original order if items. | |
| F=~/temp/numbers | |
| cat > $F <<-EOF | |
| one | |
| two | |
| three | |
| one | |
| three | |
| four | |
| EOF | |
| nl numbers |sort -k2 -u |sort -n |cut -f2 | |
| } | |
| (( 0 )) && { # man file to text file. | |
| man foo |col -b > foo.txt | |
| } | |
| (( 0 )) && { # see if the centos torrent site is up. | |
| nmap -sT -p6969 -vv torrent.centos.org | |
| # port scan | |
| nmap -p 1-1024 192.168.1.10 | |
| # Prints: | |
| # Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2010-09-13 17:08 PDT | |
| # Note: Host seems down. If it is really up, but blocking our ping probes, try -P0 | |
| # Nmap finished: 1 IP address (0 hosts up) scanned in 3.003 seconds | |
| # post scan, treats all hosts as online. | |
| nmap -p 1-1024 -P0 192.168.1.10 | |
| # Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2010-09-13 17:09 PDT | |
| # Interesting ports on pacific.brc.localnet (192.168.1.10): | |
| # Not shown: 1022 filtered ports | |
| # PORT STATE SERVICE | |
| # 22/tcp open ssh | |
| # 631/tcp closed ipp | |
| } | |
| (( 0 )) && { # get a list of IP addresses on network | |
| # -sP is ping scanning. | |
| # -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans | |
| # -P0: Treat all hosts as online -- skip host discovery | |
| # -O: Enable OS detection | |
| # -A is os scanning, version detection, and more. | |
| # -T4 is agressive timing. ie hammer the hosts. | |
| # -p <port ranges>: Only scan specified ports | |
| # -n/-R: Never do DNS resolution/Always resolve [default: sometimes] | |
| nmap -sP 192.168.1.0/24 | |
| # prints: | |
| # Starting nmap 3.70 ( http://www.insecure.org/nmap/ ) at 2007-12-16 15:49 PST | |
| # Host 192.168.1.1 appears to be up. | |
| # MAC Address: 00:18:39:5B:75:C0 (Unknown) | |
| # Host pacific.brc.localnet (192.168.1.10) appears to be up. | |
| # Host baffin.brc.localnet (192.168.1.11) appears to be up. | |
| # MAC Address: 00:1A:4D:40:E7:F1 (Unknown) | |
| # Host quiettoo.brc.localnet (192.168.1.12) appears to be up. | |
| # MAC Address: 00:0F:EA:23:9C:64 (Giga-Byte Technology Co.) | |
| # Host fundy.brc.localnet (192.168.1.15) appears to be up. | |
| # MAC Address: 00:1A:4D:4A:92:59 (Unknown) | |
| # Nmap run completed -- 256 IP addresses (5 hosts up) scanned in 5.624 seconds | |
| } | |
| (( 0 )) && { # FUNCNAME is an array that has a list of functions being executed, as far back as "main". | |
| # "caller" identifies where a subroutine was called from. | |
| test_a(){ echo "My name is test_a" ; caller 0 ; echo ${FUNCNAME[@]} ; echo ${BASH_LINENO[@]} ; } | |
| test_b() | |
| { | |
| echo "My name is test_b"; | |
| caller 0 ; echo ${FUNCNAME[@]} ; echo ${BASH_LINENO[@]} ; | |
| test_a; # this is line 18 | |
| # this section turns out to be redundant. | |
| caller 0 ; echo ${FUNCNAME[@]} ; echo ${BASH_LINENO[@]}; | |
| } | |
| test_b # this is line 24. | |
| # prints: | |
| # My name is test_b | |
| # 24 main /home/ja/bin/code_bash.sh # caller | |
| # test_b main # funcname | |
| # 24 0 # lineno | |
| # My name is test_a | |
| # 18 test_b /home/ja/bin/code_bash.sh | |
| # test_a test_b main | |
| # 18 24 0 | |
| # 24 main /home/ja/bin/code_bash.sh # redundant with above output from caller | |
| # test_b main # redundant with above output from funcname | |
| # 24 0 # redundant with above output from lineno | |
| } | |
| (( 0 )) && { # backups with split. | |
| # t ~= 240K. bzips to ~63K. | |
| cat t |bzip2 |(split -b 10k - dump.bz2.) | |
| # creates 7 files named dump.bz2.xa{a,b,c,d,e,f,g}, each 10k except the last. | |
| # "cat t |bzip2 |tee >(split -b 10k - dump.bz2.) |md5sum > t.md5" does not finish, but it works. | |
| # Thanks: Ray Van Dolson <[email protected]> | |
| mkfifo t.fifo | |
| (split t.fifo -b 10k) & | |
| cat t |bzip2 |tee t.fifo |md5sum | |
| rm -f t.fifo | |
| # create a pipe. in the background, split the pipe. | |
| # then create the splits and the md5sum. | |
| } | |
| (( 0 )) && { # get bios, system, ... info. run as root. | |
| /usr/sbin/dmidecode |less # all info | |
| /usr/sbin/dmidecode -s bios-vendor # string. from a list in man page | |
| /usr/sbin/dmidecode -t bios # type. | |
| /usr/sbin/dmidecode -t 1,2,3 # type | |
| hdparm -i /dev/sda # get hard disk info reported during boot. Includes serial number for a WD disk. | |
| hdparm -i /dev/dvd # info, but no serial number. | |
| /usr/bin/hal-device |less # on hudson, about 2000 lines of info. | |
| } | |
| (( 0 )) && { # using "less" or "man", set a mark and, later, return to it. | |
| # | |
| # set a mark: press "m" and then a letter. (case sensitive) | |
| # return to mark: press "'" and the letter. | |
| # run a command while in "less" or "man" | |
| # | |
| # exclaimation mark "!", type command | |
| # press "return" to return to less or man. | |
| echo | |
| } | |
| (( 0 )) && { # netstat options | |
| # | |
| # p Show the PID and name of the program to which each socket belongs. | |
| # l Show only listening sockets. | |
| # u udp | |
| # t tcp | |
| # n numeric | |
| # a Show both listening and non-listening sockets. | |
| With the --interfaces option, show interfaces that are not marked | |
| # s Display summary statistics for each protocol. | |
| netstat -plutn | |
| options compare: | |
| -nap 343 lines. | |
| -nap |grep LISTEN 44 lines. | |
| -nlp 61 lines. | |
| -nlp |grep LISTEN 44 lines. Apparently no different than -nap |grep LISTEN | |
| -nlp |grep -v LISTEN 17 lines. all udp. | |
| -plutn 28 lines. tcp and udp. looks useful! | |
| } | |
| (( 0 )) && { # try these options with diff. | |
| diff --suppress-common-lines --side-by-side /etc/inittab{,.original} | |
| # prints: id:3:initdefault: | id:5:initdefault: | |
| # how is the above different from this: sdiff -s | |
| # from man sdiff: | |
| # sdiff without -o (or --output) produces a side-by-side difference. This usage is obsolete; use diff --side-by-side instead | |
| # -s --suppress-common-lines Do not print common lines. | |
| # So, ... don't use. | |
| } | |
| (( 0 )) && { # Given a dir with several/many image files, identify duplicates. | |
| # Sort by size, then compare file1 vs file2, file2 vs file3, ... | |
| # If no diff, remove prev. | |
| DIR=/tmp/windowmovie | |
| PREV='' | |
| echo " There are $(ls $DIR/*.xwd |wc -l) files in $DIR" | |
| for F in $(ls -S $DIR/*.xwd) | |
| do | |
| if [ -z $PREV ] | |
| then | |
| PREV=$F | |
| continue | |
| else | |
| echo " Prev: $PREV Curr: $F" | |
| DIFF=$(diff $PREV $F) | |
| [ -z "$DIFF" ] && echo " rm: $PREV" && rm $PREV | |
| PREV=$F | |
| fi | |
| done | |
| } | |
| (( 0 )) && { # Use diff Result Code. | |
| # An exit status of 0 means no differences were found, | |
| # 1 means some differences were found, and 2 means trouble. | |
| diff ~/temp/iptable_notes{,_copy} | |
| EC=$? | |
| [ $EC -eq 2 ] && echo -e "\tError code is 2, which means trouble." | |
| [ $EC -eq 1 ] && echo -e "\tError code is 1, which means differences." | |
| [ $EC -eq 0 ] && echo -e "\tError code is 0, which means no differences." | |
| [ $EC -ne 0 ] && echo "\n\tThe files are different." | |
| } | |
| (( 0 )) && { # diff versus cmp. which is faster? 1. | |
| # compare tarballs on DVD vs harddisk | |
| dir1=/data/bu/diff/ja | |
| dir2=/data/bu/bu_users/ja | |
| echo -e "\tDir1: $dir1 \tDir2: $dir2" | |
| tarballs=$(find "$dir2" \( -iname '*.gz' -or -iname '*.tar' \) \ | |
| -type f -print |sed -e 's/\/data\/bu\/bu_users\/ja\///') | |
| # echo -e "\n\tTarballs: \n$tarballs" | |
| echo -e "\tCompare test 1: diff -- mainly for loading" | |
| time { for f in $tarballs; do echo -en "."; diff $dir1/$f $dir2/$f; done }; echo | |
| echo -e "\tCompare test 2: cmp" | |
| time { for f in $tarballs; do echo -en "."; cmp $dir1/$f $dir2/$f; done }; echo | |
| echo -e "\tCompare test 3: diff" | |
| time { for f in $tarballs; do echo -en "."; diff $dir1/$f $dir2/$f; done }; echo | |
| # results: on pacific: 6:41 vs 6:48; diff is 7sec faster, about 1sec/min, not sig. | |
| # on q2: 9:55 vs 10:00; diff is 5sec faster, not sig. | |
| # So, ... use diff, forget cmp. | |
| } | |
| (( 0 )) && { # diff versus cmp. which is faster? 0. | |
| # compare tarballs on DVD vs harddisk | |
| dir1=/data/bu/diff/elh | |
| dir2=/data/bu/bu_users/elh | |
| echo -e "\tDir1: $dir1 \tDir2: $dir2" | |
| tarballs=$(find "$dir2" \( -iname '*.gz' -or -iname '*.tar' \) \ | |
| -type f -print |sed -e 's/\/data\/bu\/bu_users\/elh\///') | |
| # echo -e "\n\tTarballs: \n$tarballs" | |
| echo -e "\tCompare test 1: diff -- mainly for loading" | |
| time { for f in $tarballs; do echo -en "."; diff $dir1/$f $dir2/$f; done }; echo | |
| echo -e "\tCompare test 2: cmp" | |
| time { for f in $tarballs; do echo -en "."; cmp $dir1/$f $dir2/$f; done }; echo | |
| echo -e "\tCompare test 3: diff" | |
| time { for f in $tarballs; do echo -en "."; diff $dir1/$f $dir2/$f; done }; echo | |
| # results: on pacific: cmp was 1:29 vs diff was 1:35 | |
| # on q2: no sig difference | |
| } | |
| (( 0 )) && { # list open files, lsof | |
| # /usr/sbin/lsof # lists all open files belonging to all active processes | |
| # gives over 4000 open files on pacific | |
| # headings: COMMAND, PID, USER, FD, TYPE, DEVICE, SIZE NODE, NAME | |
| # FD=FileDescriptor. see man lsof. | |
| lsof |egrep -i 'COMMAND|Deleted' |less # list files that have been deleted (eg with rm) but the owning process has not yet finished. | |
| # /usr/sbin/lsof /bin/bash # lists all processes that use bash | |
| # 6 files: bash, startx, firefox, run-mozil, bash, bash | |
| # /usr/sbin/lsof -p 40 # list open files for process with PID 40 | |
| # lists 3 files: pdflush, pdflush, pdflush | |
| # /usr/sbin/lsof +D /tmp # lists all open files in /tmp and its' subdirs, w/o symbolic links | |
| # lists 139 files on pacific | |
| # /usr/sbin/lsof -u ja # list for specified user. Over 2400 for ja | |
| # /usr/sbin/lsof -u ^root # list for all users, except root. | |
| # /usr/sbin/lsof -d txt # shows a process list, similar to ps aux, by listing entires | |
| # with the file descriptor entry of txt. | |
| # /usr/sbin/lsof -u ja +L # shows link count for each file | |
| # /usr/sbin/lsof -u ja +L8 # shows files with link count less than 8 | |
| # /usr/sbin/lsof +L1 # shows files that have been unlinked, ie: none. | |
| # /usr/sbin/lsof -i # shows network-related files. ~43. | |
| # /usr/sbin/lsof -i -P -n # don't convert port number to port name, and don't resolve hostnames(for speed) | |
| # /usr/sbin/lsof -i |grep '\->' # ESTABLISHED connections. | |
| # /usr/sbin/lsof -a -i -u ntp # all open network files for the ntp account(AND relation -a) | |
| # /usr/sbin/lsof -t /dev/cdrom # lists PIDs accessing cdrom. Helpful when cannpt unmount CD. | |
| # /usr/sbin/lsof -i TCP -n -P \ | |
| # |awk '/LISTEN/ {print $1"/"$3"/"$8}' # lists open ports, process names, user-names, interfaces. | |
| /usr/sbin/lsof -i TCP -n -P \ | |
| |awk '/LISTEN/ {print $1"/"$3"/"$8}' \ | |
| |sort -u # same as above, and sort unique. | |
| # print the currently playing tune on baffin, under the elh login. | |
| /usr/sbin/lsof |grep elh |egrep '\.mp3$|\.ogg$' |awk '{print $9}'; echo | |
| } | |
| (( 0 )) && { # rsync options: | |
| : <<-MYCOMMENTS | |
| -a archive mode, equivalent to -rlptgoD | |
| (recursion and preserve almost everything.) | |
| -u update only (don’t overwrite newer files) | |
| -v verbose | |
| -e, --rsh=COMMAND specify the remote shell, eg: -e ssh | |
| -P, --partial keep partially transferred files | |
| -z, --compress compress file data | |
| --progress show progress during transfer. (Very verbose.) | |
| --exclude <pattern> exclude files matching some pattern, eg: "*~" | |
| --delete delete files that don’t exist on sender | |
| -n, --dry-run show what would have been transferred. | |
| Good to use with --delete "initially" | |
| -b, --backup make backups (see --suffix & --backup-dir) | |
| --backup-dir=DIR make backups into hierarchy based in DIR. good for incremental backups. | |
| --suffix=SUFFIX backup suffix (default ~ w/o --backup-dir) | |
| --delete --backup --backup-dir=$MIRROR_DIR/RsyncBckups --suffix=".$DATE" | |
| Allows you to keep an exact duplication of the original directory and | |
| keeping the original files that were either deleted or overwritten in | |
| a seperate backup directory with dated suffixes, which can be archived | |
| on some regular basis. | |
| rsync -a # for manual rsync within LAN. | |
| rsync -auv -e ssh --exclude <patt> # for scripted rsync to 1and1 (to keep a log). | |
| MYCOMMENTS | |
| } | |
| (( 0 )) && { # wrap with xargs -n | |
| echo "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" |xargs -n 5 | |
| } | |
| (( 0 )) && { # Problem with xargs. features ? | |
| # On baffin: /usr/local/bin is not empty. /usr/local/sbin is empty. | |
| for d in /usr/local/bin /usr/local/sbin | |
| do | |
| echo -e "\n\t========== $d " | |
| find $d -type f -print |xargs ls -al # lists current dir if $d is empty | |
| EC=$? ; echo $EC # prints: 0 | |
| done | |
| # also shows: | |
| echo '' |xargs ls -al # prints current dir. | |
| # Just like "ls -al" would with no addnl parms. | |
| } | |
| (( 0 )) && { # Get entries from the specified administrative database using the specified search keys. | |
| # Database is one of: aliases, ethers, group, hosts, netgroup, networks, | |
| # passwd, protocols, rpc, services or shadow. | |
| # for db in aliases ethers group hosts netgroup networks passwd protocols rpc services shadow | |
| for db in passwd | |
| do | |
| echo -e "\tDatabase: $db" | |
| eval getent $db | |
| echo | |
| done | |
| } | |
| (( 0 )) && { # bash test operators. quoted variables. | |
| a='' | |
| [ -n "$a" ] && echo "A is non-null" # prints: | |
| [ -z "$a" ] && echo "A has a length of zero" # prints: A has a length of zero | |
| echo "A: ***$a***" # prints: A: ****** | |
| [ -n "$b" ] && echo "B is non-null" # prints: | |
| [ -z "$b" ] && echo "B has a length of zero" # prints: B has a length of zero | |
| echo "B: ***$b***" # prints: B: ****** | |
| c=$(cat /dev/null) | |
| [ -n "$c" ] && echo "C is non-null" # prints: | |
| [ -z "$c" ] && echo "C has a length of zero" # prints: C has a length of zero | |
| echo "C: ***$c***" # prints: C: ****** | |
| # So, apparently, non-null is the opposite of length zero. ie: -n = ! -z | |
| } | |
| (( 0 )) && { # Get an average of some empirical value, eg: speed for a hard disk. | |
| # toss out the high and low readings, then average the rest. | |
| cum=0 ; high=0 ; low=999999999 | |
| for i in {1..12} # 12 samples. | |
| do | |
| speed=$(/sbin/hdparm -t /dev/mapper/VolGroup00-LogVol00 \ | |
| |grep 'MB/sec' \ | |
| |cut -d'=' -f2 \ | |
| |sed -e 's/ MB\/sec//' \ | |
| |sed -e 's/^\s*//') # eg: 234.56 MB/sec --> 234.56 | |
| cum=$( echo "$cum + $speed" |bc ) # use decimal math. | |
| [ $(echo "$speed > $high" |bc) -eq 1 ] && high=$speed | |
| [ $(echo "$speed < $low" |bc) -eq 1 ] && low=$speed | |
| echo -e "\tI: $i \tSpeed: $speed \tCum: $cum " | |
| done | |
| echo -e "\tHigh: $high \tLow: $low " | |
| n=$(($i-2)) # use integer math. | |
| cum=$( echo "$cum - $high - $low" |bc ) # use decimal math. | |
| avg=$( echo "$cum / $n" |bc ) | |
| echo -e "\tSummary: \tN: $n \tCum: $cum \tAvg: $avg " | |
| } | |
| (( 0 )) && { # run a program some number of times. accumulate totals. round down to integers. | |
| # toss out the high and low numbers. | |
| cum=0 ; high=0 ; low=999999999 | |
| for i in {1..12} | |
| do | |
| # get integer for speed in MB/sec. | |
| speed=$(/sbin/hdparm -t /dev/mapper/VolGroup00-LogVol00 \ | |
| |grep 'MB/sec' \ | |
| |cut -d'=' -f2 \ | |
| |sed -e 's/ MB\/sec//' \ | |
| |cut -d'.' -f1) | |
| cum=$(($cum + $speed)) | |
| [ $speed -gt $high ] && high=$speed | |
| [ $speed -lt $low ] && low=$speed | |
| echo -e "\tI: $i \tSpeed: $speed \tCum: $cum " | |
| done | |
| echo -e "\tHigh: $high \tLow: $low " | |
| n=$(($i-2)) | |
| cum=$(($cum - $high -$low)) | |
| avg=$(($cum / $n)) | |
| echo -e "\tSummary: \tN: $n \tCum: $cum \tAvg: $avg " | |
| } | |
| (( 0 )) && { # logical volume management. | |
| [ ! $(whoami) = 'root' ] && echo "Must be root to execute." && exit | |
| ( | |
| /sbin/fdisk -l | |
| for c in dumpconfig formats segtypes \ | |
| pvs pvscan pvdisplay \ | |
| lvs lvscan lvdisplay lvmdiskscan \ | |
| vgs vgscan vgdisplay vgck \ | |
| version | |
| do | |
| echo -e "==================== /sbin/lvm $c \n" | |
| eval /sbin/lvm $c | |
| echo; echo; echo | |
| done | |
| ) |less | |
| } | |
| (( 0 )) && { # find all the executable files in a tree | |
| find ~ja/temp/spread/ -perm /u=x,g=x,o=x -type f | |
| } | |
| (( 0 )) && { # change DIR permissions to 755. | |
| # From: "nate" <[email protected]> | |
| # find <path> -type d -exec chmod 755 {} \; | |
| # Or, using -execdir | |
| find <path> -type d -execdir chmod 755 {} \; | |
| # From: Bill Campbell <[email protected]> | |
| find . -type d | xargs chmod 755 | |
| # Or if the directories may have whitespace | |
| find . -type d -print0 | xargs -0 chmod 755 | |
| } | |
| (( 0 )) && { # Using "find" command when symbolic links are involved. | |
| # 3 "find" commands that are run on hudson. | |
| # find /home/ja/etc/config/ -iname '*startx*' -print |less | |
| # find /home/ja/etc/ -iname '*startx*' -print |less | |
| # find /home/ja/ -iname '*startx*' -print |less | |
| # | |
| # ### Of the 3 immediately above, the last does NOT work. | |
| # On fundy (where the etc dir really is) each of the 3 works. | |
| # | |
| # On hudson: | |
| # find /home/ja/ -ilname '*startx*' -print |less | |
| # find /home/ja/ -lname '*startx*' -print |less | |
| # find /home/ja/ -follow -iname '*startx*' -print |less | |
| # | |
| # ### Of the 3 immediately above, ONLY the last WILL work. | |
| echo "So, use -follow for symbolic links" | |
| } | |
| (( 0 )) && { # Using "find" with multiple values for some parms. | |
| # multiple dirs. | |
| # find ~/public/1and1/fam/2006/pool_{leak,pad} -iname '*.php' -type f | |
| # multiple iname | |
| # find . \( -iname '*.wma' -or -iname '*.mp3' \) -type f -print | |
| # files LT 5 days old and GT 0 days old. | |
| # find ~/temp -maxdepth 1 \( -mtime -5 -and -mtime +0 \) -print # Gets 3 files. | |
| # files LT 5 days old and GT 1 days old. | |
| # find ~/temp -maxdepth 1 \( -mtime -5 -and -mtime +1 \) -print # Gets 1 file. | |
| # files LT 5 days old and GT 2 days old. | |
| find ~/temp -maxdepth 1 \( -mtime -5 -and -mtime +2 \) -print # Gets 0 files, which is right. | |
| } | |
| (( 0 )) && { # calendar mx | |
| # list the summary line from AE. then compare with ... | |
| grep SUMMARY 2009-03-28_AE.ics |sed -e 's;^........;;' |sort | |
| # generate an AE only list. | |
| ~ja/bin/ical_vevents.pl ./2009-03-28_AE.ics > agenda_test_ae | |
| # then get a "summary" list, to compare against AE.ics | |
| tail -n 47 ./agenda_test_ae |sed -e 's;^.*all-day....;;' |sort | |
| # look for 'old' dates in AE | |
| grep ^DTSTART 2009-03-28_AE.ics |grep DATE |grep -v ':2010' |sort | |
| } | |
| (( 0 )) && { # find and mtime | |
| find ~/temp/calendars/google -mtime -2 -print # Gets files for today and yesterday, | |
| # ie, less than 2 days old. | |
| echo one | |
| find ~/temp/calendars/google -mtime -1 -print # Gets files for today, | |
| # ie, less than 1 days old. | |
| echo two | |
| find ~/temp/calendars/google -mtime -0 -print # Gets NO files | |
| # ie, less than 0 day old. | |
| echo three | |
| find ~/temp/calendars/google -mtime +2 -print # Gets one older file | |
| # ie, more than 2 days old. | |
| echo four | |
| find ~/temp/calendars/google -mtime +1 -print # Gets one older file | |
| # ie, more than 1 days old. | |
| echo five | |
| find ~/temp/calendars/google -mtime +0 -print # gets files for yesterday and older, | |
| # ie, more than 0 days old. | |
| # I guess that today is day 0, yesterday is day 1, ... | |
| } | |
| (( 0 )) && { # print var name, var value. must dereference var. see ABS example 23-5 | |
| # todo. modify for null values: x=$(eval "expr \"\$$v\"") | |
| a=aaa; b=bbb; c=ccc; d=ddd | |
| for var in a b c d | |
| do | |
| # y=\$"$var" ; x=$(eval "expr \"$y\" ") # works. | |
| # y=\$"$var" ; x=$(eval "expr $y ") # works. | |
| # y=\$"$var" ; x=$(eval "expr $y") # works. | |
| # x=$(eval "expr \$${var}") # works. | |
| # printf "\t%6s: %s \n" "$var" "$x" | |
| printf "\t%6s: %s \n" "$var" "$(eval "expr \$${var}")" # works. | |
| # printf "\t%6s: %s \n" "$var" "$(eval "expr $${var}")" # NO works. | |
| # printf "\t%6s: %s \n" "$var" "$(echo "expr \$${var}")" # NO works. | |
| # printf "\t%6s: %s \n" "$var" "$(expr \$${var})" # NO works. | |
| done | |
| } | |
| (( 0 )) && { # use printf with a variable in the format statement, eg printf " %${NUM}s \n" "$SomeText" | |
| NUM=20 ; My1=" Begin. %-${NUM}s End. \n" | |
| printf " Begin. %${NUM}s End. \n" "This is some text." # prints: " Begin. This is some text. End." | |
| printf " Begin. %-${NUM}s End. \n" "This is some text." # prints: " Begin. This is some text. End." | |
| printf "${My1}" "This is some text." # prints: " Begin. This is some text. End." | |
| printf "${My1}" "This is more text." # prints: " Begin. This is more text. End." | |
| # I guess "eval" is not needed. | |
| } | |
| (( 0 )) && { # $1 might be a dir, filename, ..., that we want to check for unwanted characters. | |
| HERE=$1 | |
| i=0 | |
| i=$(($i+`echo "$HERE" | grep -c \ `)) | |
| i=$(($i+`echo "$HERE" | grep -c \*`)) | |
| i=$(($i+`echo "$HERE" | grep -c \\\\\\\\`)) | |
| i=$(($i+`echo "$HERE" | grep -c \"`)) | |
| i=$(($i+`echo "$HERE" | grep -c \'`)) | |
| i=$(($i+`echo "$HERE" | grep -c \\\``)) | |
| if [ $i -ne 0 ]; | |
| then echo "Badness" | |
| else echo "Goodness" | |
| fi | |
| } | |
| (( 0 )) && { # recent changes in ACC178 | |
| echo -e "\n\tChanges in ACC178 in recent weeks. \n" | |
| for w in {1..12} # weeks 1-x | |
| do | |
| d=$((7*${w})) # convert weeks to days. | |
| printf "\tChanged in the last %2d weeks: " "$w" | |
| find ~/public/1and1/acc -mtime -$d |wc -l # count of changes | |
| find ~/public/1and1/acc -mtime -$d # actual changes. | |
| echo | |
| done | |
| } | |
| (( 0 )) && { # Find average file size, excluding home. then for home | |
| for d in home data | |
| do | |
| c=$(find /$d |wc -l) | |
| printf "%15s: %12d\n" "$d" $c | |
| cum=$((cum+c)) | |
| done | |
| printf "%15s: %12d\n" "Cum" $cum | |
| # home: 72292 | |
| # data: 1245 | |
| # Cum: 73537 | |
| # So, about 225 + 74 ~= 300,000 files | |
| # ~32GB used, ===> ~107 KB | |
| } | |
| (( 0 )) && { # parse on word boundaries | |
| # ie, in /etc/services, look for port 25, but not 525 or 1525 | |
| grep '\b25/' /etc/services # \b matches the leading boundary. | |
| # / matches the following character. | |
| # alternately: | |
| grep -w 25 /etc/services # -w means match words, with non-word boundary. | |
| } | |
| (( 0 )) && { # Find "bin" dirs. Ignore 5 trees | |
| BinDirs=$(find / \ | |
| -path '/data' -prune -o \ | |
| -path '/home/ja' -prune -o \ | |
| -path '/mnt' -prune -o \ | |
| -path '/NFS4exports' -prune -o \ | |
| -path '/proc' -prune -o \ | |
| -type d \ | |
| -name '*bin' \ | |
| -print) | |
| echo " BinDirs:" | |
| echo $BinDirs | |
| } | |
| (( 0 )) && { # use *find* but skip a few directories. | |
| # 1. this works. | |
| find ~ja/temp \ | |
| -path '/home/ja/temp/downloads' -prune -o \ | |
| -path '/home/ja/temp/img' -prune -o \ | |
| -path '/home/ja/temp/spread' -prune -o \ | |
| -path '/home/ja/temp/calendars' -prune -o \ | |
| -print |wc -l | |
| # 2. also works. | |
| find ~ja/temp -path '/home/ja/temp/downloads' -prune \ | |
| -o -path '/home/ja/temp/img' -prune \ | |
| -o -path '/home/ja/temp/spread' -prune \ | |
| -o -path '/home/ja/temp/calendars' -prune \ | |
| -o -print \ | |
| |wc -l | |
| # 3. also works | |
| cd ~ja/temp | |
| find . -path './downloads' -prune \ | |
| -o -path './img' -prune \ | |
| -o -path './spread' -prune \ | |
| -o -path './calendars' -prune \ | |
| -o -print \ | |
| | wc -l | |
| # 4. does not yield the same as 3. Yikes! | |
| cd ~ja/temp | |
| find . -path '/home/ja/temp/downloads' -prune \ | |
| -o -path './img' -prune \ | |
| -o -path './spread' -prune \ | |
| -o -path './calendars' -prune \ | |
| -o -print \ | |
| | wc -l | |
| # 5. yields same as 4. | |
| cd ~ja/temp | |
| find . -path '~ja/temp/downloads' -prune \ | |
| -o -path './img' -prune \ | |
| -o -path './spread' -prune \ | |
| -o -path './calendars' -prune \ | |
| -o -print \ | |
| | wc -l | |
| # Apparently, the starting dir (~ja/temp), after expansion (/home/ja/temp) | |
| # must be an exact text match of the -path value (/home/ja/temp), | |
| # without reguard for actual location. | |
| # That is: starting dir (~ja/temp) gets expanded to /home/ja/temp | |
| # but path value (~ja/temp/downloads) does not get expanded, since it is in quotes. | |
| # Remove the quotes and it's prune logic is lost. | |
| # Good grief, can this be right? | |
| } | |
| (( 0 )) && { # How to tell if your processor supports hardware kvm | |
| # from: http://kerneltrap.org/node/8088 | |
| egrep '^flags.*(vmx|svm)' /proc/cpuinfo | |
| } | |
| (( 0 )) && { # Get a collective time for a series of commands | |
| # | |
| # From: Luciano Miguel Ferreira Rocha <[email protected]> | |
| # On the [CentOS] mailing list | |
| cd ~ja/bin | |
| # what is the total time for running all 3 commands ?? | |
| # using {} | |
| # time { tune.mgr.repos_compare; tune.mgr.filenames /data/mp3; tune.mgr.playlists /data/mp3; } | |
| # using () | |
| # time ( tune.mgr.repos_compare.sh; tune.mgr.filenames /data/mp3; tune.mgr.playlists /data/mp3; ) | |
| # Discussion on CentOS list: sometimes the time () approach does not work. | |
| # Better to use {} or sh -c approaches | |
| # using non-builtin time | |
| # /usr/bin/time sh -c "tune.mgr.repos_compare.sh; tune.mgr.filenames /data/mp3; tune.mgr.playlists /data/mp3;" | |
| # Reportedly, "time scriptname" will also work, provided that none of the | |
| # commands in scriptname will fork to the background. | |
| } | |
| (( 0 )) && { # Collect a series of screenshots. | |
| i=0 | |
| while [ 1 ] | |
| do | |
| import -frame -window $1 "cap_$(printf "%04i" $i).miff" | |
| i=$(( $i + 1 )) | |
| sleep 5 | |
| done | |
| } | |
| (( 0 )) && { # Screencast prep | |
| # take screenshot of named window. | |
| # | |
| import -frame -window 0xc00035 "test.miff" # save in IM native format | |
| # convert miff to jpg | |
| # | |
| convert -antialias -resize 720x486! test.miff test.jpg | |
| # get the name of a window in X | |
| # run the xwininfo command and then click on a window. | |
| # | |
| xwininfo -frame |grep 'Window id:' # prints: "xwininfo: Window id: 0xc00b0b (has no name)" | |
| } | |
| (( 0 )) && { # wget options | |
| wget --recursive \ | |
| --no-clobber \ | |
| --page-requisites \ | |
| --html-extension \ | |
| --convert-links \ | |
| --restrict-file-names=windows \ | |
| --domains website.org \ | |
| --no-parent \ | |
| www.website.org/tutorials/html/ | |
| # This command downloads the Web site www.website.org/tutorials/html/. | |
| # The options are: | |
| # | |
| # --recursive: download the entire Web site. | |
| # --domains website.org: don't follow links outside website.org. | |
| # --no-parent: don't follow links outside the directory tutorials/html/. | |
| # --page-requisites: get all the elements that compose the page (images, CSS and so on). | |
| # --html-extension: save files with the .html extension. | |
| # --convert-links: convert links so that they work locally, off-line. | |
| # --restrict-file-names=windows: modify filenames so that they will work in Windows as well. | |
| # --no-clobber: don't overwrite any existing files (used in case the download is interrupted and resumed). | |
| } | |
| (( 0 )) && { # go thru a list of URLs in a file, deleting each as it is used. | |
| # (after an interruption, we want to resume where we left off, not at begining.) | |
| T=~ja/temp/temp.$$ | |
| cat > $T <<-ENDOFLIST; | |
| http://www.notbig.org | |
| http://www.cnn.com | |
| http://www.lugod.org | |
| http://www.linux.org | |
| ENDOFLIST | |
| while [ `find $T -size +0` ] | |
| do | |
| url=`head -n1 $T` | |
| # wget -c $url | |
| echo $url | |
| ERRORCODE=$? | |
| if [ $ERRORCODE -eq 0 ] | |
| then # s="consider files as seperate", ... | |
| sed -si 1d $T # i="edit files in-place", ... | |
| else # 1d="line 1, delete" (I think.) | |
| echo "ERROR: could not get $url" 1>&2 | |
| exit $ERRORCODE | |
| fi | |
| done | |
| rm $T | |
| } | |
| (( 0 )) && { # list URLs in a file. | |
| f=~/temp/temp.ttt | |
| cat > $f <<-ENDOFLIST; | |
| http://www.notbig.org | |
| http://www.cnn.com | |
| http://www.lugod.org | |
| http://www.linux.org | |
| ENDOFLIST | |
| cat $f |xargs printf '\t%s\n' | |
| } | |
| (( 0 )) && { # grab some lines from a list of proceses. from unspawn on RKHunter list. minor changes. | |
| RKHTMPVAR="" | |
| # awk -F defines a string for field breaks. | |
| # ie, the string "syslogd -f somefile" will break on '-f'. | |
| for TMPVAR in `\ps -auwwx | grep syslogd | awk -F'-f' '{print $2}'` | |
| do | |
| if [ -f "$TMPVAR" ] | |
| then | |
| RKHTMPVAR=$TMPVAR | |
| break | |
| fi | |
| done | |
| if [ -z $RKHTMPVAR ] | |
| then | |
| echo "Syslogd using regular configuration file." | |
| else | |
| echo "Syslogd using alternative configuration file: $RKHTMPVAR." | |
| fi | |
| } | |
| (( 0 )) && { # Get config items re quick-launch tray for gnome-terminal. | |
| for X in /apps/panel/{general,objects/object_0} | |
| do | |
| echo -e "\n\t$X\n" | |
| /usr/bin/gconftool-2 --all-entries $X | |
| done > ~/temp/gnome-terminal-panel-config | |
| : <<-MYCOMMENTS | |
| /apps/panel/general | |
| profiles_migrated = false | |
| object_id_list = [menu_bar,object_0] | |
| enable_program_list = true | |
| enable_autocompletion = true | |
| show_program_list = false | |
| applet_id_list = [clock,systray,show_desktop_button,workspace_switcher,trash_applet,window_list] | |
| toplevel_id_list = [top_panel,bottom_panel] | |
| /apps/panel/objects/object_0 | |
| toplevel_id = top_panel | |
| bonobo_iid = | |
| attached_toplevel_id = | |
| use_custom_icon = false | |
| action_type = lock | |
| tooltip = | |
| custom_icon = | |
| launcher_location = /usr/share/applications/gnome-terminal.desktop | |
| use_menu_path = false | |
| panel_right_stick = false | |
| object_type = launcher-object | |
| position = 325 | |
| locked = false | |
| menu_path = applications:/ | |
| MYCOMMENTS | |
| } | |
| (( 0 )) && { # turn off system restart options at the login screen. | |
| gconftool-2 --direct --config-source xml:readwrite:/etc/gconf /gconf.xml.mandatory -t bool -s /apps/gdm/simple-greeter /disable_restart_buttons true | |
| } | |
| (( 0 )) && { # change wallpaper to a random image every X seconds. restore to original when done. | |
| seconds=4 | |
| default=$(/usr/bin/gconftool-2 --get /desktop/gnome/background/picture_filename) | |
| declare -a images | |
| images=( $(ls ~ja/public/wallpaper/*.{png,jpg}) ) | |
| count=${#images[@]} | |
| for x in {1..3} | |
| do | |
| i=$(($RANDOM%$count)) # starts with 0. | |
| img=${images[$i]} | |
| /usr/bin/gconftool-2 \ | |
| --type "string" \ | |
| --set /desktop/gnome/background/picture_filename $img | |
| sleep $seconds | |
| done | |
| /usr/bin/gconftool-2 \ | |
| --type "string" \ | |
| --set /desktop/gnome/background/picture_filename $default | |
| } | |
| (( 0 )) && { # dump all entries, make config change, dump all entries, compare | |
| /usr/bin/gconftool-2 --all-entries /apps/ | |
| /usr/bin/gconftool-2 --all-entries /desktop/ | |
| } | |
| (( 0 )) && { # play with the 'fold' command, to wrap text to a specified width. | |
| unit='Now is the time for all good men and women to come to the aid of their country. ' # 81 characters. | |
| for x in `seq 1 9` ; do big=" $big $unit"; done # 81 x 9 = 729 characters | |
| # echo $big |fold --spaces --width=50 # --spaces = break at spaces. | |
| # echo | |
| echo $big |fmt -w50 # some minor differences. | |
| echo | |
| # echo $big |fmt -w50 -u # uniform spaces. 1 'tween words, 2 'tween sentences. no diff. | |
| # echo $big |fmt -w50 -cu # crown margin. no diff. | |
| # echo $big |fmt -w50 -t # tagged para. no indent on first line. else, indent 4 spaces. | |
| # echo $big |fmt -tuw50 # no diff. | |
| } | |
| (( 0 )) && { # from maemo-users list. | |
| # [ja@pacific ~]$ cat /proc/sys/fs/file-nr # from pacific. file descriptor usage. | |
| # 2760 0 102655 | |
| # | |
| # ~ $ cat /proc/sys/fs/file-nr # from N800 | |
| # 1059 0 4096 | |
| : <<-MYCOMMENTS | |
| # from http://www.netadmintools.com/art295.html | |
| [root@srv-4 proc]# cat /proc/sys/fs/file-nr | |
| 3391 969 52427 | |
| | | | | |
| | | | | |
| | | maximum open file descriptors | |
| | total free allocated file descriptors | |
| total allocated file descriptors | |
| (the number of file descriptors allocated since boot) | |
| MYCOMMENTS | |
| # ls /proc |wc -l # 156 on pacific. 126 on N800 | |
| for pid in /proc/[0-9]* | |
| do | |
| cmd=$(tr '\0' ' '<$pid/cmdline) | |
| if [ "$cmd" ] | |
| then | |
| #echo FDs for this pid: $(ls -l $pid/fd/|wc -l) | |
| #echo PID \(no path info\): ${pid##*/} | |
| #echo "base command: ${cmd%% *}" | |
| #echo "Nr FDs and basename: $(ls -l $pid/fd/|wc -l) ${cmd%% *}[${pid##*/}]" | |
| echo "$(ls -l $pid/fd/|wc -l) ${cmd%% *}[${pid##*/}]" | |
| fi | |
| done |sort -n | |
| } | |
| (( 0 )) && { # from maemo user list. "Let's add to the script output, | |
| # also the (first crawler) process memory usage and | |
| # check only files opened from the card(s):" | |
| # app=metalayer-crawler | |
| app=gmplayer # get it running on "solo_guitars" | |
| # filter=media/ | |
| filter=solo # filter on "solo" | |
| # sleep=2 | |
| sleep=10 | |
| while true | |
| do | |
| pid=$(/sbin/pidof ${app} |cut -d' ' -f1); # could manually get app name from ps aux | |
| ls -l /proc/${pid}/fd/ |grep $filter; # what is happening right now? | |
| grep RSS /proc/${pid}/status; # gets: VmRSS: 20140 kB | |
| echo -e "\tSleep for $sleep seconds" | |
| sleep $sleep | |
| done | |
| } | |
| (( 0 )) && { # compare several approaches to parsing an apache logfile. 1. | |
| # From: Linux Mag. Issue 64, March 2006 | |
| # takes ~ 0.58 seconds, wall clock. | |
| # MUCH FASTER !!! than below. | |
| exec 3<~/temp/big_access_log # uses file descriptor 3 to open the file | |
| while read -u 3 Request # process one line at a time in the loop. no caching. ### double spaces. wtfo. | |
| do | |
| Request="${Request##*GET }" # remove from start-of-line thru GET | |
| echo "${Request%% HTTP/*}" # remove from HTTP thru end-of-line | |
| done | |
| } | |
| (( 0 )) && { # compare several approaches to parsing an apache logfile. 0. | |
| # From: Linux Mag. Issue 64, March 2006 | |
| # takes ~ 2.57 seconds, wall clock | |
| IFS=$'\n' | |
| for l in `cat ~/temp/big_access_log` # reads whole file into memory before anything else. | |
| do | |
| IFS=" " | |
| echo "${l}" | cut -d" " -f7 # calls "cut", an external program, for each loop | |
| done | |
| } | |
| (( 0 )) && { # sort IP addresses. | |
| # From: http://linuxgazette.net/133/misc/lg/How_do_you_sort_an_IP_address_list.html | |
| f=~/t.$$ | |
| cat > $f <<-ENDOFSORTLIST; | |
| 10.123.189.105 | |
| 12.149.177.21 | |
| 12.154.4.213 | |
| 12.159.232.66 | |
| 12.205.7.190 | |
| 12.206.142.76 | |
| 12.214.50.126 | |
| 12.221.163.162 | |
| 12.30.72.162 | |
| 4.3.76.194 | |
| 8.10.33.176 | |
| ENDOFSORTLIST | |
| # Use -t. to break the lines into fields on ., | |
| # then sort 4 ints from left to right: | |
| # sort -t. +0n -1 +1n -2 +2n -3 +3n -4 < $f | |
| # sort -u -n -t. -k 1,1 -k 2,2 -k 3,3 -k 4,4 $f | |
| # Another way would be to multiply each address out into an int, sort, and re-format. | |
| # | |
| tr '.' ' ' < $f | xargs printf '%03d.%03d.%03d.%03d\n' |sort -u |sed -re 's/\b0+//g' | |
| } | |
| (( 0 )) && { # regex patterns | |
| DICT=~/etc/config/dict/linux.words | |
| # egrep -i '^fu.*ia$' $DICT # match whole lines | |
| for i in `seq 1 32` | |
| do | |
| echo "There are" `egrep '^.{'$i'}$' $DICT \ | |
| | wc -l` "$i-letter words in the dictionary." | |
| done | |
| } | |
| (( 0 )) && { # Good Practices. | |
| # From: http://www-128.ibm.com/developerworks/aix/library/au-badunixhabits.html?ca=lnxw01GoodUnixHabits | |
| ~ $ tar xvf -C tmp/a/b/c newarc.tar.gz # unpack tarball into dir tmp/a/b/c | |
| ~/tmp $ ls -1 | xargs file # run "file" on each file in pwd. | |
| ~/tmp $ ls -l | awk '$6 == "Dec"' # match part of the date field | |
| # -rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar | |
| # -rw-r--r-- 1 root root 238 Dec 03 08:19 README | |
| } | |
| (( 0 )) && { # list current fonts | |
| for d in /usr/share/fonts/{bitmap-fonts,bitstream-vera,default,openoffice} \ | |
| /usr/X11R6/lib/X11/fonts/{Type1,OTF} \ | |
| ~/.fonts | |
| do | |
| [ -d $d ] && echo -e "\n\t$d" && ls -l $d | |
| done | |
| } | |
| (( 0 )) && { # update $vvp variable in *.php files. | |
| p=~/public/kin/fam/2006/au | |
| for f in $(ls ${p}/{mac,syd,tap}/*.php |grep -v index.php) | |
| do | |
| echo -e "\t${f}" | |
| cat ${f} |sed -e 's/zz\/lite/..\/zz\/lite/' >${f}.temp | |
| mv $f $f.old | |
| mv $f.temp $f | |
| done | |
| } | |
| (( 0 )) && { # drivers | |
| f=/usr/share/hwdata/pci.ids # list of PCI IDs in RHEL 4.4 | |
| less $f # has vendor number and name. | |
| # device number and name. ... | |
| # see also: http://pciids.sourceforge.net/ | |
| /sbin/lspci # eg, 00:00.0 Host bridge: Silicon Integrated Systems [SiS] 645xx (rev 51) | |
| /sbin/lspci -n # eg, 00:00.0 Class 0600: 1039:0648 (rev 51) | |
| # -n: Show PCI vendor and device codes as numbers. Don't look up in PCI ID db. | |
| /sbin/modinfo ipw2100 # misc info. And aliases (cards to be handled by this module.) | |
| # udev will detect hardware, scan the modules list for a match, and load. | |
| } | |
| (( 0 )) && { # Virtual Memory Statistics | |
| vmstat # one-time | |
| vmstat -a 2 4 # 2 sec interval, 4 times. | |
| vmstat 1 20 # 1 sec interval, 20 times. Use while Firefox loads. | |
| } | |
| (( 0 )) && { # setup image date. later, compare date with xml track info. | |
| show_3_times(){ ls -l --time=atime $1; ls -l --time=ctime $1; ls -l $1; echo; } | |
| IMG1=~ja/public/geo/geotag_images/jim.jpg | |
| show_3_times $IMG1 | |
| # set mtime between 2006-09-02T14:47:01Z and 2006-09-02T14:47:07Z | |
| year=2006; month=09; day=02; hour=07; min=47; sec=03 # GMT -7 = PDT | |
| touch -m -t $year$month$day$hour$min.$sec $IMG1 | |
| show_3_times $IMG1 | |
| IMG2=~ja/public/geo/geotag_images/bfp.jpg | |
| show_3_times $IMG2 | |
| # set mtime between 2006-09-02T14:51:52Z and 2006-09-02T14:51:57Z | |
| year=2006; month=09; day=02; hour=07; min=51; sec=55 # GMT -7 = PDT | |
| touch -m -t $year$month$day$hour$min.$sec $IMG2 | |
| show_3_times $IMG2 | |
| } | |
| (( 0 )) && { # filter tracks.txt for gpsvisualizer input. format: name,lat,long | |
| # use sequential number for name. | |
| # grep '<trkpt ' ./tracks.txt |sed -e 's/\" lon=\"/,/' -e 's/>//' -e 's/<trkpt lat="/b,/' | |
| i=0 | |
| for s in $( grep '<trkpt ' ./tracks.txt |sed -e 's/\" lon=\"/,/' -e 's/>//' -e 's/<trkpt lat="//' ) | |
| do | |
| ((i++)) | |
| echo "$i,$s" | |
| done | |
| } | |
| (( 0 )) && { # download info from Garmin eTrex gps receiver. | |
| # verify /dev/ttyS0 is rw for all | |
| TTY=/dev/ttyS0 | |
| [ $( ls -l $TTY |grep '^crw-rw-rw-' |wc -l ) -lt 1 ] \ | |
| && echo -e "\tNot rw for all: $TTY \n\tAs root, chmod a+rw" \ | |
| && exit 1 | |
| F=~/public/geo/geotag_images/waypoints.txt | |
| ~/bin/gpsbabel -igarmin -f $TTY -o gpx -F $F | |
| F=~/public/geo/geotag_images/tracks.txt | |
| ~/bin/gpsbabel -t -igarmin -f $TTY -o gpx -F $F | |
| } | |
| (( 0 )) && { # color screen characters. | |
| tput clear # clear the screen | |
| tput cup 3 15 # Move cursor to screen location Row,Col (top left is 0,0) | |
| tput setaf 3 # Set a foreground colour using ANSI escape | |
| echo "XYX Corp LTD." | |
| tput sgr0 # Reset text attributes w/o clearing screen. | |
| tput cup 5 17 | |
| tput rev # Set reverse video mode | |
| echo "M A I N - M E N U" | |
| tput sgr0 # Reset text attributes... | |
| tput cup 7 15 | |
| echo "1. User Management" | |
| tput cup 8 15 | |
| echo "2. Service Management" | |
| tput cup 9 15 | |
| echo "3. Process Management" | |
| tput cup 10 15 | |
| echo "4. Backup" | |
| tput bold # Set bold mode | |
| tput cup 12 15 | |
| read -p "Enter your choice [1-4] " choice | |
| tput clear | |
| tput sgr0 | |
| tput rc | |
| # Prints: | |
| XYX Corp LTD. | |
| M A I N - M E N U | |
| 1. User Management | |
| 2. Service Management | |
| 3. Process Management | |
| 4. Backup | |
| Enter your choice [1-4] | |
| } | |
| (( 0 )) && { # color echo | |
| black='\E[30;47m' | |
| red='\E[31;47m' | |
| green='\E[32;47m' | |
| yellow='\E[33;47m' | |
| blue='\E[34;47m' | |
| magenta='\E[35;47m' | |
| cyan='\E[36;47m' | |
| white='\E[37;47m' | |
| cecho () | |
| { | |
| local default_msg="No message passed." | |
| message=${1:-$default_msg} # Default message. | |
| color=${2:-$black} # Default color. | |
| echo -e "$color" | |
| echo "$message" | |
| tput sgr0 # Reset text attributes w/o clearing screen. | |
| return | |
| } | |
| cecho "Feeling blue..." $blue | |
| cecho "Magenta looks more like purple." $magenta | |
| cecho "Green with envy." $green | |
| cecho "Seeing red?" $red | |
| cecho "Cyan, more familiarly known as aqua." $cyan | |
| cecho "No color passed (defaults to black)." # no color passed. | |
| cecho "\"Empty\" color passed (defaults to black)." "" # Empty $color argument. | |
| cecho # Missing $message and $color arguments. | |
| cecho "" "" # Empty $message and $color arguments. | |
| echo | |
| } | |
| (( 0 )) && { # Prints a table of ASCII characters. | |
| # Sorta centers the values under the headings. | |
| START=33 # Range of printable ASCII characters (decimal). | |
| END=125 | |
| printf "\t%7s %3s %8s \n" "Decimal" "Hex" "Character" | |
| printf "\t%7s %3s %8s \n" "-------" "---" "---------" | |
| for ((i=START; i<=END; i++)) | |
| do | |
| echo $i | awk '{printf("\t%4d %6x %5c \n", $1, $1, $1)}' | |
| done | |
| exit 0 | |
| } | |
| (( 0 )) && { # debugging techniques. | |
| # Version 1. | |
| debug=1 | |
| (( $debug )) && echo -e "\tThis will print, since debug is set to 1." # yep, it prints. | |
| debug=0 | |
| (( $debug )) && echo -e "\tThis will NOT print, since debug is set to 0." # yep, it does NOT print. | |
| # Version 2. | |
| qaprint() { [ ! -z "$qa" ] && echo -e "\t$1" >&2; } | |
| qa=1 | |
| qaprint "Since qa is 1, this will print" # yep, it prints. | |
| qa= | |
| qaprint "Since qa is null, this will NOT print" # yep, it does NOT print. | |
| } | |
| (( 0 )) && { # Delete contents of a file, but preserve the file itself, (and permissions) | |
| f=/home/ja/temp/TenGO/Palm5_Installation_Instructions.pdf | |
| [ -f $f ] && cat /dev/null > $f | |
| f=/home/ja/temp/TenGO/TengoUserManual_Palm.pdf | |
| [ -f $f ] && : > $f # has same effect, but does not spawn a new process. | |
| } | |
| (( 0 )) && { # alternate means to determine process for a given pid. | |
| echo Alt1 | |
| find /proc/$1/exe -printf '%l\n' | |
| echo Alt2 | |
| /usr/sbin/lsof -aFn -p $1 -d txt | sed -ne 's/^n//p' | |
| } | |
| (( 0 )) && { # Get process path name for a given pid. | |
| # use an existing pid as $1 | |
| [ $# -ne 1 ] && echo "Usage: `basename $0` PID-number" >&2 && exit 1 | |
| pidno=$( ps ax | grep $1 | awk '{ print $1 }' | grep $1 ) | |
| [ -z "$pidno" ] && echo "No such process running." && exit 1 | |
| PROCFILE=exe | |
| if [ ! -r "/proc/$1/$PROCFILE" ] | |
| then | |
| echo "Process $1 running, but..." | |
| echo "No read permission on /proc/$1/$PROCFILE." | |
| exit 1 | |
| fi | |
| exe_file=$( ls -l /proc/$1/exe | awk '{ print $11 }' ) | |
| if [ -e "$exe_file" ] | |
| then echo -e "\tProcess #$1 invoked by $exe_file." | |
| else echo -e "\tNo such process running." | |
| fi | |
| } | |
| (( 0 )) && { # Starting the script with "#!/bin/bash -r" runs entire script in restricted mode. | |
| echo -e "\tChanging directory." | |
| cd /usr/local | |
| echo -e "\tNow in `pwd`" | |
| echo -e "\tComing back home." | |
| cd | |
| echo -e "\tNow in `pwd` \n" | |
| # Everything up to here in normal, unrestricted mode. | |
| set -r # set --restricted has same effect. | |
| echo -e "\t==> Now in restricted mode. <==" | |
| echo -e "\n\n\tAttempting directory change in restricted mode." | |
| cd .. | |
| echo -e "\tStill in `pwd`" | |
| # echo -e "\n\n\t\$SHELL = $SHELL" | |
| # echo -e "\tAttempting to change shell in restricted mode." | |
| # SHELL="/bin/ash" # does not permit this. aborts script. | |
| # echo -e "\n\t\$SHELL= $SHELL" | |
| echo -e "\n\n\tAttempting to redirect output in restricted mode." | |
| ls -l /usr/bin > bin.files | |
| ls -l bin.files # Try to list attempted file creation effort. | |
| } | |
| (( 0 )) && { # avoid subshell problem. | |
| fn=~ja/temp/temp.$$ | |
| cat <<- EOF >> $fn | |
| Line 1. | |
| Line 2. | |
| Line 3. | |
| Line 4. | |
| Line 5. | |
| EOF | |
| Lines=0 | |
| cat $fn | while read line # ?? pipe creates subshell ?? | |
| do | |
| echo $line ; (( Lines++ )) | |
| done | |
| echo "Number of lines read = $Lines" # prints 0 # Wrong! | |
| Lines=0 | |
| while read line # redirect file to while loop | |
| do | |
| echo $line ; (( Lines++ )) | |
| done < $fn | |
| echo "Number of lines read = $Lines" # prints 5 # Right! | |
| Lines=0 | |
| exec 3<> $fn # Assign filehandle 3 to $fn | |
| while read line <&3 | |
| do | |
| echo "$line" ; (( Lines++ )) | |
| done | |
| exec 3>&- | |
| echo "Number of lines read = $Lines" # prints 5 # Right! | |
| rm $fn | |
| } | |
| (( 0 )) && { # comment out code, on a temp basis. | |
| echo -e "The code below will not print." | |
| : <<-DEBUGXXX | |
| for file in * | |
| do | |
| cat "$file" | |
| done | |
| DEBUGXXX | |
| echo -e "Note the \"-\" just prior to DEBUGXXX." | |
| } | |
| (( 0 )) && { # Using the m4 macro processor. | |
| # m4 builtin functions: len, substr, regexp, incr, eval, ... | |
| # Strings | |
| string=abcdA01 | |
| echo "len($string)" | m4 # 7 | |
| echo "substr($string,4)" | m4 # A01 (first char is position zero.) | |
| echo "regexp($string,[0-1][0-1],\&Z)" | m4 # 01Z | |
| # Arithmetic | |
| echo "incr(22)" | m4 # 23 | |
| echo "eval(99 / 3)" | m4 # 33 | |
| } | |
| (( 0 )) && { # graphic of "tee" command | |
| # |----> redirect to file | |
| # | | |
| # ==========================|==================== | |
| # command ---> command ---> |tee ---> command ---> ---> output of pipe | |
| # =============================================== | |
| cat ~/temp/curl_options | sort | tee curl.check | uniq > curl.result | |
| } | |
| (( 0 )) && { # more play with bc. 1. | |
| # using files. | |
| f=~/t.$$ | |
| cat > $f <<-ENDOFBCCODE; | |
| scale=2 | |
| /* C-style comments | |
| are allowed, as are spaces */ | |
| print "\nConvert Fahrenheit to Celsius\n\n" | |
| print "Temperature in Fahrenheit: " ; fah = read() | |
| print "\n" | |
| print "Equivalent Temperature in Celsius is: " | |
| (fah - 32.0) * 5.0 / 9.0 | |
| quit | |
| ENDOFBCCODE | |
| # to envoke: $ bc -q $f | |
| } | |
| (( 0 )) && { # more play with bc. 0. | |
| # thanks: http://www.basicallytech.com/blog/index.php?/archives/23-command-line-calculations-using-bc.html | |
| echo '57+43' | bc # 100 | |
| echo '57-43' | bc # 14 | |
| echo '57*43' | bc # 2451 | |
| echo 'scale=25;57/43' | bc # 1.3255813953488372093023255 | |
| echo 'scale=30;sqrt(2)' | bc # 1.414213562373095048801688724209 | |
| echo '6^6' | bc # 46656 | |
| echo '(6^6)^6' | bc # 10314424798490535546171949056 | |
| echo 'obase=16;255' | bc # FF # convert 255 from base 10 to base 16. | |
| echo 'obase=2;12' | bc # 1100 # convert 12 from base 10 to base 2. | |
| echo 'ibase=2;obase=A;10' | bc # 2 # convert from binary to deciaml | |
| echo 'ibase=2;obase=A;10000001' | bc # 129 # | |
| echo 'ibase=16;obase=A;FF' | bc # 255 # convert from hex to decimal. | |
| FIVE=5 ; echo "$FIVE^2" | bc # 25 # using bc in shell scripts. | |
| } | |
| (( 0 )) && { # add column headings. format columns. | |
| # "column" uses logical columns. | |
| (printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n"; \ | |
| ls -l /usr/local/bin/pilot*) | column -t | |
| # colrm uses character columns. (better know the format of input text!) | |
| (printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n"; \ | |
| ls -l /usr/local/bin/pilot*) | column -t |colrm 14 60 | |
| } | |
| (( 0 )) && { # downshift: this function return the argument as downshifted string | |
| # from: http://www.samag.com/documents/s=9373/sam0203f/0203f.htm | |
| function down_shift | |
| { | |
| # alternate translate command | |
| # echo $1 | tr "[:upper:]" "[:lower:]" | |
| echo $1 | tr '[A-Z]' '[a-z]' | |
| } | |
| string="ALLLOWERCASE" | |
| string=$(down_shift $string) | |
| printf "%s\n" $string | |
| } | |
| (( 0 )) && { # path munging, from /etc/profile | |
| # Note interesting pattern matching with egrep. From the man page: | |
| # Repetition takes precedence over concatenation, | |
| # which in turn takes precedence over alternation. | |
| # A whole sub-expression may be enclosed in parentheses to override these precedence rules. | |
| ppath='a:b:c:d:e' # psuedo path | |
| pathm() | |
| { | |
| # If $1 is already in ppath, then do nothing. | |
| # If not in path, then add before or after. | |
| if ! $(echo $ppath | /bin/egrep -q "(^|:)$1($|:)") | |
| then | |
| if [ "$2" = "after" ]; then ppath=$ppath:$1 | |
| else ppath=$1:$ppath | |
| fi | |
| fi | |
| } | |
| pathm c; echo -e "\tPpath: $ppath"; # no change. | |
| pathm /usr/local/sbin; echo -e "\tPpath: $ppath"; # adds $1 to begin of ppath. | |
| pathm /usr/X11R6/bin after; echo -e "\tPpath: $ppath"; # adds $1 to end of ppath. | |
| } | |
| (( 0 )) && { # build a string of items. special handeling for first item. | |
| dm= | |
| for d in /usr/man /usr/share/man | |
| do | |
| if [ -d $d ] | |
| then | |
| if [ x$dm = x ] | |
| then | |
| dm=$d; else dm=$dm:$d | |
| fi | |
| fi | |
| done | |
| echo "dm: $dm" | |
| } | |
| (( 0 )) && { # play with using "find" then looking at each file. | |
| find ~ja/public/web/ideas/ -iname '*.html' -type f \ | |
| |xargs grep '\.css' \ | |
| |grep -v 'strict.dtd' | |
| } | |
| (( 0 )) && { # wtf re errors from /etc/cron.weekly/00-makewhatis | |
| # ?? incorrect format of NAME in man pages ?? | |
| # later, use output of $(man --path) | |
| # for d in /usr/kerberos/man | |
| # for d in /usr/local/share/man | |
| # for d in /usr/share/man/en | |
| # for d in /usr/share/man | |
| for d in /usr/share/man/man{0p,1,1p} | |
| # for d in /usr/X11R6/man/man1 | |
| do | |
| [ ! -d $d ] && echo -e "NOT a dir: $d" && exit | |
| echo -e "\tDir: $d" | |
| find $d -iname '*.gz' -type f -execdir /home/ja/bin/manpage_name.sh '{}' \; | |
| echo | |
| done | |
| } | |
| (( 0 )) && { # play with ~ja/temp/nvram-clean.sh and /root/nvram-show | |
| # just look at "type" | |
| echo -e "\n===== 15 Most Frequent key _TAILS_ =====" | |
| cat /root/nvram-show 2>/dev/null | \ | |
| { | |
| while read LINE ### double spaces probably naf. | |
| do | |
| CONTENTS="${LINE##*=}" # del longest match from LEFT. gives value. | |
| LINE="${LINE%%=*}" # del longest match from RIGHT. gives key. | |
| TYPE="${LINE%%_*}" # del longest match from RIGHT. gives left of _ | |
| TAIL=${LINE##*_} # gives right of _. ie, the key tail. | |
| echo "$TAIL" | |
| done | |
| } |sort |uniq -c |sort -rn |head -n 15 | |
| } | |
| (( 0 )) && { # get a list of subfolders sorted by their size | |
| du -k --max-depth=1 /temp/ | sort -n -r | |
| # or, to avoid crossing into another filesystem | |
| du -xk --max-depth=1 / |sort -rn | |
| # or, find recent large files | |
| find . -mount -ctime -1 -size +5M # files within the last day, with size GT 5MB. | |
| # or, print out size directly | |
| find . -mount -ctime -1 -size +5M -printf "%k %p\n" # k=KB p=filename | |
| } | |
| (( 0 )) && { # Some X notes | |
| xset q # shows current settings | |
| } | |
| (( 0 )) && { # list shared memory processes with ipcs, extract the cpid (creator pid ??), | |
| # then find each pid is the output of ps. | |
| # Thanks to [email protected], msg author: dking@ketralnis | |
| # filter out verbiage in ipcs output using egrep. also, sort and remove dups. | |
| ipcs -pm |cut -c23-26 |egrep ^[0-9] |sort -n |uniq \ | |
| |while read r; do ps auxww |grep $r |grep -v 'grep'; done ### double spaces probably naf. | |
| # use perl rather than egrep. | |
| # ipcs -pm |cut -c23-26 |perl -n -e 'print if /^\d/' |sort -n |uniq \ | |
| # |while read r; do ps auxww |grep $r |grep -v 'grep'; done ### double spaces probably naf. | |
| } | |
| (( 0 )) && { # use grep to match *just* the pattern, not the whole line. | |
| # snap the urls from a logfile. then sort, count, sort numberic, and take top few. | |
| # egrep -o '(((http(s)?)://)[^/]+)' \ | |
| # ~/bin/support/check_access/check_access.log \ | |
| # |sort |uniq -c |sort -nr |head -n 4 | |
| # grep is smart enough to avoid passing color to a pipe. | |
| # but, it can be forced. | |
| egrep --color=always -o '(((http(s)?)://)[^/]+)' \ | |
| ~/bin/support/check_access/check_access.log \ | |
| |sort |uniq -c |sort -nr |head -n 4 | |
| } | |
| (( 0 )) && { # some ps one-liners | |
| ps -eo user,pcpu,pid,cmd | sort -r -k2 | head -6 # show processes in cpu % order. | |
| ps -eo pcpu,user,pid,cmd | sort -r | head -6 # show processes in cpu % order. | |
| } | |
| (( 0 )) && { # this is a list of ps options from elsewhere in this file. Plus a little more. | |
| # ToDo: sort thru and summarize. Make it easy to decide which to use. | |
| ps aux # 11 columns, as root or ja. | |
| ps auxw # no difference. | |
| ps auxww # no difference. | |
| ps ax # 5 cols, as ja or root. | |
| ps -f # see which processes are attached to the tty. Use with an ssh session to prevent hangs. | |
| ps xaf # tree-like, 5 cols: PID TTY STAT TIME COMMAND | |
| ps -eo pid,state,nice,args | |
| ps -e # all processes. 4 columns: PID TTY TIME CMD | |
| ps -eo pid:10,time,command # works. | |
| ps -eO rss # 6 cols: PID RSS S TTY TIME COMMAND | |
| ps -eo pid,rss,state,tname,time,command # save as above | |
| ps -eo pid,rss,vsz,time,command # 5 cols. | |
| ps -eo pid,rss=ResidentSetSize,vsz,time,command # same as above. | |
| ps -eo pid,rss:15,vsz,time,command # same as above. | |
| ps -eo user:15,pid,ppid,c,stime,tname,time,cmd | |
| ps -eo pid,ppid,%cpu,%mem,time,cmd:80 # did NOT limit col width. ??? | |
| ps -eo pid,ppid,%cpu,%mem,time,comm # just the command, no parms. | |
| ps -eo pid,ppid,%cpu,%mem,time,nice=Nice,rss=ResidentSetSize,comm | |
| ps -A # all processes owned by user | |
| ps -A -o rss,vsz,command| grep bash | |
| } | |
| (( 0 )) && { # Simple process selection options: | |
| echo | |
| # -A Select all processes (SAP). Identical to -e. | |
| # -N SAP except those that fulfill the specified conditions. | |
| # T SAP associated with this terminal. Identical to the t option without any argument. | |
| # -a SAP except session leaders (see getsid(2)) and processes not associated with a terminal. | |
| # a List all processes with a terminal (tty), or when used together with the x option. | |
| # -d SAP except session leaders. | |
| # -e SAP. Identical to -A. | |
| # r Restrict the selection to only running processes. | |
| # x List all processes owned by you (same EUID as ps), or when used together with the a option. | |
| # -w wide output. Use twice for unlimited width. | |
| } | |
| (( 0 )) && { # process status, including nice. | |
| # -e all precesses (everything) | |
| # -A All precesses (everything) | |
| # -o Format user defined format | |
| # ps -eo pid,state,nice,args | less | |
| # filter out most of the nice=0 lines. | |
| ps -eo pid,state,nice,args \ | |
| |grep -v '0 \[' \ | |
| |grep -v '0 \/' \ | |
| |grep -v '0 g' \ | |
| |grep -v '0 bash' \ | |
| |less | |
| } | |
| (( 0 )) && { # various formats for ps. | |
| # ps -e # all processes. 4 columns: PID TTY TIME CMD | |
| # ps -eo pid=ProcessID,time,command # does not work. | |
| # ps -eo pid:10,time,command # works. | |
| # ps -eO rss # 6 cols: PID RSS S TTY TIME COMMAND | |
| # ps -eo pid,rss,state,tname,time,command # save as above | |
| # ps -eo pid,rss,vsz,time,command # 5 cols. | |
| # ps -eo pid,rss=ResidentSetSize,vsz,time,command # same as above. | |
| # ps -eo pid,rss:15,vsz,time,command # same as above. | |
| # ps -eo user:15,pid,ppid,c,stime,tname,time,cmd | |
| # ps -eo pid,ppid,%cpu,%mem,time,cmd:80 # did NOT limit col width. ??? | |
| # ps -eo pid,ppid,%cpu,%mem,time,comm # just the command, no parms. | |
| ps -eo pid,ppid,%cpu,%mem,time,nice=Nice,rss=ResidentSetSize,comm | |
| } | |
| (( 0 )) && { # process status, ps | |
| # rss and vsz are in KB. | |
| # ps -A # all processes owned by user | |
| # list 3 columns for all bash processes | |
| # ps -A -o rss,vsz,command| grep bash | |
| # total the columns for rss and vsz. | |
| ps -A -o rss,vsz,command| grep bash \ | |
| |awk '{rss += $1; vsz += $2 } END { print "Real: ",rss, "Virtual: ",vsz }' | |
| } | |
| (( 0 )) && { # ack uses perl's regex at the cli. | |
| # Find all the modules used in a source tree. ie: use Module::Name::Text qw/ blah blah /; | |
| ack -h '^use\s+(\w+(?:::\w+)*).*' <SomeTree> --output=\$1 | sort -u | |
| # ja notes: use Module::Name::Text qw/ abcd efgh /; | |
| # ------ ( first \w+ match ) | |
| # ------ ( first ?:::\w+ match ) | |
| # ------ ( second ?:::\w+ match ) | |
| # ----------------- ( the .* match ) | |
| # ------------------ ( $1 ) | |
| # | |
| # run against ~ja/bin. probably do NOT need ~/public/lang/perl. | |
| } | |
| (( 0 )) && { # CPAN module installs. | |
| # From: Gavin Carr <[email protected]> | |
| # Subject: Re: [CentOS] Enbended Perl | |
| # To: CentOS mailing list <[email protected]> | |
| # [...] | |
| # It's a cpan module called Embperl. You can either install it straight from cpan: | |
| perl -MCPAN -e 'install Embperl' # enters endless dialog. ?? config file ?? | |
| # or look at using something like cpan2rpm (http://perl.arix.com/cpan2rpm/) | |
| } | |
| (( 0 )) && { # perl at the cli. print lines that match a pattern. then filter out unwanted. | |
| # in this specific case, look for the letter j, i, and m, with interveening characters, | |
| # filter out 'ism'. | |
| perl -ne 'print if /.*j.*i.*m/i' ~/etc/config/dict/linux.words \ | |
| |grep -iv 'ji' |grep -iv 'im' |grep -iv 'ism' |less | |
| # a code listing has line numbers like <spaces>=n=<spaces> before each line. | |
| # lines 1-9 have 5 spaces after the line number. 10-99 have 4 spaces. 100-999 have 3 spaces. | |
| # remove the line numbers and spaces. | |
| perl -n -e 's/^\s*=\d=\s{5}//; print' find_similar_images.pl \ | |
| | perl -n -e 's/^\s*=\d\d=\s{4}//; print' \ | |
| | perl -n -e 's/^\s*=\d\d\d=\s{3}//; print' \ | |
| | less | |
| } | |
| (( 0 )) && { # more perl at the cli. Randal L. Schwartz, 2006.11.02. www.samag.com | |
| f='/home/ja/temp/emedicine_image_hack'; | |
| # For text processing, we can add -n, which puts a wrapper around our program that looks like: | |
| # LINE: | |
| # while (<>) { | |
| # ... # rest of your program here | |
| # } | |
| # eg, print each line with a sequential line number in front. Use the $. variable for the numbers: | |
| # perl -n -e 'print "$.: $_"' $f | |
| # Another way to approach this problem is the -p, which adds a print at the end of the loop: | |
| # LINE: | |
| # while (<>) { | |
| # ... # your program here | |
| # print; | |
| # } | |
| # So, we could just substitute the line number into the beginning of each line: | |
| perl -pe 's/^/$.: /' $f | |
| } | |
| (( 0 )) && { # perl cli. count all occurances of a string, eg, jerry. | |
| # | |
| echo "jerry jerry" | perl -lane '$count = grep $_ =~ m/jerry/, @F; print $count' | |
| # From: "Ross S. W. Walker" <[email protected]> | |
| echo "jerry jerry" | awk 'BEGIN{RS=FS} /^jerry$/ {jerry++} END{print jerry}' | |
| # From: Stephen Harris <[email protected]> | |
| echo "jerry jerry" | tr -c '[:alnum:]' '\012' | grep -c jerry | |
| } | |
| (( 0 )) && { # perl at cli. http://programming.newsforge.com/article.pl?sid=06/03/08/1456241&from=rss | |
| # thanks: Hubert Chen | |
| # (see more examples later in this file.) | |
| # | |
| # perl cli options: | |
| # -p = "print" lines. assume input loop. | |
| # 0777 = "slurp" in whole file at once. | |
| # 00 = read files in "paragraph mode"; equivalent to undefining the $/ variable, ie INPUT_RECORD_SEPARATOR | |
| # -i = "in-place" file edits. | |
| # -e = "execute" this perl command. | |
| # -n = "no-print". assume input loop. | |
| # -a = "autosplit" each line. saves fields to @F | |
| # -l = auto "line" ending processing. | |
| # -F = "Field" delimiter. (default is space char, ie, " ") | |
| file=/home/ja/temp/FC5_notes | |
| # Edit the file in place and make a backup of the old version as well. | |
| # perl -pe 's/mp3/MP3/g' < $file > $file.new | |
| # make a backup with -i.old, then do in-place replacement. | |
| # perl -p -i.old -e 's/mp3/MP3/g' $file | |
| # do a bunch of files. | |
| # perl -p -i.old -e 's/oldstring/newstring/g' myfiles* | |
| # change all the strings in all files recursively: | |
| # find . | xargs perl -p -i.old -e 's/oldstring/newstring/g' | |
| # print the fourth word of every line, but also skip any line beginning with a #. | |
| # perl -naF -e 'next if /^#/; print "$F[3]\n"' < $file | |
| # extract all usernames from /etc/passwd. | |
| # perl -na -F: -e 'print "$F[0]\n"' < /etc/passwd | |
| # or: -F/:/ | |
| # To split on whitespace use -F'/\s+/'. | |
| # from the comments section: | |
| # Pick a random file (e.g. MP3) | |
| # ls /home/ja/temp | perl -e '@a=<>;print $a[rand(@a)]' | |
| # Shuffle the contents of a file | |
| # cat $file |perl -e '@a=<>;while(@a){print splice(@a,rand(@a),1)}' |less | |
| } | |
| (( 0 )) && { # perl cli, pattern matching. | |
| # Thanks Ben Browning, http://www.linux.com/article.pl?sid=06/01/17/2036214 | |
| # cat /etc/passwd | perl -ne 'print if $_=~/daemon/' | |
| # print line in passwd, if matches daemon | |
| # prints: daemon:x:2:2:daemon:/sbin:/sbin/nologin | |
| # and: haldaemon:x:68:68:HAL daemon:/:/sbin/nologin | |
| # from LWN comment at: http://lwn.net/Articles/169495/ | |
| perl -ne 'print if /daemon/' /etc/passwd # prints the same as above | |
| } | |
| (( 0 )) && { # perl at the cli. http://www.redhat.com/magazine/005mar05/features/perl/ | |
| # thanks: Chip Turner | |
| # | |
| # perl cli options: | |
| # -p = "print" lines. assume input loop. | |
| # -i = "in-place" file edits. | |
| # -e = "execute" this perl command. | |
| # -n = "no-print". assume input loop. | |
| # -a = "autosplit" each line. saves fields to @F | |
| # -l = auto "line" ending processing. | |
| # -F = "Field" delimiter. (default is space char, ie, " ") | |
| # seq 1 10 | perl -p -e '$_ = "prefix: $_"' # add a prefix to each variable | |
| # perl -p -e 's/:.*//' /etc/passwd # all system users. | |
| # perl -n -e '@fields = split /:/; print "$fields[0]\n"' /etc/passwd # all sysem users, again. 1/line. | |
| # perl -n -e '@fields = split /:/; chomp @fields; print "$fields[0], ";' /etc/passwd # comma seperated. | |
| # perl -l -a -n -e 'print $F[6]' ~/temp/access_log # list of URLs requested. 1/line | |
| # perl -a -n -e 'print $F[6]' ~/temp/access_log # list of URLs requested. mushed together. | |
| # perl -a -n -e 'print "$F[6], "' ~/temp/access_log # list of URLs requested. sep by ", ". | |
| # what are teh most requested files? | |
| # cat ~/temp/access_log | perl -l -a -n -e 'print $F[6]' | sort | uniq -c | sort -n | tail -n 10 | |
| # who is hitting the server the most? | |
| # cat ~/temp/access_log | perl -l -a -n -e 'print $F[0]' | sort | uniq -c | sort -n | tail -n 10 | |
| # make in-place changes to a large number of files. | |
| # find -type f -name '*.txt' | xargs perl -p -i -e 's/PLACEHOLDER/new_value/g' | |
| # perl -F: -l -a -n -e 'print $F[0]' /etc/passwd # all system users. using -F. 1/line. | |
| # perl -F: -a -n -e 'print "$F[0], "' /etc/passwd; echo # all system users. sep by ", " | |
| # cat ~/temp/access_log | perl -l -a -n -e '$n += $F[9]; } END { print $n' # total bytes server. | |
| # convert unix timestamps to human-readable form. | |
| # echo "1104903117 0.3" | perl -l -a -n -e 'print scalar(localtime $F[0]), " @F[1..$#F]"' | |
| echo "1104903117 0.3" > ~ja/temp/wierd-timestamp # Tue Jan 4 21:31:57 2005 | |
| echo "1104903177 0.4" >> ~ja/temp/wierd-timestamp # plus 60 | |
| echo "1104906717 0.5" >> ~ja/temp/wierd-timestamp # plus 3600 | |
| # cat ~ja/temp/wierd-timestamp | perl -l -a -n -e 'print scalar(localtime $F[0]), " @F[1..$#F]"' # ver 1 | |
| # cat ~ja/temp/wierd-timestamp | perl -l -a -n -e '$F[0] = scalar localtime $F[0]; print "@F"' # ver 2 | |
| # Perl at the command line: | |
| # | |
| # Reverse parts of a web address. | |
| # eg, www.whatever.com --> whatever.www.com | |
| # or, ftp.whatever.org --> whatever.ftp.org | |
| # perl -i.bak -p -e 's/(www|ftp)\.(.*?)\.(com|gov)/$2.$1.$3/gi' resources.php | |
| # | |
| } | |
| (( 0 )) && { # Start with "tolkien". using only these letters, find words in /usr/share/dict/linux.words | |
| # Thanks: http://perlbuzz.com/mechanix/2008/06/scrabble-cheating-with-perl-on.html | |
| perl -lne' print if /t/ && /o/ && /l/ && /k/ && /i/ && /e/ && /n/' /usr/share/dict/words |wc -l # prints: 294 | |
| perl -lne' print if /t/ && /o/ && /l/ && /k/ && /i/ && /e/ && /n/ && length($_)==8' /usr/share/dict/words # prints: knotlike, konilite, townlike | |
| # There were no words of 7 characters or less | |
| perl -lne' print if /t/ && /o/ && /l/ && /k/ && /i/ && /e/ && /n/ && length($_)<10' /usr/share/dict/words |wc -l # prints: 18 | |
| } | |
| (( 0 )) && { # bash string operations. 8. Get the 3rd last string (dots to seperate) from: | |
| # foo.bar.VALUE.baz.lala | |
| # or foor.bar.gigi.VALUE.baz.lala | |
| # from: Alex S.<[email protected]> | |
| echo foo.bar.VALUE.baz.lala | awk -F. '{ print $(NF-2); }' | |
| # from Stephen Harris <[email protected]> | |
| # Use IFS to split the string | |
| a=foo.var.VALUE.baz.lala | |
| OIFS="$IFS" # save Internal Field Separator | |
| IFS="." | |
| set -- $a # the positional parms are set to $a | |
| IFS="$OIFS" # restore IFS | |
| SHIFT=$(($# - 3)) # how many positional parms to shift off? | |
| shift $SHIFT | |
| echo $1 | |
| # Using string pattern matching | |
| a=foo.var.VALUE.baz.lala | |
| front=${a%.*.*.*} # cut shortest path from end, ie, cut the last three. | |
| b=${a#$front.} # cut shortest match from start, leaving the last three. | |
| b=${b%%.*} # cut longest match from end, leaving the 3rd from end. | |
| echo $b | |
| } | |
| (( 0 )) && { # bash string operations. 7. take a string and make it an array. | |
| message='Test Message' | |
| last=$(expr ${#message} - 1) | |
| declare -a msg # array msg will hold individual characters from $message | |
| for n in $(seq 0 $last) | |
| do | |
| msg[$n]="${message:$n:1}" | |
| echo -e "\t$n: \t${msg[$n]}" | |
| done | |
| } | |
| (( 0 )) && { # bash string operations. 6. Single and Global replacement. | |
| a='"this got quotation"' | |
| # echo ${a//\"/} # global replacement of | |
| #prints: this got quotation | |
| B="Four\nscore\nand\nseven\nyears\nago" | |
| echo $B | |
| echo "${B//\\n/ }" | |
| # prints: Four score and seven years ago | |
| } | |
| (( 0 )) && { # bash string operations. 5. | |
| # If $foo exists and is not null, return $foo, else return bar. | |
| # export foo="" | |
| # echo ${foo:-bar} one # prints: bar one | |
| # echo $foo # prints nothing | |
| # If $foo exists and is not null, return $foo, else set $foo to bar and return bar. | |
| # export foo="" | |
| # echo ${foo:=bar} one # prints: bar one | |
| # echo $foo one # prints: bar one | |
| # If $foo exists and is not null, return bar, else return a null. | |
| # export foo="this is a test" | |
| # echo ${foo:+bar} # prints: bar | |
| # If $foo exists and isn't null, return its value. | |
| # If it doesn't exist or is null, print the error message. | |
| export foo="" | |
| echo ${foo:?"this is an error message"} | |
| } | |
| (( 0 )) && { # bash string operations. 4. sub-string operator | |
| a="abcdef" | |
| b=${a:0:1}; echo $b # prints a | |
| c=${a:0:2}; echo $c # prints ab | |
| d=${a:2:2}; echo $d # prints cd | |
| e=${a:4}; echo $e # prints ef | |
| } | |
| (( 0 )) && { # bash string operations. 3. sub-string operation. start at specified position. | |
| devArray=(/dev/hda7 /dev/hda10 /dev/hda11 /dev/hda13) | |
| mapArray=(${devArray[0]:5} ${devArray[1]:5} ${devArray[2]:5} ${devArray[3]:5}) | |
| # eg: mapArray=(hda7 hda10 hda11 hda13) ## ":5" means start at position 5, zero based. | |
| mntArray=(/tmp /mnt/bergen /mnt/trondheim /mnt/oslo) | |
| for (( i=0 ; i < ${#devArray[@]} ; ++i )) | |
| do | |
| echo | |
| dev=${devArray[$i]} ; echo " dev: $dev" | |
| map=${mapArray[$i]} ; echo " map: $map" | |
| mnt=${mntArray[$i]} ; echo " mnt: $mnt" | |
| done | |
| } | |
| (( 0 )) && { # bash string operations. 2. "String operations using \"expr \$string : \" construct" | |
| a=1234zipper5FLIPPER43231 | |
| echo -e "\tString being operated on: \"`expr "$a" : '\(.*\)'`\"." # note escaped parens. | |
| echo -e "\tLength: `expr "$a" : '.*'`." # Length of string | |
| echo -e "\tNumber of digits at the beginning: `expr "$a" : '[0-9]*'`." | |
| echo -e "\tDigits at the beginning: `expr "$a" : '\([0-9]*\)'`." | |
| echo -e "\tFIRST 7 chars: `expr "$a" : '\(.......\)'`." # parens | |
| echo -e "\tLAST 7 chars: `expr "$a" : '.*\(.......\)'`." # note .* before parens. | |
| } | |
| (( 0 )) && { # bash string operations. 1. | |
| a=1234zipper43231 | |
| echo -e "\tThe string being operated on is \"$a\"." | |
| echo -e "\tLength of \"$a\" is $(expr length $a)." | |
| echo -e "\tNumerical position of first \"2\" in \"$a\" is \"$(expr index $a 23)\"." | |
| echo -e "\tSubstring of \"$a\", starting at position 2, and 6 chars long is \"$(expr substr $a 2 6)\"." | |
| # The default behavior of the 'match' operations is to | |
| #+ search for the specified match at the ***beginning*** of the string. | |
| # | |
| # uses Regular Expressions | |
| b=`expr match "$a" '[0-9]*'` # Numerical count. | |
| echo -e "\tNumber of digits at the beginning of \"$a\" is $b." | |
| b=`expr "$a" : '[0-9]*'` # exact equivalent above | |
| echo -e "\tNumber of digits at the beginning of \"$a\" is $b." | |
| b=`expr match "$a" '\([0-9]*\)'` # escaped parentheses trigger substring match | |
| echo -e "\tThe digits at the beginning of \"$a\" are \"$b\"." | |
| b=`expr $a : '\([0-9]*\)'` # exact equivalent above | |
| echo -e "\tThe digits at the beginning of \"$a\" are \"$b\"." | |
| } | |
| (( 0 )) && { # bash string operations. 0. | |
| # Thanks to Pat Eyler at http://www.linuxjournal.com/article/8919 | |
| export $foo="this is a test" | |
| # del shortest match from left | |
| echo ${foo#t*is} # prints: is a test | |
| # del longest match from left | |
| echo ${foo##t*is} # prints: a test | |
| # del shortest match from right | |
| echo ${foo%t*st} # prints: this is a | |
| # del longest match from right | |
| echo ${foo%%t*st} # prints nothing | |
| # A convenient mnemonic: | |
| # The # key is on the left side of the $ key and operates from the left. | |
| # The % key is on the right of the $ key and operates from the right. | |
| } | |
| (( 0 )) && { # more string operations. | |
| # Thanks: http://linuxgazette.net/114/okopnik.html | |
| var="amanuensis" # Let's pick a nice, longish word to play with. | |
| echo ${#var} # ${#var} - return length. prints "10" | |
| echo ${var#*n} # ${var#word} - cut shortest match from start. prints "uensis" | |
| echo ${var##*n} # ${var##word} - cut longest match from start. prints "sis" | |
| echo ${var%n*} # ${var%word} - cut shortest match from end. prints "amanue" | |
| echo ${var%%n*} # ${var%%word} - cut longest match from end. prints "ama" | |
| echo ${var:7} # ${var:offset} - return string starting at 'offset'. prints "sis" | |
| echo ${var:1:3} # ${var:offset:l} - return l chars starting at 'offset'. prints "man" | |
| echo ${var/amanuen/paralip} # ${var/pattern/string} - replace single match. prints "paralipsis" | |
| echo ${var//a/A} # ${var//pattern/string} - replace all matches. prints "AmAnuensis" | |
| experiment=supercallifragilisticexpialadocious | |
| echo ${experiment%l*} # prints "supercallifragilisticexpia" | |
| echo ${experiment%%l*} # prints "superca" | |
| echo ${experiment#*l} # prints "lifragilisticexpialadocious" | |
| echo ${experiment##*l} # prints "adocious" | |
| } | |
| (( 0 )) && { # Using \b (backspace) for fun and profit. | |
| echo -en "\tHave a very nice day, Sir." | |
| sleep 2 | |
| echo -e "\b\b\b\bButtBreath." | |
| } | |
| (( 0 )) && { # for z22, convert a .jpg file to a .jpg.pdb file | |
| # thanks: http://www.thehaus.net/index.php?ent=4938 for par usage | |
| # thanks: http://www.djw.org/product/palm/par/ for par program | |
| # source: LOGOS2.jpg destination: LOGOS2.jpg.pdb | |
| # par c -a "stream" LOGOS2.jpg.pdb LOGOS2.jpg Foto Foto LOGOS2.jpg | |
| cd /home/ja/public/in_work/pda_images | |
| from=tom_160.jpg | |
| to=$from.pdb | |
| /data/downloads/z22/par/prc/par c -a "stream" test_160.jpg.pdb tom_160.jpg Foto Foto tom_160.jpg | |
| # The above will create a file test_160.jpg.pdb that I am unable | |
| # to install into my z22 with pilot-xfer or pilot-foto. | |
| } | |
| (( 0 )) && { # pass an array to a function and return an array from the function. | |
| Pass_Array () | |
| { | |
| local my_local_array | |
| my_local_array=( $(echo "$1") ) # assign argument to local array variable | |
| # do something to array. | |
| echo "${my_local_array[@]}" | |
| } | |
| original=( element1 element2 element3 element4 element5 ) | |
| echo -e "\tOriginal: ${original[@]}" # space-separated list of elements. | |
| argument=$( echo ${original[@]} ) # Pack a var with a space-separated list of elements | |
| echo -e "\tArgument: $argument" | |
| echo -e "\tEchoed : $(Pass_Array "$argument")" # echo what the function returns. | |
| returned=( $(Pass_Array "$argument") ) # Assign output of function to array variable. | |
| echo -e "\tReturned: ${returned[@]}" | |
| exit 0 | |
| } | |
| (( 0 )) && { # Array basics. | |
| array=(one two three four [5]=five) | |
| echo "Array size: ${#array[*]}" | |
| echo "Array items:" | |
| for item in ${array[*]}; do printf " %s\n" $item; done | |
| echo "Array indexes:" | |
| for index in ${!array[*]}; do printf " %d\n" $index; done | |
| echo "Array items and indexes:" | |
| for index in ${!array[*]}; do printf "%4d: %s\n" $index ${array[$index]}; done | |
| } | |
| (( 0 )) && { # sort an array. send each element of array to a file; sort the file; build new array. | |
| array1=(a x t g u o p w d f z l) | |
| echo "Array 1: ${array1[@]}" | |
| declare -a array2 | |
| touch tmp | |
| for i in ${array1[@]}; | |
| do | |
| echo $i >> tmp | |
| done | |
| sort tmp -o tmp | |
| while read line; | |
| do | |
| array2=(${array2[@]} $line) | |
| done < tmp | |
| rm tmp | |
| echo "Array 2: ${array2[@]}" | |
| } | |
| (( 0 )) && { # play with arrays | |
| declare -a some # declare array some | |
| some[0]=zero # add element to array | |
| some[1]=one # ditto | |
| some[2]="one two" | |
| some[3]="a b c" | |
| # echo ${#some[*]} # prints: 4 | |
| # echo ${some[*]} # prints: zero one one two a b c | |
| # for e in "${some[*]}" ; do echo "$e"; done # prints: zero one one two a b c | |
| # for e in ${some[*]} ; do echo $e; done # prints: 7 rows. burp! | |
| # for e in ${some[@]} ; do echo $e; done # prints: 7 rows. burp! | |
| echo -e "\n\t===== Just a simple echo" | |
| for e in "${some[@]}" ; do echo "$e"; done # prints: 4 rows. Yeah! | |
| ### Conclusion, use "${some[@]}" | |
| some[4]=one # add redundant element to array | |
| some[${#some[*]}]=zero # ditto | |
| some[${#some[*]}]="a b c" # ditto | |
| echo -e "\n\t===== Just a simple echo" | |
| for e in "${some[@]}" ; do echo "$e"; done # prints: 7 rows. | |
| echo -e "\n\t===== And a sort unique" | |
| for e in "${some[@]}" ; do echo "$e"; done |sort -u # prints: 4 rows. | |
| } | |
| (( 0 )) && { # using [*] and [@] with/without quotes | |
| array=("first item" "second item" "third" "item") # 4 items in array. | |
| echo "Number of items in original array: ${#array[*]}" # produces 4 items. USE This form. | |
| for ix in ${!array[*]}; do printf " %s\n" "${array[$ix]}"; done | |
| echo | |
| arr=(${array[*]}) | |
| echo "After unquoted expansion: ${#arr[*]}" # produces 6 items. | |
| for ix in ${!arr[*]}; do printf " %s\n" "${arr[$ix]}"; done | |
| echo | |
| arr=("${array[*]}") | |
| echo "After * quoted expansion: ${#arr[*]}" # produces 1 item. | |
| for ix in ${!arr[*]}; do printf " %s\n" "${arr[$ix]}"; done | |
| echo | |
| arr=("${array[@]}") | |
| echo "After @ quoted expansion: ${#arr[*]}" # procudes 4 items. OR use this form. | |
| for ix in ${!arr[*]}; do printf " %s\n" "${arr[$ix]}"; done | |
| } | |
| (( 0 )) && { # Read a file, one record per line, 4 fields per record. | |
| # NB: structured data file, no tabs, just spaces and newlines. | |
| # Thanks: http://linuxgazette.net/114/okopnik.html | |
| fn=/home/ja/temp/temp_fn_$$ | |
| #23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 | |
| cat <<-_BOINK_ > $fn | |
| Jim & Fanny Friends Business 101101 Digital Dr. LA CA [email protected] | |
| Fred & Wilma Rocks friends 12 Cave St. Granite, CT [email protected] | |
| Joe 'Da Fingers' Lucci Business 45 Caliber Av. B-klyn NY [email protected] | |
| Yoda Leahy-Hu Friend 1 Peak Fribourg Switz [email protected] | |
| Cyndi, Wendi, & Myndi Friends 5-X Rated St. Holiday FL [email protected] | |
| _BOINK_ | |
| declare -a name category address email # explicitly declare these variables as arrays. | |
| OLD=$IFS # save intra field seperator | |
| IFS=' | |
| ' | |
| for line in $(cat $fn) | |
| do | |
| ((x++)) # Inc line counter | |
| name[$x]="${line:0:24}" # load the 'name' variable | |
| name[$x]="$(echo ${name[$x]} |sed -e 's/ *$//')" # remove trailing spaces | |
| category[$x]="${line:24:11}" | |
| category[$x]="$(echo ${category[$x]} |sed -e 's/ *$//')" | |
| address[$x]="${line:35:32}" | |
| address[$x]="$(echo ${address[$x]} |sed -e 's/ *$//')" | |
| email[$x]="${line:67:20}" | |
| email[$x]="$(echo ${email[$x]} |sed -e 's/ *$//')" | |
| # printf "\t%-24s %-11s %-32s %-20s \n" ${name[$x]} ${category[$x]} ${address[$x]} ${email[$x]} | |
| done | |
| IFS=$OLD # restore $IFS | |
| echo -e "\n\tLook for records with category = friends \n" | |
| for y in $(seq $x) | |
| do | |
| if [ -z "${category[$y]##[Ff]riend*}" ] | |
| then | |
| printf "\t%-24s %-11s %-32s %-20s \n" "${name[$y]}" \ | |
| "${category[$y]}" "${address[$y]}" "${email[$y]}" | |
| fi | |
| done | |
| } | |
| (( 0 )) && { # Where did this come from ???? | |
| echo Where did this come from? | |
| # Never write it in 'C' if you can do it in 'awk'; | |
| # Never do it in 'awk' if 'sed' can handle it; | |
| # Never use 'sed' when 'tr' can do the job; | |
| # Never invoke 'tr' when 'cat' is sufficient; | |
| # Avoid using 'cat' whenever possible. | |
| # -- Taylor's Laws of Programming | |
| } | |
| (( 0 )) && { # make tempfile within temp dir | |
| TDIR=$(mktemp -d ~ja/temp/tempdir.XXXXXXXXXX) || exit 1 | |
| TFILE=$(mktemp $TDIR/tempfile.XXXXXXXXXX) || exit 1 | |
| echo -e "\tTDIR: $TDIR \t TFILE: $TFILE " | |
| } | |
| (( 0 )) && { # With FireFox, print to a file, eg hayward_viper.ps, then convert to pdf. | |
| ps2pdf hayward_viper.ps hayward_viper.pdf | |
| } | |
| (( 0 )) && { # Which pdf utilities might be useful | |
| ls /usr/bin/*pdf* |while read F; | |
| do | |
| P=$(rpm -qf $F); | |
| printf " %30s : %s \n" "$P" "$F"; | |
| done \ | |
| |egrep -v 'docbook|ghost|tetex|xmltex|texinfo|foo|jade' \ | |
| |sort >> ~ja/temp/pdf_options | |
| # prints: | |
| # Package Utility Purpose | |
| #-------------------------------- --------------------- ------------------- | |
| # kdegraphics-3.5.9-1.fc7 : /usr/bin/kpdf # reader | |
| # libtiff-3.8.2-8.fc7 : /usr/bin/tiff2pdf # tiff to pdf | |
| # pdfedit-0.3.2-2.fc7 : /usr/bin/pdfedit # editor, immature | |
| # pdftk-1.41-5.fc7 : /usr/bin/pdftk # EOL due to license problems | |
| # poppler-utils-0.5.4-8.fc7 : /usr/bin/pdffonts # font analyzer | |
| # poppler-utils-0.5.4-8.fc7 : /usr/bin/pdfimages # extract images | |
| # poppler-utils-0.5.4-8.fc7 : /usr/bin/pdfinfo # pdf info | |
| # poppler-utils-0.5.4-8.fc7 : /usr/bin/pdftohtml # | |
| # poppler-utils-0.5.4-8.fc7 : /usr/bin/pdftoppm # | |
| # poppler-utils-0.5.4-8.fc7 : /usr/bin/pdftops # | |
| # poppler-utils-0.5.4-8.fc7 : /usr/bin/pdftotext # | |
| # xpdf-3.02-4.fc7 : /usr/bin/xpdf # reader | |
| } | |
| (( 0 )) && { # extract images and text from a pdf document | |
| /usr/local/bin/pdfimages -f 40 -l 43 -j dpf_file_name image_prefix | |
| /usr/local/bin/pdftotext -f 40 -l 43 dpf_file_name text_filename | |
| } | |
| (( 0 )) && { # Using poppler-tools and psutils, extract a range of pages from a PDF. | |
| # For example, extract pages 11–14 of the PDF file afile.pdf | |
| pdftops afile.pdf - | psselect -p11-14 | ps2pdf - file-p11-14.pdf | |
| } | |
| (( 0 )) && { # use xmlwf to check if an xml document is well formed | |
| # the first, third, and fourth files are well formed. | |
| # the second (test_wf.xml) is not. An early start tag was changed. | |
| # it issues a result like: | |
| # Result for file .../test_wf.xml: .../test_wf.xml:24:2: mismatched tag | |
| # which identifies what should be the closing tag as a mismatch. | |
| for f in \ | |
| /home/ja/public/linux/database/dbd4/books.xml \ | |
| /home/ja/public/linux/database/dbd4/test_wf.xml \ | |
| /home/ja/public/kin/a/bloglines_export.xml \ | |
| /home/ja/.gaim/prefs.xml | |
| do | |
| # If normal file, check WF-ness. Result => not WF, so print result. No result => WF. | |
| res='' && [ -f $f ] && res=$( /usr/bin/xmlwf $f ) && [ ${#res} -gt 0 ] && echo -e "\tResult: $res" | |
| done | |
| # see also: ~ja/bin/well_formed_check.sh | |
| # which could be used in a "find" command, ie: | |
| # find . -iname '*.xml' -type f -execdir ~/bin/well_formed_check.sh {} \; | |
| } | |
| (( 0 )) && { # make sure html file permissions are 644 for web page dirs. | |
| for fn in fun hardware in_work kin linux nontech web | |
| do | |
| find ~/public/$fn -iname '*.html' -type f -execdir chmod 644 {} \; | |
| if [ $(find ~/public/$fn -iname '*.html' -type f -execdir ls -dl {} \; |grep -v '\-rw\-r\-\-r\-\-' |wc -l) -gt 0 ] | |
| then | |
| find ~/public/$fn -iname '*.html' -type f -execdir ls -dl {} \; |grep -v '\-rw\-r\-\-r\-\-' |less | |
| fi | |
| done | |
| } | |
| (( 0 )) && { # make sure dir permissions are 755 for web page dirs. | |
| for dir in fun hardware in_work kin linux nontech web | |
| do | |
| find ~/public/$dir -type d -execdir chmod 755 {} \; | |
| if [ $(find ~/public/$dir -type d -execdir ls -dl {} \; |grep -v 'drwxr-xr-x' |wc -l) -gt 0 ] | |
| then | |
| find ~/public/$dir -type d -execdir ls -dl {} \; |grep -v 'drwxr-xr-x' |less | |
| fi | |
| done | |
| } | |
| (( 0 )) && { # given IP address, find MAC address. on same lan | |
| ip=192.168.0.12 | |
| ping -c 1 $ip >/dev/null # tiny pings quiettoo. count (c) of 1. | |
| /sbin/arp -a $ip # retrieve from arp cache | |
| } | |
| (( 0 )) && { # switch stderr and stdout. test stderr for condition and then act. | |
| # thanks to "Linux Server Hacks" by Rob Flickenger. | |
| [ ! $(whoami) = 'root' ] && echo "Must be root to execute." && exit | |
| if [ $(crontab -u elh -l 3>&2 2>&1 1>&3 |grep "no crontab" |wc -l) -eq 1 ]; then echo Gotcha; fi | |
| } | |
| (( 0 )) && { # Find the largest 20 files. Thanks: "Rick Moen" <[email protected]> | |
| ### find options: | |
| # | |
| # -xdev and -mount: Don't descend dirs on other filesystems. | |
| # | |
| # -print0: Print full fn, followed by null char. | |
| # Then use `-0' or `--null' option to GNU xargs, GNU tar, GNU cpio, or perl. | |
| ### xargs options: | |
| # | |
| # --null or -0: Terminate filenames with null char (not whitespace). | |
| # Quotes and backslash are not special (every char is taken literally). | |
| # Useful when args might contain white space, quote marks, or backslashes. | |
| # GNU find -print0 option produces input suitable for this mode. | |
| # | |
| # -r: If the standard input does not contain any nonblanks, | |
| # do not run the command. | |
| # Normally, the command is run once even if there is no input. | |
| echo | |
| echo "The 20 largest files in or under `pwd`:" | |
| find . -xdev -type f -print0 | xargs -r0 ls -l | sort -rn +4 | head -n 20 # nice and fast | |
| } | |
| (( 0 )) && { # see if a user has a password | |
| # /etc/shadow has encrypted 34-character user password in the second position | |
| # Or, the second position may contain "x", "*", "!!" or null | |
| # So, if the lenght of the character string is greater than 2, the user has an encrypted password | |
| fn=/etc/shadow | |
| for u in ja elh guest | |
| do | |
| pw=$(cat $fn |grep ^$u: |cut -d ':' -f 2) | |
| # len=${#pw} | |
| # echo -e "\tLenght of password for user $u: \t$len" | |
| # [ $len -gt 2 ] && echo -e "\tUser $u has a password." | |
| [ ${#pw} -gt 2 ] && echo -e "\tUser $u has a password." | |
| done | |
| } | |
| (( 0 )) && { # several commands might work. find one that is installed | |
| # from the bash manual: "type [-aftpP] name [name ...]", | |
| # With no options, indicate how each name would be interpreted if used as a command name. | |
| # If the -t option is used, type prints a string which is one of alias, keyword, function, builtin, or | |
| # file if name is an alias, shell reserved word, function, builtin, or disk file, respectively. | |
| # type returns true if any of the arguments are found, false if none are found. | |
| if type w3m >/dev/null 2>&1; then echo -e "\tWe have w3m" | |
| elif type lynx >/dev/null 2>&1; then echo -e "\tWe have lynx" | |
| else echo -e "\t$0: can't find w3m or lynx"; exit 1 | |
| fi | |
| } | |
| (( 0 )) && { # Deal with special characters that may come via .doc -> OOo -> plain text | |
| # Replace with entities: rsquo, lsquo, rdquo, ldquo, apos, hellip, ndash, mdash | |
| # ToDo | |
| # - lsquo | |
| # - apos needed? | |
| ttt="/home/ja/temp/ttt.temp" | |
| echo | |
| # for fn in ~/public/kin/gg/test/{01,28}* | |
| for fn in $(ls ~/public/kin/gg/test/* |grep -v '.txt') | |
| do | |
| echo $fn | |
| cat $fn |sed -e 's/…/\&hellip\;/' \ | |
| -e 's/\’/\&rsquo\;/' \ | |
| -e 's/\©/\©\;/' \ | |
| -e 's/\–/\&ndash\;/g' \ | |
| -e 's/\—/\&mdash\;/' \ | |
| -e 's/\“/\&ldquo\;/g' \ | |
| -e 's/\”/\&rdquo\;/g' \ | |
| > $ttt | |
| [ -f $fn ] && [ -f $ttt ] && rm $fn && mv $ttt $fn | |
| done | |
| } | |
| (( 0 )) && { # using getopts | |
| [ $# -eq 0 ] && echo "Error msg" && exit 65 | |
| while getopts ":mnopq:rs" Option | |
| do | |
| case $Option in | |
| m ) echo -e "\tScenario #1: option -m- [OPTIND=${OPTIND}]";; | |
| n | o ) echo -e "\tScenario #2: option -$Option- [OPTIND=${OPTIND}]";; | |
| p ) echo -e "\tScenario #3: option -p- [OPTIND=${OPTIND}]";; | |
| q ) echo -e "\tScenario #4: option -q- with argument \"$OPTARG\" [OPTIND=${OPTIND}]";; | |
| r | s ) echo -e "\tScenario #5: option -$Option-";; | |
| * ) echo -e "\tUnimplemented option chosen.";; # DEFAULT | |
| esac | |
| done | |
| shift $(($OPTIND - 1)) # just the args remain in $* | |
| # [ja@pacific ~]$ ~/bin/code_bash.sh -mnopqboink -rs | |
| # Scenario #1: option -m- [OPTIND=1] | |
| # Scenario #2: option -n- [OPTIND=1] | |
| # Scenario #2: option -o- [OPTIND=1] | |
| # Scenario #3: option -p- [OPTIND=1] | |
| # Scenario #4: option -q- with argument "boink" [OPTIND=2] | |
| # Scenario #5: option -r- | |
| # Scenario #5: option -s- | |
| } | |
| (( 0 )) && { # have several levels of verbosity | |
| vlevel=0 | |
| while getopts "v" flag; do | |
| case $flag in | |
| v) vlevel=$((vlevel +1)) ;; | |
| *) echo -e "\tKindly specify -v or -vv ... or nothing"; exit 1 ;; | |
| esac | |
| done | |
| echo -e "\tVlevel: $vlevel" | |
| } | |
| (( 0 )) && { # manipulate options and arguments. call as: $0 -a aaa -b bbbb -c option_one *.jpg | |
| echo -e "\t parms: $*" # prints: -a aaa -b bbbb -c option_one and expanded *.jpg files. | |
| while getopts "a:b:c" flag; do | |
| case $flag in | |
| a) my_a="$OPTARG" ;; | |
| b) my_b="$OPTARG" ;; | |
| c) my_c="true" ;; | |
| \?) echo "usage: $0 -a aaa -b bbb -c argument_1 arg_2 ..."; exit 1 ;; | |
| esac | |
| done | |
| echo -e "\t options: a: $my_a, b: $my_b, c: $my_c" # as expected. | |
| echo -e "\t m: ${OPTIND}, n: ${!OPTIND}" # m: 6, n: option_one, | |
| first_arg=${!OPTIND}; # ${!xxxx} is an "indirect reference", ie, value of $6. | |
| echo -e "\t first arg: $first_arg" # first arg: option_one | |
| shift $OPTIND # shift off first 6 parms. | |
| echo -e "\t parms: $*" # parms: just the expanded .jpg files. | |
| } | |
| (( 0 )) && { # SELinux utilities for mode of operation. # 1=enforceing, 0=permissive | |
| echo $(/usr/sbin/getenforce) # prints: Enforcing | |
| if [ /usr/sbin/selinuxenabled ] # prints enabled | |
| then echo enabled | |
| else echo disabled | |
| fi | |
| /usr/sbin/setenforce 0 | |
| echo $(/usr/sbin/getenforce) # prints: Permissive | |
| if [ /usr/sbin/selinuxenabled ] # prints enabled | |
| then echo enabled | |
| else echo disabled | |
| fi | |
| /usr/sbin/setenforce 1 | |
| echo $(/usr/sbin/getenforce) # prints: Enforcing | |
| if [ /usr/sbin/selinuxenabled ] # prints enabled | |
| then echo enabled | |
| else echo disabled | |
| fi | |
| } | |
| (( 0 )) && { # determine "device" in prep for cdrecord | |
| address=$(/usr/bin/cdrecord -scanbus |grep Removable |awk '{print $1}';) 1>/dev/null 2>/dev/null | |
| hn=$(/bin/hostname -s) | |
| case $hn in | |
| pacific) d=burp ;; | |
| quietone) d=$address ;; | |
| quiettoo) d="ATAPI:$hn" ;; | |
| *) d=double_burp ;; | |
| esac | |
| echo -e "\t Hostname: $hn \t device: $d " | |
| } | |
| (( 0 )) && { # Spelling | |
| echo -e "\nTest 1. correct spelling => heading only" | |
| echo compatible|aspell -a | |
| echo -e "\nTest 2. incorrect spelling => heading and some options" | |
| echo compatable|aspell -a | |
| echo -e "\nTest 3. Spell check a file. prints mis-spelled words." | |
| fn=/home/ja/temp_fn_$$ | |
| cat <<-_BOINK_ > $fn | |
| Now is the time for all good men ansd women | |
| to come to the aid of their country. | |
| Four score and seven years ago, out for-fathers brought forth in this continant, | |
| a new nation, concieved in liberaty and dedicated to the proposition that all | |
| men are created equal. | |
| _BOINK_ | |
| spell $fn | |
| rm $fn | |
| echo -e "\nTest 4. Look in dict for words matching _active_." | |
| look active # prints active and actively | |
| echo -e "\nTest 5. Look in dict for words matching _inkorrectrly_." | |
| look inkorrectrly # no output | |
| echo -e "\nTest 6. Look in dict for words matching _percei_." | |
| look percei # prints 8 matching words | |
| } | |
| (( 0 )) && { # process chunks of data from some program. (Thanks to Jerry Peek, Linux Mag., Oct 2004) | |
| fn=/etc/httpd/conf/httpd.conf | |
| cat $fn | | |
| while : | |
| do | |
| chunk=$(dd count=1 bs=1024 2>/dev/null) | |
| # test -z "$chunk" && break | |
| [ -z "$chunk" ] && break | |
| echo -n "." # do processing here for each chunk | |
| # in this case, prints 35 dots. | |
| done | |
| } | |
| (( 0 )) && { # less options | |
| # Created by Ben Okopnik on Sun Jun 13 11:03:00 EDT 2004 | |
| p="Press 'q' to quit" | |
| q="'direct rendering' should be marked 'Yes'\. $p" | |
| r="Press 'n' to see the next warning or error" | |
| LIBGL_DEBUG=verbose glxinfo 2>&1 |less -P"$q" | |
| dmesg |egrep -i 'agp|drm' |less -P"$p" | |
| less -P "$r" -p "\(WW|EE\)" /var/log/XFree86.0.log | |
| } | |
| (( 0 )) && { # parse logfile | |
| logfile='/var/log/httpd/error_log.2' | |
| ( | |
| echo "Here is a report of the top 20 'missing' files in $logfile" | |
| echo | |
| for x in `grep "File does not exist:" $logfile |awk '{print $13}' |sort |uniq`; | |
| do | |
| grep $x $logfile | wc -l | tr -d '\n' | |
| echo " : $x" | |
| done | sort +2 -rn | head -n 20 | |
| ) | mail -s "Missing File Report" ja@quiettoo | |
| } | |
| (( 0 )) && { # send mail from within bash ( <<- means remove leading tab characters. ) | |
| mail -s 'a subject line' ja@localhost > /dev/null 2> /dev/null <<- "ENDMAIL" | |
| This is line 1 of the body of the email message. | |
| This is line 2 of the body of the email message. | |
| This is line 3 of the body of the email message. | |
| This is line 4 of the body of the email message. | |
| This is line 5 of the body of the email message. | |
| This is line 6 of the body of the email message. | |
| This is line 7 of the body of the email message. | |
| This is line 8 of the body of the email message. | |
| This is line 9 of the body of the email message. | |
| ENDMAIL | |
| } | |
| (( 0 )) && { # Get files/documents using curl (thanks to Linux Journal) | |
| # | |
| # from article. -s=silent -i=include_http_header -H=Header | |
| curl -s -i -H "Referer: http://www.livejournalx.com" 'http://www.notbig.org/fam/jim_tn.jpg' | head -n 1 | |
| # curl -s -i -H "Referer: http://www.livejournal.com" 'http://www.notbig.org/fam/jim_tn.jpg' | head -n 1 | |
| # curl -s -i 'http://www.notbig.org/fam/jim_tn.jpg' | head -n 1 | |
| # results: HTTP/1.1 200 OK | |
| # -v=verbose, use own jpg. | |
| # curl -v -i 'http://www.notbig.org/fam/jim_tn.jpg' | head # results: 25 lines of header stuff. | |
| # curl -i 'http://www.notbig.org/fam/jim_tn.jpg' | head -n 1 # results: download stats | |
| # curl -s -i 'http://www.notbig.org/fam/lists.php' | head -n 1 # results: HTTP/1.1 200 OK | |
| # curl -s -i 'http://www.notbig.org/fam/lists.php' > curl_output # headers, blank line, file contents | |
| # -I=head only | |
| # curl -I -s -i 'http://www.notbig.org/fam/lists.html' > curl_output # results: nothing | |
| # curl -I -i 'http://www.notbig.org/fam/lists.html' > curl_output # results: stats | |
| } | |
| (( 0 )) && { # check /var/run for files named *.pid | |
| # do a "kill -0 PID" and check return code to see if process is processing signals. | |
| # OR, just parse ps output. | |
| for F in /var/run/atd.pid | |
| do | |
| PID=$(cat $F |head -n 1) | |
| kill -0 $PID | |
| errmsg=$? | |
| printf " Process: %-25s \tPID: %-8s \tErrorMsg: %s \n" "$F" "$PID" "$errmsg" | |
| done | |
| } | |
| (( 0 )) && { # This script traps CTRL-C (SIGINT) and CTRL-Z (SIGTERM) | |
| # | |
| # when run in the foreground: | |
| # CTRL-C (interrupt) will result in a message, | |
| # CTRL-Z (suspend) will stop the script and put it in the bg | |
| # use fg to get it in the fg | |
| # use 'kill -KILL %2' to really kill it (after a suitable delay). | |
| # | |
| # when run in bg, the script will NOT respond to either signal | |
| trap "echo 'You hit control-C!'" INT # ctrl c | |
| trap "echo 'You tried to terminate me!'" TERM # ctrl z | |
| trap 'echo "exiting script"' EXIT # finish normally, or by an explicit 'exit', or by getting a 'INT' or 'TERM' signal | |
| while true; do | |
| echo -n "sleeping, " | |
| sleep 4 | |
| done | |
| } | |
| (( 0 )) && { # "kill" info | |
| echo | |
| # [ja@hudson ~]$ kill -l | |
| # 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL | |
| # 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE | |
| # 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 | |
| # 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT | |
| # 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP | |
| # 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU | |
| # 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH | |
| # 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN | |
| # 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 | |
| # 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 | |
| # 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 | |
| # 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 | |
| # 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 | |
| # 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 | |
| # 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 | |
| # 63) SIGRTMAX-1 64) SIGRTMAX | |
| # See /usr/include/asm/signal.h on Fedora8 for name and number. | |
| # From: "Filipe Brandenburger" <[email protected]> | |
| # > aux' and issue the command 'kill -9 pidofprocess'. If you know the | |
| # > name of the process you may use 'killall -9 processname'. | |
| # ... | |
| # Why the hell -9? | |
| # TERM is -15 and HUP is -1 (but I would stick to the names). | |
| # Using -9 is almost always the wrong answer. It's a last resort when everything else failed, | |
| # and it should be reserved for such. One should never use this command on a day-to-day basis, | |
| # much less teach it or suggest it in a mailing list like this one. | |
| # From Randal L. Schwartz | |
| # No no no. Don't use kill -9 (SIGKILL). | |
| # It doesn't give the process a chance to cleanly: | |
| # 1) shut down socket connections | |
| # 2) clean up temp files | |
| # 3) inform its children that it is going away | |
| # 4) reset its terminal characteristics | |
| # and so on and so on and so on. | |
| # Generally, send 15 (SIGTERM), wait 1-2 sec, then send 2 (SIGINT), and if that doesn't work, send 1 (SIGHUP). | |
| # If that doesn't, REMOVE THE BINARY because the program is badly behaved! | |
| # So: "kill -15 pids", wait, "kill -2 pids", "kill -1 pids" | |
| } | |
| (( 0 )) && { # More "kill" info | |
| echo | |
| # From "info kill": | |
| # | |
| # The following signal names and numbers are supported on all POSIX compliant systems: | |
| # | |
| # `HUP' 1. Hangup. | |
| # `INT' 2. Terminal interrupt. | |
| # `QUIT' 3. Terminal quit. | |
| # `ABRT' 6. Process abort. | |
| # `KILL' 9. Kill (cannot be caught or ignored). | |
| # `ALRM' 14. Alarm Clock. | |
| # `TERM' 15. Termination. | |
| # | |
| # Other supported signal names have system-dependent corresponding numbers. | |
| # All systems conforming to POSIX 1003.1-2001 also support the following signals: | |
| # | |
| # `BUS' Access to an undefined portion of a memory object. | |
| # `CHLD' Child process terminated, stopped, or continued. | |
| # `CONT' Continue executing, if stopped. | |
| # `FPE' Erroneous arithmetic operation. | |
| # `ILL' Illegal Instruction. | |
| # `PIPE' Write on a pipe with no one to read it. | |
| # `SEGV' Invalid memory reference. | |
| # `STOP' Stop executing (cannot be caught or ignored). | |
| # `TSTP' Terminal stop. | |
| # `TTIN' Background process attempting read. | |
| # `TTOU' Background process attempting write. | |
| # `URG' High bandwidth data is available at a socket. | |
| # `USR1' User-defined signal 1. | |
| # `USR2' User-defined signal 2. | |
| # | |
| # ... and so on. | |
| } | |
| (( 0 )) && { # Weak example. Send cli text to an email account. Prevent an INT or TERM from | |
| # leaving a mess. | |
| # | |
| # if this script is interrupted by a signal, then 'rm $msgfile' may not get run | |
| # so, trap signals and run function cleanup | |
| # | |
| function cleanup { | |
| if [ -e $msgfile ]; then mv $msgfile dead.letter; fi | |
| exit | |
| } | |
| trap cleanup INT TERM | |
| msgfile=/home/ja/temp/msg_temp_$$ # $$=pid | |
| cat > $msgfile # cli text to $msgfile | |
| # send $msgfile to an email address... | |
| rm $msgfile | |
| } | |
| (( 0 )) && { # Issue a message on termination. | |
| # | |
| : | |
| trap 'echo Thank you for playing' EXIT | |
| magicnum=$(($RANDOM%10+1)) # ??? | |
| echo 'Guess a number between 1 and 10:' | |
| while echo -n 'Guess: ' >&2 ; read guess; | |
| do | |
| sleep 1 | |
| if [ "$guess" = $magicnum ]; then | |
| echo 'Right!' | |
| exit | |
| fi | |
| echo 'Wrong!' | |
| done | |
| } | |
| (( 0 )) && { # review files from remote hosts | |
| # NB: ssh keys pairs must be setup prior. Eg, on fundy: | |
| cd ~ja/.ssh | |
| scp ./id_dsa.pub baffin:.ssh/authorized_keys2 | |
| # copy remote file to local. | |
| scp ja@baffin:/etc/yum/yum-updatesd.conf ~ja/temp/baffin_yum-updatesd.conf | |
| echo | |
| } | |
| (( 0 )) && { # Push a file to several remote servers. | |
| # This would be more useful w/o a password prompt. | |
| # Could be put in .bashrc | |
| work_server[0]="quietone" | |
| work_server[1]="quiettoo" | |
| work_server[2]="pacific" | |
| function servers() | |
| { | |
| for host in "${work_server[@]}" | |
| do | |
| scp $1 ja@$host:$2 | |
| done | |
| } | |
| servers $1 $2 | |
| } | |
| (( 0 )) && { # remote into baffin, run uname -a, send results to local pipeline. | |
| ssh baffin uname -a |cut -d'#' -f1 | |
| } | |
| (( 0 )) && { # Run an X app on a remote server. (X11 forwarding) | |
| # ssh -Y ja@shuttle # setup forwarding. | |
| # then run an X app, like gedit | |
| # ssh -Y ja@shuttle 'gedit' # do it on 1 line. | |
| echo "Kindly enter password for ja on shuttle" # a helpful message. | |
| ssh -Y ja@shuttle 'gedit' | |
| # ssh -Y ja@tiny 'nautilus --no-desktop --browser' | |
| # ssh -Y ja@tiny 'gnome-terminal' | |
| # ssh -Y ja@tiny 'oocalc' # spreadsheet on tiny | |
| } | |
| (( 0 )) && { # Create a key pair | |
| # Generate a key if necessary: | |
| mkdir -p ~/.ssh | |
| chmod 700 ~/.ssh | |
| cd ~/.ssh | |
| ssh-keygen -t dsa | |
| # Or: | |
| # -N=new_passphrase -f=filename_of_keyfile. | |
| ssh-keygen -N '' -f ~/.ssh/id_dsa | |
| # Copy the public key to the remote host: | |
| scp -p id_dsa.pub remoteuser@remotehost: | |
| # Log into the remote host and install the public key: | |
| ssh -l remoteuser remotehost | |
| mkdir -p ~/.ssh | |
| chmod 700 ~/.ssh | |
| cat id_dsa.pub >> ~/.ssh/authorized_keys # Appending | |
| chmod 600 ~/.ssh/authorized_keys | |
| mv id_dsa.pub ~/.ssh # Optional | |
| logout | |
| # Or: | |
| #cat ~/.ssh/id_rsa.pub | ssh <REMOTE_SERVER> 'cat - >> ~/.ssh/authorized_keys2' | |
| # Or: | |
| #ssh-copy-id <REMOTE_SERVER> | |
| } | |
| (( 0 )) && { # With SSH you can also automatically login to a remote server, | |
| # gzip a series of files or folders, and | |
| # transfer the resulting tarball to your local machine, | |
| # without creating archives on the remote machine! | |
| # | |
| # from: http://www.linux.com/article.pl?sid=06/02/21/2025220 | |
| # Seems best to same login at each host. else, permissions | |
| # can be a problems. ?? | |
| # ja login to quietone | |
| from=/tmp/90 | |
| to=/home/ja/temp/test_elh_backup-`date +%Y%m%d`.tar.gz | |
| ssh ja@quietone "tar czpf - $from" | cat > $to | |
| } | |
| (( 0 )) && { # capture host loads from "uptime". Save to file. | |
| # NB: Better have SSH setup to NOT prompt for password. | |
| getLoad () | |
| { | |
| ssh ja@$1 "export TERM=linux; uptime" | | |
| sed -e 's/^.*load average://' | | |
| awk -F',' '{print $1,$2,$3}' | |
| } | |
| for HOST in quiettoo quietone | |
| do | |
| echo $HOST: $(getLoad $HOST) >> ~ja/public/in_work/uptime_loads/uptime_load_$HOST | |
| done | |
| } | |
| (( 0 )) && { # copy a tree on one server to a location on another server. preserve permissions. | |
| # p=perserve-permissions | |
| # | |
| cd /home/ja/etc | |
| tar -czf - config/ | ssh pacific "cd /home/ja; mv config config.bak; tar xzpf -" | |
| } | |
| (( 0 )) && { # Create a ramdisk | |
| MOUNTPT=/mnt/ramdisk | |
| SIZE=500 # blocks | |
| BLOCKSIZE=1024 # 1K block size | |
| DEVICE=/dev/ramdisk-test # ramdisk | |
| [ "$UID" -ne "0" ] && echo -e "\nMust be run by root. \n" && exit 1 | |
| mkdir -p $MOUNTPT | |
| IF='if=/dev/zero' # code folding vs dd | |
| eval "/bin/dd ${IF} of=$DEVICE count=$SIZE bs=$BLOCKSIZE" # Zero out RAM device. | |
| mke2fs $DEVICE # Create an ext2 filesystem on it. | |
| mount $DEVICE $MOUNTPT # Mount it. | |
| chmod 777 $MOUNTPT # Enables ordinary user to access ramdisk. | |
| # However, must be root to unmount it. | |
| echo -e "\n\t\"$MOUNTPT\" now available for use by ordinary users." | |
| } | |
| (( 0 )) && { # Creating a swapfile. | |
| FILE=/root/swap | |
| MINBLOCKS=40 | |
| [ "$UID" -ne "0" ] && echo -e "\nMust be root. \n" && exit 1 | |
| blocks=${1:-$MINBLOCKS} # Default is 40 blocks. | |
| [ "$blocks" -lt $MINBLOCKS ] && blocks=$MINBLOCKS # At least 40 blocks long. | |
| echo -e "\tCreating swap file of size $blocks blocks (KB)." | |
| IF='if=/dev/zero' # code folding vs dd | |
| eval "dd $IF of=$FILE bs=1024 count=$blocks" # Zero out file. | |
| mkswap $FILE $blocks # Designate it a swap file. | |
| swapon $FILE # Activate swap file. | |
| echo "Swap file created and activated." | |
| exit 0 | |
| } | |
| (( 0 )) && { # play with od and dd. (Thanks to Jerry Peek, Linux Mag., Oct 2004) | |
| echo "Sending 137 bytes of random to a file" | |
| #dd if=/dev/urandom of=/home/ja/temp/myrand bs=1 count=137 | |
| echo "looking at the file with od" | |
| od -b /home/ja/temp/myrand | |
| echo "Note that some of these bytes are legal characters" | |
| } | |
| (( 0 )) && { # Invoking bc using command substitution in combination with a here document. | |
| var1=`bc <<- EOF | |
| 18.33 * 19.78 | |
| EOF` | |
| echo -e "\t$var1 " # 362.56 | |
| # $( ... ) notation also works. | |
| v1=23.53 | |
| v2=17.881 | |
| v3=83.501 | |
| v4=171.63 | |
| var2=$(bc <<- EOF | |
| scale = 4 | |
| a = ( $v1 + $v2 ) | |
| b = ( $v3 * $v4 ) | |
| a * b + 15.35 | |
| EOF) | |
| echo -e "\t$var2 " # 593487.8452 | |
| var3=$(bc -l <<- EOF # The "-l" option calls the 'bc' math library. | |
| scale = 9 | |
| s ( 1.7 ) # Returns the sine of 1.7 radians. | |
| EOF) | |
| echo -e "\t$var3 " # .991664810 | |
| } | |
| (( 0 )) && { # Calculate hypotenuse of a right triangle. 2. | |
| hyp= | |
| hypotenuse () | |
| { | |
| hyp=$(bc -l <<- EOF | |
| scale = 9 | |
| sqrt ( $1 * $1 + $2 * $2 ) | |
| EOF) # But, can't return floating point values from a Bash function. | |
| } | |
| hypotenuse 3.68 7.31 | |
| echo -e "\tHypotenuse = $hyp" # 8.184039344 | |
| } | |
| (( 0 )) && { # Calculate hypotenuse of a right triangle. 1. | |
| hypot() | |
| { | |
| local hypot | |
| hypot=$(bc -l <<- EOF | |
| scale = 9 | |
| sqrt ( $1 * $1 + $2 * $2 ) | |
| EOF) | |
| echo $hypot | |
| # echo the result. acts as "returning" a value. | |
| } | |
| echo -e "\tHypot = $(hypot 3.68 7.31)" # 8.184039344 | |
| echo -e "\tHypot = $(hypot 5 12)" # 13.000000000 | |
| echo -e "\tHypot = $(hypot 12 12)" # 16.970562748 | |
| } | |
| (( 0 )) && { # Calculate hypotenuse of a right triangle. 0. | |
| hypot () | |
| { | |
| echo $(bc -l <<- EOF | |
| scale = 9 | |
| sqrt ( $1 * $1 + $2 * $2 ) | |
| EOF) | |
| } | |
| echo -e "\tHypot = $(hypot 3.68 7.31)" # 8.184039344 | |
| echo -e "\tHypot = $(hypot 5 12)" # 13.000000000 | |
| echo -e "\tHypot = $(hypot 12 12)" # 16.970562748 | |
| } | |
| (( 0 )) && { # bc - An arbitrary precision calculator language | |
| # length is number of digits. scale is number of decimal digits. | |
| # thanks: december 2006 www.linuxjournal.com, Dave Taylor. | |
| echo "scale=2; 3000 / 3001" |bc # prints: .99 | |
| echo "scale=6; 3000 / 3001" |bc # prints: .999666 | |
| } | |
| (( 0 )) && { # Create an image of a data CD using dd, where CD drive is /dev/hdc | |
| # thanks to www.linux-magazine.com, june 2005 issue. | |
| dd if=/dev/hdc of=cd.iso | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment