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