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