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