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