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