📄 contributed-scripts.html
字号:
9 10 11 MATRIX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 12 # ==> Password will consist of alphanumeric characters. 13 LENGTH="8" 14 # ==> May change 'LENGTH' for longer password. 15 16 17 while [ "${n:=1}" -le "$LENGTH" ] 18 # ==> Recall that := is "default substitution" operator. 19 # ==> So, if 'n' has not been initialized, set it to 1. 20 do 21 PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}" 22 # ==> Very clever, but tricky. 23 24 # ==> Starting from the innermost nesting... 25 # ==> ${#MATRIX} returns length of array MATRIX. 26 27 # ==> $RANDOM%${#MATRIX} returns random number between 1 28 # ==> and [length of MATRIX] - 1. 29 30 # ==> ${MATRIX:$(($RANDOM%${#MATRIX})):1} 31 # ==> returns expansion of MATRIX at random position, by length 1. 32 # ==> See {var:pos:len} parameter substitution in Chapter 9. 33 # ==> and the associated examples. 34 35 # ==> PASS=... simply pastes this result onto previous PASS (concatenation). 36 37 # ==> To visualize this more clearly, uncomment the following line 38 # echo "$PASS" 39 # ==> to see PASS being built up, 40 # ==> one character at a time, each iteration of the loop. 41 42 let n+=1 43 # ==> Increment 'n' for next pass. 44 done 45 46 echo "$PASS" # ==> Or, redirect to a file, as desired. 47 48 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>+</P><P><ANAME="ZFIFO"></A>James R. Van Zandt contributed this script which uses named pipes and, in his words, <SPANCLASS="QUOTE">"really exercises quoting and escaping."</SPAN></P><DIVCLASS="EXAMPLE"><HR><ANAME="FIFO"></A><P><B>Example A-15. <ICLASS="FIRSTTERM">fifo</I>: Making daily backups, using named pipes</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # ==> Script by James R. Van Zandt, and used here with his permission. 3 4 # ==> Comments added by author of this document. 5 6 7 HERE=`uname -n` # ==> hostname 8 THERE=bilbo 9 echo "starting remote backup to $THERE at `date +%r`" 10 # ==> `date +%r` returns time in 12-hour format, i.e. "08:08:34 PM". 11 12 # make sure /pipe really is a pipe and not a plain file 13 rm -rf /pipe 14 mkfifo /pipe # ==> Create a "named pipe", named "/pipe". 15 16 # ==> 'su xyz' runs commands as user "xyz". 17 # ==> 'ssh' invokes secure shell (remote login client). 18 su xyz -c "ssh $THERE \"cat > /home/xyz/backup/${HERE}-daily.tar.gz\" < /pipe"& 19 cd / 20 tar -czf - bin boot dev etc home info lib man root sbin share usr var > /pipe 21 # ==> Uses named pipe, /pipe, to communicate between processes: 22 # ==> 'tar/gzip' writes to /pipe and 'ssh' reads from /pipe. 23 24 # ==> The end result is this backs up the main directories, from / on down. 25 26 # ==> What are the advantages of a "named pipe" in this situation, 27 # ==>+ as opposed to an "anonymous pipe", with |? 28 # ==> Will an anonymous pipe even work here? 29 30 # ==> Is it necessary to delete the pipe before exiting the script? 31 # ==> How could that be done? 32 33 34 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>+</P><P><ANAME="PRIMES1"></A></P><P>St閜hane Chazelas used the following script to demonstrate generating prime numbers without arrays.</P><P><ANAME="PRIMES00"></A></P><DIVCLASS="EXAMPLE"><HR><ANAME="PRIMES"></A><P><B>Example A-16. Generating prime numbers using the modulo operator</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # primes.sh: Generate prime numbers, without using arrays. 3 # Script contributed by Stephane Chazelas. 4 5 # This does *not* use the classic "Sieve of Eratosthenes" algorithm, 6 #+ but instead the more intuitive method of testing each candidate number 7 #+ for factors (divisors), using the "%" modulo operator. 8 9 10 LIMIT=1000 # Primes, 2 ... 1000. 11 12 Primes() 13 { 14 (( n = $1 + 1 )) # Bump to next integer. 15 shift # Next parameter in list. 16 # echo "_n=$n i=$i_" 17 18 if (( n == LIMIT )) 19 then echo $* 20 return 21 fi 22 23 for i; do # "i" set to "@", previous values of $n. 24 # echo "-n=$n i=$i-" 25 (( i * i > n )) && break # Optimization. 26 (( n % i )) && continue # Sift out non-primes using modulo operator. 27 Primes $n $@ # Recursion inside loop. 28 return 29 done 30 31 Primes $n $@ $n # Recursion outside loop. 32 # Successively accumulate positional parameters. 33 # "$@" is the accumulating list of primes. 34 } 35 36 Primes 1 37 38 exit $? # Pipe output of the script to 'fmt' for prettier printing. 39 40 # Uncomment lines 16 and 24 to help figure out what is going on. 41 42 # Compare the speed of this algorithm for generating primes 43 #+ with the Sieve of Eratosthenes (ex68.sh). 44 45 46 # Exercise: Rewrite this script without recursion, for faster execution.</PRE></TD></TR></TABLE><HR></DIV><P>+</P><P>Rick Boivie's revision of Jordi Sanfeliu's <SPANCLASS="emphasis"><ICLASS="EMPHASIS">tree</I></SPAN> script.</P><DIVCLASS="EXAMPLE"><HR><ANAME="TREE"></A><P><B>Example A-17. <ICLASS="FIRSTTERM">tree</I>: Displaying a directory tree</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # tree.sh 3 4 # Written by Rick Boivie. 5 # Used with permission. 6 # This is a revised and simplified version of a script 7 #+ by Jordi Sanfeliu (and patched by Ian Kjos). 8 # This script replaces the earlier version used in 9 #+ previous releases of the Advanced Bash Scripting Guide. 10 11 # ==> Comments added by the author of this document. 12 13 14 search () { 15 for dir in `echo *` 16 # ==> `echo *` lists all the files in current working directory, 17 #+ ==> without line breaks. 18 # ==> Similar effect to for dir in * 19 # ==> but "dir in `echo *`" will not handle filenames with blanks. 20 do 21 if [ -d "$dir" ] ; then # ==> If it is a directory (-d)... 22 zz=0 # ==> Temp variable, keeping track of directory level. 23 while [ $zz != $1 ] # Keep track of inner nested loop. 24 do 25 echo -n "| " # ==> Display vertical connector symbol, 26 # ==> with 2 spaces & no line feed in order to indent. 27 zz=`expr $zz + 1` # ==> Increment zz. 28 done 29 30 if [ -L "$dir" ] ; then # ==> If directory is a symbolic link... 31 echo "+---$dir" `ls -l $dir | sed 's/^.*'$dir' //'` 32 # ==> Display horiz. connector and list directory name, but... 33 # ==> delete date/time part of long listing. 34 else 35 echo "+---$dir" # ==> Display horizontal connector symbol... 36 # ==> and print directory name. 37 numdirs=`expr $numdirs + 1` # ==> Increment directory count. 38 if cd "$dir" ; then # ==> If can move to subdirectory... 39 search `expr $1 + 1` # with recursion ;-) 40 # ==> Function calls itself. 41 cd .. 42 fi 43 fi 44 fi 45 done 46 } 47 48 if [ $# != 0 ] ; then 49 cd $1 # move to indicated directory. 50 #else # stay in current directory 51 fi 52 53 echo "Initial directory = `pwd`" 54 numdirs=0 55 56 search 0 57 echo "Total directories = $numdirs" 58 59 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>Patsie's version of a directory <ICLASS="FIRSTTERM">tree</I> script.</P><DIVCLASS="EXAMPLE"><HR><ANAME="TREE2"></A><P><B>Example A-18. <ICLASS="FIRSTTERM">tree2</I>: Alternate directory tree script</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # tree2.sh 3 4 # Lightly modified/reformatted by ABS Guide author. 5 # Included in ABS Guide with permission of script author (thanks!). 6 7 ## Recursive file/dirsize checking script, by Patsie 8 ## 9 ## This script builds a list of files/directories and their size (du -akx) 10 ## and processes this list to a human readable tree shape 11 ## The 'du -akx' is only as good as the permissions the owner has. 12 ## So preferably run as root* to get the best results, or use only on 13 ## directories for which you have read permissions. Anything you can't 14 ## read is not in the list. 15 16 #* ABS Guide author advises caution when running scripts as root! 17 18 19 ########## THIS IS CONFIGURABLE ########## 20 21 TOP=5 # Top 5 biggest (sub)directories. 22 MAXRECURS=5 # Max 5 subdirectories/recursions deep. 23 E_BL=80 # Blank line already returned. 24 E_DIR=81 # Directory not specified. 25 26 27 ########## DON'T CHANGE ANYTHING BELOW THIS LINE ########## 28 29 PID=$$ # Our own process ID. 30 SELF=`basename $0` # Our own program name. 31 TMP="/tmp/${SELF}.${PID}.tmp" # Temporary 'du' result. 32 33 # Convert number to dotted thousand. 34 function dot { echo " $*" | 35 sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' | 36 tail -c 12; } 37 38 # Usage: tree <recursion> <indent prefix> <min size> <directory> 39 function tree { 40 recurs="$1" # How deep nested are we? 41 prefix="$2" # What do we display before file/dirname? 42 minsize="$3" # What is the minumum file/dirsize? 43 dirname="$4" # Which directory are we checking? 44 45 # Get ($TOP) biggest subdirs/subfiles from TMP file. 46 LIST=`egrep "[[:space:]]${dirname}/[^/]*$" "$TMP" | 47 awk '{if($1>'$minsize') print;}' | sort -nr | head -$TOP` 48 [ -z "$LIST" ] && return # Empty list, then go back. 49 50 cnt=0 51 num=`echo "$LIST" | wc -l` # How many entries in the list. 52 53 ## Main loop 54 echo "$LIST" | while read size name; do 55 ((cnt+=1)) # Count entry number. 56 bname=`basename "$name"` # We only need a basename of the entry. 57 [ -d "$name" ] && bname="$bname/" 58 # If it's a directory, append a slash. 59 echo "`dot $size`$prefix +-$bname" 60 # Display the result. 61 # Call ourself recursively if it's a directory 62 #+ and we're not nested too deep ($MAXRECURS). 63 # The recursion goes up: $((recurs+1)) 64 # The prefix gets a space if it's the last entry, 65 #+ or a pipe if there are more entries. 66 # The minimum file/dirsize becomes 67 #+ a tenth of his parent: $((size/10)). 68 # Last argument is the full directory name to check. 69 if [ -d "$name" -a $recurs -lt $MAXRECURS ]; then 70 [ $cnt -lt $num ] \ 71 || (tree $((recurs+1)) "$prefix " $((size/10)) "$name") \ 72 && (tree $((recurs+1)) "$prefix |" $((size/10)) "$name") 73 fi 74 done 75 76 [ $? -eq 0 ] && echo " $prefix" 77 # Every time we jump back add a 'blank' line. 78 return $E_BL 79 # We return 80 to tell we added a blank line already. 80 } 81 82 ### ### 83 ### main program ### 84 ### ### 85 86 rootdir="$@" 87 [ -d "$rootdir" ] || 88 { echo "$SELF: Usage: $SELF <directory>" >&2; exit $E_DIR; } 89 # We should be called with a directory name. 90 91 echo "Building inventory list, please wait ..." 92 # Show "please wait" message. 93 du -akx "$rootdir" 1>"$TMP" 2>/dev/null 94 # Build a temporary list of all files/dirs and their size
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -