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