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