1 #!/bin/bash
  2 #
  3 # /home/lantw44/.bash_include
  4 #
  5 # -- UTF-8 --
  6 #
  7 
  8 #### if tty -s; then interactive_shell=1; fi
  9 if [[ "$-" == *i* ]] ; then interactive_shell=1; fi
 10 
 11 [ "$interactive_shell" ] && echo "Running .bash_include"
 12 [ "$interactive_shell" ] && default_tty_setting="`stty -g`"
 13 
 14 # Internal Variables
 15 
 16 colorprompting='\[\e[1;31m\]\!\[\e[m\] [\[\e[1;33m\]\u\[\e[m\]@\[\e[1;32m\]\h\[\e[m\] \[\e[1;36m\]\w\[\e[m\]]\$ '
 17 nocolorprompting='\! [\u@\h \w]\$ '
 18 
 19 if [ "$SSH_CONNECTION" ]
 20 then
 21     colorprompting="\[\e[1;44m\]*\[\e[m\]$colorprompting"
 22     nocolorprompting="*$nocolorprompting"
 23 fi
 24 
 25 historycountfile="$HOME/.bash_history.count"
 26 historybackupfile="$HOME/.bash_history.bak"
 27 bgrunfiledir="$HOME/tmp/bgrun-`whoami`"
 28 trashdir="$HOME/trash"
 29 
 30 HISTSIZE=1000000
 31 HISTFILESIZE=1000000
 32 HISTCONTROL=ignoredups:ignorespace
 33 
 34 REALPATH_PROGRAM="realpath"
 35 
 36 CFLAGS="-Wall -pipe -g"
 37 
 38 
 39 # Environment Variables
 40 
 41 export EDITOR=vim
 42 export FCEDIT=vim
 43 export PAGER=less
 44 
 45 
 46 
 47 
 48 # Aliases
 49 
 50 alias startcolor='PS1=$colorprompting'
 51 alias stopcolor='PS1=$nocolorprompting'
 52 
 53 alias ll='ls -l'
 54 alias grep='grep --color=always'
 55 alias rm='rm -i'
 56 alias cp='cp -pi'
 57 alias mv='mv -i'
 58 alias jobs='jobs -l'
 59 alias less='less -RS'
 60 
 61 alias cccc='LANG=C;LANGUAGE=C;LC_ALL=C'
 62 alias enus='LANG=en_US.UTF-8;LANGUAGE=en_US:en;LC_ALL=en_US.UTF-8'
 63 alias big5='LANG=zh_TW.Big5;LANGUAGE=zh_TW:zh;LC_ALL=zh_TW.Big5'
 64 alias zhtw='LANG=zh_TW.UTF-8;LANGUAGE=zh_TW:zh;LC_ALL=zh_TW.UTF-8'
 65 
 66 alias savetty='default_tty_setting=`stty -g`'
 67 alias resetty='stty $default_tty_setting'
 68 
 69 
 70 
 71 
 72 # Functions
 73 
 74 function compile_all ()
 75 {
 76     local noask=0
 77     [ "$1" = '' ] && echo "Which file(s) do you want to compile? " && return 1
 78     [ "$1" = "-n" ] && noask=1
 79     if [ "$noask" = "0" ]; then
 80         read -e -p "CFLAGS: " -i "$CFLAGS" NEWCFLAGS
 81         read -e -p "LDFLAGS: " -i "$LDFLAGS" NEWLDFLAGS
 82         [ "$NEWCFLAGS" '!=' '' ] && CFLAGS=$NEWCFLAGS
 83         [ "$NEWLDFLAGS" '!=' '' ] && LDFLAGS=$NEWLDFLAGS
 84     else
 85         shift
 86     fi
 87     while [ "$1" '!=' '' ]
 88     do
 89         local TARGETFILE="`echo "$1" | cut -d . -f 1`"
 90         local SUFFIX="`echo "$1" | cut -d . -f 2`"
 91         if [ -f "$1" ]; then
 92             true
 93         else
 94             printf\
 95             "\e[1;33mWarning\e[0m: $1 Non-existent file or not a regular file\n"
 96             shift ; continue
 97         fi
 98         [ "$TARGETFILE" = "$1" ] && shift && continue
 99         if [ "$SUFFIX" = "c" ]; then
100             echo "[CC] $1 -> $TARGETFILE"
101             gcc $CFLAGS "$1" $LDFLAGS -o "$TARGETFILE"
102         elif [ "$SUFFIX" = "cpp" ]; then
103             echo "[CXX] $1 -> $TARGETFILE"
104             g++ $CFLAGS "$1" $LDFLAGS -o "$TARGETFILE"
105         else
106             printf "$1: Unknown suffix (\e[1;33mskipped\e[0m)\n"
107         fi
108         [ "$?" '!=' "0" ] && printf\
109             '\e[1;31mError\e[0m while compiling file\n'
110         shift
111     done
112     return 0
113 }
114 
115 
116 function convert_to_html ()
117 {
118     while [ "$1" '!=' '' ]
119     do
120         for i in "$1"
121         do
122             vim $i -c 'set background=dark' \
123                 -c 'highlight PreProc ctermfg=darkcyan' \
124                 -c "$BEFORE_CONVERT_TO_HTML" \
125                 -c "$BEFORE_CONVERT_TO_HTML1" \
126                 -c "$BEFORE_CONVERT_TO_HTML2" \
127                 -c TOhtml \
128                 -c :w \
129                 -c :qa
130         done
131         shift
132     done
133 }
134 
135 function mkscreenacl ()
136 {
137     PERMIT_COMMAND="select windowlist other meta detach reset hardcopy info redisplay lastmsg next prev xon xoff windows suspend help colon copy paste writebuf readbuf displays stuff attach"
138     while [ "$1" '!=' '' ]
139     do
140         for i in $PERMIT_COMMAND
141         do
142             echo "aclchg $1 +x $i"
143         done
144         echo "aclchg $1 -rw \"#?\"" 
145         shift
146     done
147 }
148 
149 ########## Background ##########
150 
151 alias bgr=bgrun
152 alias bgv=bgview
153 alias bgl=bglist
154 alias bgc=bgcount
155 alias bgls=bglist
156 alias bgrm=bgclean
157 
158 function bgrun ()
159 {
160     [ "$#" = "0" ] && return 1
161     [ '!' -d "$bgrunfiledir" ] && mkdir -p "$bgrunfiledir"
162 #   [ '!' -d "$bgrunfiledir/pid" ] && mkdir -p "$bgrunfiledir/pid"
163     local current_time=`date "+%Y%m%d-%H%M%S"`
164     local cmdname=`echo "$1" | sed -e 's/-/_/g' -e 's/\\//_/g' -e 's/ /_/g'`
165     if [ "`echo "$cmdname" | cut -c 1`" == "_" ]
166     then
167         cmdname=`echo "$cmdname" | cut -c 2-`
168     fi
169     local filename="$bgrunfiledir/$current_time-$cmdname"
170     echo "Writing to $filename"
171     {
172         echo -n "$BASHPID " > "$filename"
173         echo "$@" >> "$filename"
174         exec "$@" &>> "$filename"
175     } &
176 }
177 
178 function bglist ()
179 {
180     local viewtime=0
181     [ "$1" = "--full" ] && viewtime=1
182     {
183         for i in `find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | sort`
184         do
185             [ "$viewtime" = "1" ] && echo "$i"
186             head -n 1 "$i" | {
187                 local procpid
188                 local cmdline
189                 read -d ' ' procpid
190                 read cmdline
191                 printf "(%5d) %s\n" "$procpid" "$cmdline"
192             }
193         done
194     } | {
195         if [ "$viewtime" = "1" ]
196         then
197             echo " INDEX         TIME          PID   COMMAND"
198             local readstat=0
199             local -i i=1
200             while true
201             do
202                 local dateandtime_long
203                 local cmdline
204                 read dateandtime_long
205                 read cmdline
206                 [ "$?" '!=' "0" ] && break
207                 local dateandtime=`basename "$dateandtime_long"`
208     ####        local part_year=`echo $dateandtime | cut -c 1-4`
209     ####        local part_month=`echo $dateandtime | cut -c 5-6`
210     ####        local part_date=`echo $dateandtime | cut -c 7-8`
211     ####        local part_hour=`echo $dateandtime | cut -c 10-11`
212     ####        local part_minute=`echo $dateandtime | cut -c 12-13`
213     ####        local part_second=`echo $dateandtime | cut -c 14-15`
214                 echo "$dateandtime" | {
215                     read -n 4 part_year
216                     read -n 2 part_month
217                     read -n 2 part_date
218                     read -n 1 drop_this_char; unset drop_this_char
219                     read -n 2 part_hour
220                     read -n 2 part_minute
221                     read -n 2 part_second
222                     printf '%6d' "$i"
223                     echo " $part_year-$part_month-$part_date $part_hour:$part_minute:$part_second $cmdline"
224                 }
225                 i=$i+1
226             done
227         else
228             echo " INDEX    PID   COMMAND"
229             cat -n
230         fi
231     } | $PAGER
232 }
233 
234 function bgview ()
235 {
236     local -i yourchoice
237     if [ "$1" = "" ]
238     then
239         yourchoice=`bgcount`
240     else
241         if [ "$1" -le "0" ]
242         then
243             yourchoice=$((`bgcount`+$1))
244         else
245             yourchoice=$1
246         fi
247     fi
248     echo "Your choice is $yourchoice."
249     local realfilename=`find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | sort | sed -n ${yourchoice}p`
250     head -n 1 "$realfilename" | {
251         read -d ' ' procpid
252         read cmdline
253         echo "PID: $procpid"
254         echo "Command Line: $cmdline"
255     }
256     read -e -p "View '$realfilename' ? " confirm
257     if [ "$confirm" = "n" ] || [ "$confirm" = "N" ]
258     then
259         return 1
260     fi
261     {
262         printf "===> Process Information: "
263         cat "$realfilename"
264     } | $PAGER
265 }
266 
267 function bgcount ()
268 {
269     find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | cut -d - -f 2,3 | wc | awk '{print $2}'
270 }
271 
272 function bgclean ()
273 {
274     if [ "$1" = "all" ]
275     then
276         echo "Removing the directory $bgrunfiledir"
277         rm -rf "$bgrunfiledir" &
278         return 0
279     else
280         split_arguments "$@"
281         local -i i=0
282         while [ "${arglist[$i]}" ]
283         do
284             arglist[$i]="-e ${arglist[$i]}p"
285             i=$i+1
286         done
287         local oneline
288         find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | sort | sed -n ${arglist[*]} | {
289             while read oneline
290             do
291                 echo "Removing $oneline"
292                 rm -f "$oneline"
293             done
294         }
295     fi
296     unset arglist
297     unset prefixlist
298 }
299 
300 function bgdu () 
301 {
302     du -a "$bgrunfiledir"
303 }
304 
305 ########## Background End ##########
306 
307 function check_dmesg ()
308 {
309     [ "$#" = "0" ] && return 1
310 
311     while true
312     do
313         PREVIOS_DMESG_BUF="$DMESG_BUF"
314         DMESG_BUF="`dmesg`"
315         [ "$PREVIOS_DMESG_BUF" '!=' "$DMESG_BUF" ] && [ "$FIRST_RUN" = "0" ] && echo '===> You should check the system message buffer <==='
316         sleep $1
317         [ "$?" '!=' "0" ] && return 1
318         FIRST_RUN=0
319     done
320 }
321 
322 function prehistory_backup ()
323 {
324     echo "Checking your current history file"
325     local currentcount=`wc "$HISTFILE" | awk '{print $1}'`
326     [ '!' -f "$historycountfile" ] && touch "$historycountfile"
327     local -i previoushistorycount
328     previoushistorycount=`cat "$historycountfile"`
329     if [ "$currentcount" -lt "$previoushistorycount" ]
330     then
331         printf "\e[1;31mWarning\e[m: Your $HISTFILE may be TRUNCATED OR OVERWRITTEN BY OTHER PROGRAMS!\n"
332         printf "Note: \e[1;33m$currentcount\e[m < $previoushistorycount\n"
333         echo "Your $historycountfile and $historybackupfile will not be overwritten until this problem is fixed."
334         echo " 1. Check your $HISTFILE."
335         echo " 2. Edit your $HISTFILE manually if some unexpected changes are found." 
336         echo "    (You may need $historybackupfile to do it) "
337         echo " 3. Remove the file $historycountfile."
338         echo " 4. Run the command \`prehistory_backup' again."
339         return 3
340     fi
341     echo -n "Backing up your current history file ($previoushistorycount -> $currentcount, "
342     if [ "$previoushistorycount" = "$currentcount" ]
343     then
344         echo "no modification)"
345     else
346         echo "+$(($currentcount-$previoushistorycount)))"
347     fi
348     echo "$currentcount" > "$historycountfile"
349     \cp -f "$HISTFILE" "$historybackupfile"
350 }
351 
352 ########## Trash Manager ##########
353 
354 alias trash_put=trash_mv
355 alias trash_add=trash_mv
356 alias trash_list=trash_ls
357 alias trash_ct=trash_count
358 alias trash_restore=trash_recover
359 alias trash_rc=trash_recover
360 alias trash_drop=trash_rm
361 alias trash_clean=trash_rm
362 
363 function trash_mv ()
364 {
365     [ "$#" = "0" ] && return 1
366     [ '!' -d "$trashdir" ] && mkdir -p "$trashdir"
367     local original_path
368     local current_time
369     local -i i=0
370     split_arguments "$@"
371     while [ "${arglist[$i]}" ]
372     do
373         original_path="`$REALPATH_PROGRAM "${arglist[$i]}"`"
374         current_time=`date "+%Y%m%d-%H%M%S"`
375         better_time=`date "+%Y-%m-%d %H:%M:%S"`
376         dirname="`basename "${arglist[$i]}" | sed -e 's/-/_/g' -e 's/ /_/g'`"
377         fulldirname="$trashdir/$current_time-$dirname"
378         mkdir -p "$fulldirname"
379         echo "Move: ${arglist[$i]} -> $fulldirname"
380         "${prefixlist[@]}" mv "${arglist[$i]}" "$fulldirname"
381         if [ "$?" = "0" ]
382         then
383             echo "$better_time" > "$fulldirname/information.date"
384             echo "$original_path" > "$fulldirname/information.path"
385         else
386             rmdir "$fulldirname"
387         fi
388         i=$i+1
389         shift
390     done
391     unset arglist
392     unset prefixlist
393 }
394 
395 function trash_rm ()
396 {
397     split_arguments "$@"
398     local -i i=0
399     while [ "${arglist[$i]}" ]
400     do
401         arglist[$i]="-e ${arglist[$i]}p"
402         i=$i+1
403     done
404     trash_dirname=`find "$trashdir" -mindepth 1 -maxdepth 1 | sort | sed -n ${arglist[*]} `
405     echo 'Type rm -rf $trash_dirname to remove them.'
406     unset arglist
407     unset prefixlist
408 }
409 
410 function trash_ls ()
411 {
412     local -i i=1
413     local oneline
414     find "$trashdir" -mindepth 1 -maxdepth 1 | sort | {
415         while read oneline
416         do
417             printf "%6d %s %s\n" "$i" \
418                 "`cat "$oneline/information.date"`" \
419                 "`cat "$oneline/information.path"`"
420             i=$i+1
421         done
422     } | $PAGER
423 }
424 
425 function trash_pushd ()
426 {
427     [ -z "$1" ] && return 1
428     pushd `find "$trashdir" -mindepth 1 -maxdepth 1 | sort | sed -n $1p`
429 }
430 
431 function trash_cd ()
432 {
433     [ -z "$1" ] && return 1
434     cd `find "$trashdir" -mindepth 1 -maxdepth 1 | sort | sed -n $1p`
435 }
436 
437 function trash_recover ()
438 {
439     [ -z "$1" ] && return 1
440     split_arguments "$@"
441     local -i i=0
442     while [ "${arglist[$i]}" ]
443     do
444         arglist[$i]="-e ${arglist[$i]}p"
445         i=$i+1
446     done
447     find "$trashdir" -mindepth 1 -maxdepth 1 | sort | sed -n ${arglist[*]} | {
448         while read oneline
449         do
450             local fromfile="$oneline/`basename "$(cat "$oneline/information.path")"`"
451             local tofile="`dirname "$(cat "$oneline/information.path")"`"
452             if [ -e "`cat "$oneline/information.path"`" ]
453             then
454                 echo "Destination file exists."
455                 continue
456             fi
457             echo "Move: $fromfile -> $tofile"
458             "${prefixlist[@]}" mv -f "$fromfile" "$tofile"
459             if [ "$?" = "0" ]
460             then
461                 echo "Remove: $oneline"
462                 \rm -rf "$oneline"
463             fi
464         done
465     }
466     unset arglist
467     unset prefixlist
468 }
469 
470 function trash_count () 
471 {
472     find "$trashdir" -mindepth 1 -maxdepth 1 | wc | awk '{print $2}'
473 }
474 
475 function trash_du ()
476 {
477     split_arguments "$@"
478     local oneline
479     find "$trashdir" -maxdepth 1 -mindepth 1 | sort | {
480         while read oneline
481         do
482             echo "'$oneline'"
483         done
484     } | xargs -n 10 "${prefixlist[@]}" du -s
485     unset arglist
486     unset prefixlist
487 }
488 
489 ########## Trash Manager End ##########
490 
491 function split_arguments ()
492 {
493     local argcount=$#
494     local -i i=0
495     local prefix_start=0
496     while [ "$1" ]
497     do
498         if [ "$prefix_start" == "0" ]
499         then
500             if [ "$1" = "--" ]
501             then
502                 prefix_start=1
503                 i=0
504                 shift
505                 continue
506             else
507                 arglist[$i]="$1"
508             fi
509         else
510             prefixlist[$i]="$1"
511         fi
512         i=$i+1
513         shift
514     done
515 }
516 
517 function check_important_files ()
518 {
519     IMPORTANT_FILES="$HOME/.screenrc $HOME/.vimrc"
520     for i in $IMPORTANT_FILES
521     do
522         [ '!' -f "$i" ] && printf "\e[1;31mWarning\e[m: \e[1;33m$i\e[m does not exist.\n"
523     done
524 }
525 
526 ########## PATH Editor ##########
527 
528 function split_path_core ()
529 {
530     echo "$current_path" | {
531         while read -d : oneline
532         do
533             [ '!' "$oneline" = '^' ] && echo "$oneline"
534         done
535         [ '!' "$oneline" = '^' ] && echo "$oneline"
536     }
537     unset oneline
538 }
539 
540 function split_path () 
541 {
542     coproc split_path_core
543     readarray -t -u ${COPROC[0]} patharr
544     wait $COPROC_PID
545 }
546 
547 function update_path ()
548 {
549     current_path=''
550     local -i i=0
551     local firsttime="yes"
552     while [ "${patharr[$i]}" ]
553     do
554         if [ '!' "${patharr[$i]}" = "^" ]
555         then
556             if [ "$firsttime" ]
557             then
558                 firsttime=''
559             else
560                 current_path+=':'
561             fi
562             current_path+="${patharr[$i]}"
563         fi
564         i=$i+1
565     done
566 }
567 
568 function path_editor ()
569 {
570     path_editor_core
571 }
572 
573 function ldpath_editor ()
574 {
575     path_editor_core ld
576 }
577 
578 function path_editor_core ()
579 {
580     if [ "$1" = "ld" ]
581     then
582         export current_path="$LD_LIBRARY_PATH"
583     else
584         export current_path="$PATH"
585     fi
586     local should_continue="yes"
587     local command
588     local command_sub
589     local command_sub2
590     local -i i
591     while [ "$should_continue" ]
592     do
593         split_path
594         i=0
595         echo "========================================"
596         while [ "${patharr[$i]}" ]
597         do
598             echo "$i: ${patharr[$i]}"
599             i=$i+1
600         done
601         [ "$i" = '0' ] && echo "(Empty or not declared)"
602         echo "========================================"
603         read -e -p "[A]ppend/(D)elete/(E)dit/(M)ove/(R)eset/(Q)uit ? " command
604         case "$command" in
605             ''|A|a)
606                 read -e -p "Type a new entry: " patharr[$i]
607                 update_path
608                 ;;
609             D|d)
610                 read -e -p "Index: " command_sub
611                 patharr[$command_sub]='^'
612                 update_path
613                 ;;
614             E|e)
615                 read -e -p "Index: " command_sub
616                 read -e -p "Modify this entry: " -i "${patharr[$command_sub]}" patharr[$command_sub]
617                 update_path
618                 ;;
619             M|m)
620                 read -e -p "From: " command_sub
621                 read -e -p "To: " command_sub2
622                 swaptmp="${patharr[$command_sub]}"
623                 patharr[$command_sub]="${patharr[$command_sub2]}"
624                 patharr[$command_sub2]="$swaptmp"
625                 unset swaptmp
626                 update_path
627                 ;;
628             R|r)
629                 if [ "$1" = "ld" ]
630                 then
631                     current_path="$LD_LIBRARY_PATH"
632                 else
633                     current_path="$PATH"
634                 fi
635                 ;;
636             Q|q)
637                 if [ "$1" = "ld" ]
638                 then
639                     export LD_LIBRARY_PATH="$current_path"
640                     echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
641                     history -s "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
642                 else
643                     export PATH="$current_path"
644                     echo "PATH=$PATH"
645                     history -s "PATH=$PATH"
646                 fi
647                 should_continue=''
648                 ;;
649             *)
650                 printf " \e[33m*** Unknown command ***\e[m \n"
651                 ;;
652         esac
653     done
654     unset patharr
655     unset current_path
656 }
657 
658 ########## PATH Editor End ##########
659 
660 function backup_file ()
661 {
662     split_arguments "$@"
663     local current_time=`date +%Y%m%d`
664     local rootfilename
665     local -i i=0
666     local -i j
667     while [ "${arglist[$i]}" ]
668     do
669         if [ '!' -f "${arglist[$i]}" ]
670         then
671             printf "\e[1;31mError\e[m: ${arglist[$i]} does not exist or it is not a regular file.\n"
672             i=$i+1
673             continue
674         fi
675         rootfilename="${arglist[$i]}.$current_time"
676         if [ -e "$rootfilename" ]
677         then
678             j=0
679             while [ "$j" -lt "10" ]
680             do
681                 if [ -e "$rootfilename.$j" ]
682                 then
683                     j=$j+1
684                     continue
685                 else
686                     "${prefixlist[@]}" \cp -p "${arglist[$i]}" "$rootfilename.$j"
687                     history -s "${prefixlist[@]}" \cp -p "${arglist[$i]}" "$rootfilename.$j"
688                     "${prefixlist[@]}" touch -r "${arglist[$i]}" "$rootfilename.$j"
689                     history -s "${prefixlist[@]}" touch -r "${arglist[$i]}" "$rootfilename.$j"
690                     break
691                 fi
692             done
693             if [ '!' "$j" -lt "10" ]
694             then
695                 printf "\e[1;31mError\e[m: Can not create a backup file for ${arglist[$i]}.\n"
696                 printf "\e[1;33mPlease delete some backup file because I only use 0 - 9.\e[m\n"
697             fi
698         else
699             "${prefixlist[@]}" \cp -p "${arglist[$i]}" "$rootfilename"
700             history -s "${prefixlist[@]}" \cp -p "${arglist[$i]}" "$rootfilename"
701             "${prefixlist[@]}" touch -r "${arglist[$i]}" "$rootfilename"
702             history -s "${prefixlist[@]}" touch -r "${arglist[$i]}" "$rootfilename"
703         fi
704         i=$i+1
705     done
706     unset arglist
707     unset prefixlist
708 }
709 
710 function keep_sudo_credential ()
711 {
712     if [ "$1" ]
713     then
714         update_sudo_interval="$1"
715     else
716         update_sudo_interval="280"
717     fi
718     while true
719     do
720         sudo -v
721         sleep "$update_sudo_interval"
722     done
723 }
724 
725 function get_memory_info ()
726 {
727     if [ "`uname`" = "Linux" ]
728     then
729         local meminfoline="`free -m | \grep -i mem`"
730         local swapinfoline="`free -m | \grep -i swap`"
731         local memtotal="`echo "$meminfoline" | awk '{print $2}'`"
732         local memused="`echo "$meminfoline" | awk '{print $3}'`"
733         local membuf="`echo "$meminfoline" | awk '{print $6}'`"
734         local memcache="`echo "$meminfoline" | awk '{print $7}'`"
735         local memprog=$(($memused-$membuf-$memcache))
736         local swaptotal="`echo "$swapinfoline" | awk '{print $2}'`"
737         local swapused="`echo "$swapinfoline" | awk '{print $3}'`"
738         echo "Memory: $memused / $memtotal MB (`printf %2d $(($memused*100/$memtotal))`%)"
739         echo "Detail:"
740         echo "    Used:    `printf %5d $memprog` MB (`printf %2d $(($memprog*100/$memtotal))`%)"
741         echo "    Buffers: `printf %5d $membuf` MB (`printf %2d $(($membuf*100/$memtotal))`%)"
742         echo "    Cached:  `printf %5d $memcache` MB (`printf %2d $(($memcache*100/$memtotal))`%)"
743         if [ "$swaptotal" = "0" ]
744         then
745             echo "Swap: not available"
746         else
747             echo "Swap: $swapused / $swaptotal MB (`printf %2d $(($swapused*100/$swaptotal))`%)"
748         fi
749     else
750         echo "Current operating system is not Linux."
751     fi
752 }
753 
754 function set_console_title ()
755 {
756     case "$TERM" in
757         screen)
758             printf "\033]0;"
759             echo -n "$*"
760             printf "\033\\"
761             ;;
762         xterm*)
763             printf "\033]0;"
764             echo -n "$*"
765             printf "\007"
766             ;;
767         *)
768             echo "Your terminal may not have the hardstatus line."
769             echo "Note: TERM=$TERM"
770             ;;
771     esac
772 }
773 
774 function mvfile ()
775 {
776     split_arguments "$@"
777     local -i i=0
778     while [ "${arglist[$i]}" ] 
779     do
780         if [ '!' -e "${arglist[$i]}" ]
781         then
782             printf "\e[33mWarning\e[m: ${arglist[$i]} does not exist.\n"
783             i=$i+1
784             continue
785         fi
786         echo "Old name: ${arglist[$i]}"
787         read -p "New name: " -e -i "${arglist[$i]}" new_file_name
788         if [ "$new_file_name" ] && [ "${arglist[$i]}" != "$new_file_name" ]
789         then
790             "${prefixlist[@]}" mv -iv "${arglist[$i]}" "$new_file_name"
791             history -s "${prefixlist[@]}" mv -iv "${arglist[$i]}" "$new_file_name"
792         fi
793         i=$i+1
794     done
795     unset arglist
796     unset prefixlist
797     unset new_file_name
798 }
799 
800 ########## Help ##########
801 
802 alias helpf='help_function'
803 alias helpm='help_myself'
804 
805 function print_iconv ()
806 {
807     [ "$1" = "$2" ] && cat && return 0
808     iconv -f "$1" -t "$2"
809 }
810 
811 function help_myself () 
812 {
813     echo "argc = $#"
814     echo "argv[0] = $0"
815     i=1
816     while [ "$1" ]
817     do
818         echo "argv[$i] = $1"
819         i=$(($i+1))
820         shift
821     done
822 }
823 
824 function help_function ()
825 {
826     [ "$#" = "0" ] && {
827         cat << ENDHELPMSG
828  <<< Help >>>
829     help_myself [arguments ...]                            (helpm)
830     help_function [functions ...]                          (helpf)
831  <<< Group: Background >>>
832     bgrun command [arguments ...]                          (bgr)
833     bglist [--full]                                        (bgl, bgls)
834     bgview [number]                                        (bgv)
835     bgclean [all | numbers ...]                            (bgrm)
836     bgcount                                                (bgc)
837     bgdu
838  <<< Group: Trash >>>
839     trash_mv [filename ...] [-- sudo_prefix ...]      (trash_put, trash_add)
840     trash_ls                                          (trash_list)
841     trash_cd [number]
842     trash_pushd [number]
843     trash_recover [number] [-- sudo_prefix ...]       (trash_restore, trash_rc)
844     trash_rm numbers ...                              (trash_drop, trash_clean)
845     trash_count                                       (trash_ct)
846     trash_du [-- sudo_prefix ...]
847  <<< Group: PATH Editor >>>
848     path_editor
849     ldpath_editor
850  x  split_path
851  x  split_path_core
852  x  update_path 
853  x  path_editor_core
854  <<< Other >>>
855     backup_file filename ... [-- sudo_prefix ]
856     check_dmesg seconds
857     check_important_files
858     compile_all [-n] filename ...
859     convert_to_html filename ...
860     keep_sudo_credential [seconds]
861     mkscreenacl username ...
862     mvfile filename ... [-- sudo_prefix]
863     prehistory_backup
864     set_console_title
865  x  split_arguments [arguments ...]
866 ENDHELPMSG
867     } && return 0
868     local current_charset=`echo "$LC_ALL" | cut -d . -f 2`
869     local -i i
870     while [ "$1" ]
871     do
872         case "$1" in
873             help_myself|helpm)
874                 cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
875 help_myself
876     一個測試命令列的小函式
877 ENDHELPMSG
878                 ;;
879             help_function|helpf)
880                 cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
881 help_function
882     顯示 .bash_include 提供的額外函式清單
883     註:前方加上「x」符號者表示此為內部使用的函式,不宜直接使用
884 ENDHELPMSG
885                 ;;
886             bgrun|bgr)
887                 cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
888 bgrun command [arguments ...]
889     執行指令 command 並將輸出導入檔案
890     註:此函式會自動以目前時間和指令名稱為檔案命名
891 ENDHELPMSG
892                 ;;
893             bglist|bgl|bgls)
894                 cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
895 bglist [--full]
896     列出所有使用 bgrun 執行的指令
897     若加上 --full 選項,則可同時察看時間
898 ENDHELPMSG
899                 ;;
900             bgview|bgv)
901                 cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
902 bgview [number]
903     顯示以 bgrun 執行指令的輸出,若省略 number,表示是最近一次執行的指令
904     若 number >  0,
905         表示第 number 個指令 (此數值可由 bglist 函式取得)
906     若 number <= 0,
907         表示第「指令總數-number」個指令 (指令總數可由 bgcount 函式取得)
908 ENDHELPMSG
909                 ;;
910             bgclean|bgrm)
911                 cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
912 bgclean [all | numbers ...]
913     bgclean all 可清除所有指令的輸出檔
914     bgclean 3 5 7 10 表示清除第 3、5、7、10 個指令輸出檔 (編號可由 bglist 取得)
915 ENDHELPMSG
916                 ;;
917             bgcount|bgc)
918                 cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
919 bgcount
920     顯示指令輸出檔總數
921 ENDHELPMSG
922                 ;;
923             bgdu)
924                 cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
925 bgdu
926     顯示每個指令輸出檔的檔案大小 (單位:KB)
927 ENDHELPMSG
928                 ;;
929             *)
930                 echo "Help message for $1 is not found"
931                 ;;
932         esac
933         shift
934     done
935 }
936 
937 ########## Help End ##########
938 
939 # Doing something
940 
941 umask 0022
942 
943 if [ "$interactive_shell" ]
944 then
945     echo "Running interactive shell configuration"
946     check_important_files
947     startcolor
948     prehistory_backup
949     bind '"\e[A":history-search-backward'
950     bind '"\e[B":history-search-forward'
951     if [ -z "$PROMPT_COMMAND" ] && [ -e "$HOME/.bash_title" ]; then
952         case "$TERM" in
953             xterm*)
954                 PROMPT_COMMAND='printf "\033]0;%s@%s:%s (%s)\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" "`date "+%H:%M:%S"`"'
955                 ;;
956             screen)
957                 PROMPT_COMMAND='printf "\033]0;%s@%s:%s (%s)\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" "`date "+%H:%M:%S"`"'
958                 ;;
959         esac
960     fi
961 fi
962 
963 if [ "`uname`" = "Linux" ]
964 then
965     [ "$interactive_shell" ] && echo "Setting special things for Linux"
966     REALPATH_PROGRAM="readlink -f"
967     ulimit -c unlimited
968 fi
969 
970 [ "$interactive_shell" ] && echo "Setting shell options"
971 
972 shopt -s histappend
973 shopt -s checkwinsize
974 shopt -s checkjobs
975 shopt -s checkhash
976 shopt -s cmdhist
977 shopt -s mailwarn
978 
979 [ "$interactive_shell" ] && {
980     echo "Done"
981     if [ "$UID" = "0" ] || [ "$EUID" = "0" ]
982     then
983         printf "\nNote: You may be \e[1;32mprivileged\e[m now!\n\n"
984     fi
985 }
986