aboutsummaryrefslogblamecommitdiffstats
path: root/bash_include
blob: ae82ca788ac356cfbc967daf196ec1cea0cff5c9 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

           
                             
 

             



                                                                                                           
 
                                            
                                                   

                                                        
                                                           


                    

                                                                                                              
 





                                                             
















                                                     

                                          
 

                                            
                                       
                      
 

                       
                                  
                       
 

                           
                       

 
                       








                 




                                       
                                
                
                 



                     



                                                                  
 


                                             
                                               


           


                       
                     


                                                                                  

                                                               






                                                                

                                                              



                                    
                                                                                            

                                        

                                                             

                                                                  
                                                


                                                                  
                                                                            

                                            
                                                                   





                     








                                                                         

                                                               
















                                                                                                                                                                                                  
                                                



                     
                          
 

                                                     



                                         

                        

 

                                




                 
                  
 

                 
                                  
                                                                            
                                                  
                                                                                



                                                     
                                                             
                                   




                                                 



                  

                                         


                                                                              







                                                                         
                    
             
                                        
                    
                                                                         









                                                                                
















                                                                                                                               


                                      
                                                      


                              

 
                  
 
                           
                        
            







                                                    
          
                                          
                                                                                                        





                                             
                                                    
                                                       


                        
         
                                                   

                                   

 




                                                                                              

                   























                                                                                              

 

                 










                                                                              
                                                                




                                                             

 
                                    
 







                                              
                                                                                                                                                   





                                             





























                                                                                                                                             

                             
                                                 
                                                       
                                                                   
                                     


                                                          
                                                                                                                 






                                                                                                                         
                        
          
                                                                                                





                                                                 
                                                  




                                               
                        






                                 
 

                    
                                  
                                                                    





                                  
                                                                    






                                                                                     






                                                                               




                        



                    







                                                                                               
                                                         

                        



                    









                                                                     
                  





                                                                            

 
                    
 

                                                                         

 

                         




























                                                                                                 



                        
                                                                        

 

                    

                            
                    


                                                           
                                                    
                                                                                    

                                                                   
                    
                  

                        

 
                                       
 

























                                                

                                 
                                                      





                                                                                                 

                                 











                                                                   

                       


                                            








                                  
                                                 












                                                      
                           
 
                            

 
                             
 
                               

 
                                
 





                                                      








                                    
                                                               




                                                 
                                                                
                                                               
                                                                                      
                                  
                               
                                                                           



                                                                
                                                         
















                                                                                                                     





                                                                       
                                  




                                                                               
                                                                                     


                                                                   
                                                               
                                  


                                                  
                                                                              



                                  
                          

 

                                     







































































































































































                                                                                                                     












                                                                 


































                                                                                              

























                                                                                                                
                                                                                                     
                                                                                                                
                                                                                                       
                                                                                                                  








                                                                                                               
                                                                                  
                                                                                             
                                                                                    
                                                                                               












                                         
                                          







                                             

                           

















































                                                                                                                                                            

 





















                                                                              

                                             


                                   
          
                                                                      
                    
                                                                                                         
                              

                                


                                                                                   
                    

                                                                                              
                  
                      
            

                        


                           














                                                                     























                                          












                                    






                                                                  

                 







                                                                      
                                                                            
                                                                  


                                                                               
                                                                               

                                                                

                               
                 

                
              
                                                 
                       
                               
                         
                                  
                                
                                               
                   
                                  
                             
                                                  
                     
                     
                        
                             

                                                   
                                   

                                                                         








































































                                                                                                   
                 
 

          
                            
    



                                                      

                                            
                                                                       








                                                                                                                                                       
  
 



                                                                           
                           
  

                                                        
 
                   





                     






                                                                           
 
#!/bin/bash
#
# /home/lantw44/.bash_include
#
# -- UTF-8 --
#
# 設定用外部檔案:
#     (1) 若 .bash_title 存在且未設定自動修改視窗標題,則依照本檔案內定規則修改
#     (2) 若 .bash_addps 存在,則第一行的的內容會加到 colorprompting 變數,第二
#         行的內容會加到 nocolorprompting 變數

#### if tty -s; then interactive_shell=1; fi
if [[ "$-" == *i* ]] ; then interactive_shell=1; fi

[ "$interactive_shell" ] && echo "Running .bash_include"
[ "$interactive_shell" ] && default_tty_setting="`stty -g`"

# Internal Variables

colorprompting='\[\e[1;31m\]\!\[\e[m\] [\[\e[1;33m\]\u\[\e[m\]@\[\e[1;32m\]\h\[\e[m\] \[\e[1;36m\]\w\[\e[m\]]'
nocolorprompting='\! [\u@\h \w]'

if [ "$SSH_CONNECTION" ]
then 
    colorprompting="\[\e[1;44m\]*\[\e[m\]$colorprompting"
    nocolorprompting="*$nocolorprompting"
fi

if [ -f "$HOME/.bash_addps" ]
then
    exec 3< "$HOME/.bash_addps"
    read -u 3 -r oneline
    colorprompting="$oneline $colorprompting"
    read -u 3 -r oneline
    nocolorprompting="$oneline $nocolorprompting"
    exec 3<&-
    unset oneline
fi

if [ "$WINDOW" ]
then
    colorprompting="$colorprompting<$WINDOW>"
    nocolorprompting="$nocolorprompting<$WINDOW>"
fi

colorprompting="${colorprompting}\\$ "
nocolorprompting="${nocolorprompting}\\$ "

historycountfile="$HOME/.bash_history.count"
historybackupfile="$HOME/.bash_history.bak"
bgrunfiledir="$HOME/tmp/bgrun-`whoami`"
trashdir="$HOME/trash"

HISTSIZE=2147483647
HISTFILESIZE=2147483647
HISTCONTROL=ignoredups:ignorespace
HISTTIMEFORMAT="%F %T "

REALPATH_PROGRAM="realpath"

CFLAGS="-Wall -pipe -g"


# Environment Variables

export EDITOR=vim
export FCEDIT=vim
export PAGER=less




# Aliases

alias startcolor='PS1=$colorprompting'
alias stopcolor='PS1=$nocolorprompting'

alias ll='ls -l'
alias grep='grep --color=always'
alias rm='rm -i'
alias cp='cp -pi'
alias mv='mv -i'
alias jobs='jobs -l'
alias less='less -RS'

alias cccc='LANG=C;LANGUAGE=C;LC_ALL=C'
alias enus='LANG=en_US.UTF-8;LANGUAGE=en_US:en;LC_ALL=en_US.UTF-8'
alias big5='LANG=zh_TW.Big5;LANGUAGE=zh_TW:zh;LC_ALL=zh_TW.Big5'
alias zhtw='LANG=zh_TW.UTF-8;LANGUAGE=zh_TW:zh;LC_ALL=zh_TW.UTF-8'

alias savetty='default_tty_setting=`stty -g`'
alias resetty='stty $default_tty_setting'

alias vimhtml='vim -c "set ts=2" -c "set sw=2"'


# Functions

function compile_all ()
{
    local noask=0
    [ "$1" = '' ] && echo "Which file(s) do you want to compile? " && return 1
    [ "$1" = "-n" ] && noask=1
    if [ "$noask" = "0" ]; then
        read -e -p "CFLAGS: " -i "$CFLAGS" NEWCFLAGS
        read -e -p "LDFLAGS: " -i "$LDFLAGS" NEWLDFLAGS
        [ "$NEWCFLAGS" '!=' '' ] && CFLAGS=$NEWCFLAGS
        [ "$NEWLDFLAGS" '!=' '' ] && LDFLAGS=$NEWLDFLAGS
    else
        shift
    fi
    while [ "$1" '!=' '' ]
    do
        local TARGETFILE="`echo "$1" | cut -d . -f 1`"
        local SUFFIX="`echo "$1" | cut -d . -f 2`"
        if [ -f "$1" ]; then
            true
        else
            printf\
            "\e[1;33mWarning\e[0m: $1 Non-existent file or not a regular file\n"
            shift ; continue
        fi
        [ "$TARGETFILE" = "$1" ] && shift && continue
        if [ "$SUFFIX" = "c" ]; then
            echo "[CC] $1 -> $TARGETFILE"
            gcc $CFLAGS "$1" $LDFLAGS -o "$TARGETFILE"
        elif [ "$SUFFIX" = "cpp" ]; then
            echo "[CXX] $1 -> $TARGETFILE"
            g++ $CFLAGS "$1" $LDFLAGS -o "$TARGETFILE"
        else
            printf "$1: Unknown suffix (\e[1;33mskipped\e[0m)\n"
        fi
        [ "$?" '!=' "0" ] && printf\
            '\e[1;31mError\e[0m while compiling file\n'
        shift
    done
    return 0
}


function convert_to_html ()
{
    while [ "$1" '!=' '' ]
    do
        for i in "$1"
        do 
            vim $i -c 'set background=dark' \
                -c 'highlight PreProc ctermfg=darkcyan' \
                -c "$BEFORE_CONVERT_TO_HTML" \
                -c "$BEFORE_CONVERT_TO_HTML1" \
                -c "$BEFORE_CONVERT_TO_HTML2" \
                -c TOhtml \
                -c :w \
                -c :qa 
        done
        shift
    done
}

function mkscreenacl ()
{
    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"
    while [ "$1" '!=' '' ]
    do
        for i in $PERMIT_COMMAND
        do
            echo "aclchg $1 +x $i"
        done
        echo "aclchg $1 -rw \"\#?\""    
        shift
    done
}

function get_file_size () 
{
    split_arguments "$@"
    "${prefixlist[@]}" du -s "${arglist[@]}" | { 
        read -d "   " dirsize
        echo "$dirsize"
        read throwaway
    } 
    unset arglist
    unset prefixlist
}

########## Background ##########

alias bgr=bgrun
alias bgv=bgview
alias bgl=bglist
alias bgc=bgcount
alias bgls=bglist
alias bgrm=bgclean

function bgrun ()
{
    [ "$#" = "0" ] && return 1
    [ '!' -d "$bgrunfiledir" ] && createdir_askmode "$bgrunfiledir" 0750
    local current_time=`date "+%Y%m%d-%H%M%S"`
    local cmdname=`echo "$1" | sed -e 's/-/_/g' -e 's/\\//_/g' -e 's/ /_/g'`
    if [ "`echo "$cmdname" | cut -c 1`" == "_" ]
    then
        cmdname=`echo "$cmdname" | cut -c 2-`
    fi
    local filename="$bgrunfiledir/$current_time-$cmdname"
    echo "Writing to $filename"
    {
        echo -n "$BASHPID " > "$filename"
        echo "$@" >> "$filename"
        exec "$@" &>> "$filename" 
    } &
}

function bglist ()
{
    local viewtime=0
    [ "$1" = "--full" ] && viewtime=1
    {
        for i in `find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | sort`
        do
            [ "$viewtime" = "1" ] && echo "$i"
            head -n 1 "$i" | {
                local procpid
                local cmdline
                read -d ' ' procpid
                read cmdline
                printf "(%5d) %s\n" "$procpid" "$cmdline"
            }
        done
    } | {
        if [ "$viewtime" = "1" ]
        then
            echo " INDEX         TIME          PID   COMMAND"
            local readstat=0
            local -i i=1
            while true
            do
                local dateandtime_long
                local cmdline
                read dateandtime_long
                read cmdline
                [ "$?" '!=' "0" ] && break
                local dateandtime=`basename "$dateandtime_long"`
    ####        local part_year=`echo $dateandtime | cut -c 1-4`
    ####        local part_month=`echo $dateandtime | cut -c 5-6`
    ####        local part_date=`echo $dateandtime | cut -c 7-8`
    ####        local part_hour=`echo $dateandtime | cut -c 10-11`
    ####        local part_minute=`echo $dateandtime | cut -c 12-13`
    ####        local part_second=`echo $dateandtime | cut -c 14-15`
                echo "$dateandtime" | {
                    read -n 4 part_year
                    read -n 2 part_month
                    read -n 2 part_date
                    read -n 1 drop_this_char; unset drop_this_char
                    read -n 2 part_hour
                    read -n 2 part_minute
                    read -n 2 part_second
                    printf '%6d' "$i" 
                    echo " $part_year-$part_month-$part_date $part_hour:$part_minute:$part_second $cmdline"
                }
                i=$i+1
            done
        else
            echo " INDEX    PID   COMMAND"
            cat -n
        fi
    } | $PAGER
}

function bgview ()
{
    local -i yourchoice
    if [ "$1" = "" ]
    then
        yourchoice=`bgcount`
    else
        if [ "$1" -le "0" ]
        then
            yourchoice=$((`bgcount`+$1))
        else
            yourchoice=$1
        fi
    fi
    echo "Your choice is $yourchoice."
    local realfilename=`find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | sort | sed -n ${yourchoice}p`
    head -n 1 "$realfilename" | {
        read -d ' ' procpid
        read cmdline
        echo "PID: $procpid"
        echo "Command Line: $cmdline"
    }
    read -e -p "View '$realfilename' ? " confirm
    if [ "$confirm" = "n" ] || [ "$confirm" = "N" ]
    then
        return 1
    fi
    {
        printf "===> Process Information: "
        cat "$realfilename"
    } | $PAGER
}

function bgcount ()
{
    find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | cut -d - -f 2,3 | wc | awk '{print $2}'
}

function bgclean ()
{
    if [ "$1" = "all" ]
    then
        echo "Removing the directory $bgrunfiledir"
        rm -rf "$bgrunfiledir" &
        return 0
    else
        split_arguments "$@"
        local -i i=0
        while [ "${arglist[$i]}" ]
        do
            arglist[$i]="-e ${arglist[$i]}p"
            i=$i+1
        done
        local oneline
        find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | sort | sed -n ${arglist[*]} | {
            while read oneline
            do
                echo "Removing $oneline"
                rm -f "$oneline"
            done
        }
    fi
    unset arglist
    unset prefixlist
}

function bgdu () 
{
    local -i j=1
    {
        echo " INDEX     SIZE   PID   COMMAND"
        for i in `find "$bgrunfiledir" -maxdepth 1 -mindepth 1 | sort`
        do
            head -n 1 "$i" | {
                local procpid
                local cmdline
                read -d ' ' procpid
                read cmdline
                printf "%6d %8d (%5d) %s\n" "$j" \
                    "`get_file_size "$i"`" \
                    "$procpid" "$cmdline"
            }
            j=$j+1
        done
    } | $PAGER
}

########## Background End ##########

function check_dmesg ()
{
    [ "$#" = "0" ] && return 1

    while true
    do
        PREVIOS_DMESG_BUF="$DMESG_BUF"
        DMESG_BUF="`dmesg`"
        [ "$PREVIOS_DMESG_BUF" '!=' "$DMESG_BUF" ] && [ "$FIRST_RUN" = "0" ] && echo '===> You should check the system message buffer <==='
        sleep $1
        [ "$?" '!=' "0" ] && return 1
        FIRST_RUN=0
    done 
}

function check_system_status ()
{
    [ "$#" = "0" ] && return 1

    filename_mail="$MAIL"
    filename_messages="/var/log/messages"
    filename_audit="/var/log/audit/audit.log"

    while true
    do
        previous_dmesg_buf="$current_dmesg_buf"
        current_dmesg_buf="`dmesg`"
        previous_mail_info="$current_mail_info"
        current_mail_info="`ls -l "$filename_mail"`"
        previous_messages_info="$current_messages_info"
        current_messages_info="`ls -l "$filename_messages"`"
        previous_audit_info="$current_audit_info"
        current_audit_info="`ls -l "$filename_audit"`"
        if [ "$first_run" = "0" ]
        then
            [ "$previous_dmesg_buf" '!=' "$current_dmesg_buf" ] && echo "===> The system message buffer is modified (dmesg) <==="
            [ "$previous_mail_info" '!=' "$current_mail_info" ] && echo "===> Your mailbox $filename_mail is modified <==="
            [ "$previous_messages_info" '!=' "$current_messages_info" ] && echo "===> $filename_messages is modified <==="
            [ "$previous_audit_info" '!=' "$current_audit_info" ] && echo "===> $filename_audit is modified <==="
        fi
        sleep $1
        first_run=0
    done 
}

function prehistory_backup ()
{
    echo "Checking your current history file"
    local -i currentcount=`cat "$HISTFILE" | wc -l`
    [ '!' -f "$historycountfile" ] && touch "$historycountfile"
    local -i previoushistorycount
    previoushistorycount=`cat "$historycountfile"`
    if [ "$currentcount" -lt "$previoushistorycount" ]
    then
        printf "\e[1;31mWarning\e[m: Your $HISTFILE may be TRUNCATED OR OVERWRITTEN BY OTHER PROGRAMS!\n"
        printf "Note: \e[1;33m$currentcount\e[m < $previoushistorycount\n"
        echo "Your $historycountfile and $historybackupfile will not be overwritten until this problem is fixed."
        echo " 1. Check your $HISTFILE."
        echo " 2. Edit your $HISTFILE manually if some unexpected changes are found." 
        echo "    (You may need $historybackupfile to do it) "
        echo " 3. Remove the file $historycountfile."
        echo " 4. Run the command \`prehistory_backup' again."
        return 3
    fi
    echo -n "Backing up your current history file ($previoushistorycount -> $currentcount, "
    if [ "$previoushistorycount" = "$currentcount" ]
    then
        echo "no modification)"
    else
        echo "+$(($currentcount-$previoushistorycount)))"
    fi
    echo "$currentcount" > "$historycountfile"
    \cp -f "$HISTFILE" "$historybackupfile"
}

########## Trash Manager ##########

alias trash_put=trash_mv
alias trash_add=trash_mv
alias trash_list=trash_ls
alias trash_ct=trash_count
alias trash_restore=trash_recover
alias trash_rc=trash_recover
alias trash_drop=trash_rm
alias trash_clean=trash_rm

function trash_mv ()
{
    [ "$#" = "0" ] && return 1
    [ '!' -d "$trashdir" ] && createdir_askmode "$trashdir" 0700
    local original_path
    local current_time
    local -i i=0
    split_arguments "$@"
    while [ "${arglist[$i]}" ]
    do
        original_path="`$REALPATH_PROGRAM "${arglist[$i]}"`"
        current_time=`date "+%Y%m%d-%H%M%S"`
        better_time=`date "+%Y-%m-%d %H:%M:%S"`
        dirname="`basename "${arglist[$i]}" | sed -e 's/-/_/g' -e 's/ /_/g'`"
        fulldirname="$trashdir/$current_time-$dirname"
        mkdir -p "$fulldirname"
        echo "Move: ${arglist[$i]} -> $fulldirname"
        "${prefixlist[@]}" mv "${arglist[$i]}" "$fulldirname"
        if [ "$?" = "0" ]
        then
            echo "$better_time" > "$fulldirname/information.date"
            echo "$original_path" > "$fulldirname/information.path"
        else
            rmdir "$fulldirname"
        fi
        i=$i+1
        shift
    done
    unset arglist
    unset prefixlist
}

function trash_rm ()
{
    split_arguments "$@"
    local -i i=0
    while [ "${arglist[$i]}" ]
    do
        arglist[$i]="-e ${arglist[$i]}p"
        i=$i+1
    done
    trash_dirname=`find "$trashdir" -mindepth 1 -maxdepth 1 | sort | sed -n ${arglist[*]} `
    echo 'Type rm -rf $trash_dirname to remove them.'
    unset arglist
    unset prefixlist
}

function trash_ls ()
{
    local -i i=1
    local oneline
    find "$trashdir" -mindepth 1 -maxdepth 1 | sort | {
        while read oneline
        do
            printf "%6d %s %s\n" "$i" \
                "`cat "$oneline/information.date"`" \
                "`cat "$oneline/information.path"`"
            i=$i+1
        done
    } | $PAGER
}

function trash_pushd ()
{
    [ -z "$1" ] && return 1
    pushd `find "$trashdir" -mindepth 1 -maxdepth 1 | sort | sed -n $1p`
}

function trash_cd ()
{
    [ -z "$1" ] && return 1
    cd `find "$trashdir" -mindepth 1 -maxdepth 1 | sort | sed -n $1p`
}

function trash_recover ()
{
    [ -z "$1" ] && return 1
    split_arguments "$@"
    local -i i=0
    while [ "${arglist[$i]}" ]
    do
        arglist[$i]="-e ${arglist[$i]}p"
        i=$i+1
    done
    find "$trashdir" -mindepth 1 -maxdepth 1 | sort | sed -n ${arglist[*]} | {
        while read oneline
        do
            local fromfile="$oneline/`basename "$(cat "$oneline/information.path")"`"
            local tofile="`dirname "$(cat "$oneline/information.path")"`"
            if [ -e "`cat "$oneline/information.path"`" ]
            then
                echo "Destination file exists."
                continue
            fi
            echo "Move: $fromfile -> $tofile"
            "${prefixlist[@]}" mv -f "$fromfile" "$tofile"
            if [ "$?" = "0" ]
            then
                echo "Remove: $oneline"
                \rm -rf "$oneline"
            fi
        done
    }
    unset arglist
    unset prefixlist
}

function trash_count () 
{
    find "$trashdir" -mindepth 1 -maxdepth 1 | wc | awk '{print $2}'
}

function trash_du ()
{
    split_arguments "$@"
    local oneline
    local -i i=1
    find "$trashdir" -maxdepth 1 -mindepth 1 | sort | {
        while read oneline
        do
            printf "%6d %8d %s\n" "$i" \
                "`get_file_size "$oneline" -- "${prefixlist[@]}"`" \
                "`cat "$oneline/information.path"`"
            i=$i+1
        done
    } | $PAGER
    unset arglist
    unset prefixlist
}

########## Trash Manager End ##########

function split_arguments ()
{
    local argcount=$#
    local -i i=0
    local prefix_start=0
    while [ "$1" ]
    do
        if [ "$prefix_start" == "0" ]
        then
            if [ "$1" = "--" ]
            then
                prefix_start=1
                i=0
                shift
                continue
            else
                arglist[$i]="$1"
            fi
        else
            prefixlist[$i]="$1"
        fi
        i=$i+1
        shift
    done
}

function check_important_files ()
{
    IMPORTANT_FILES="$HOME/.screenrc $HOME/.vimrc"
    for i in $IMPORTANT_FILES
    do
        [ '!' -f "$i" ] && printf "\e[1;31mWarning\e[m: \e[1;33m$i\e[m does not exist.\n"
    done
}

########## PATH Editor ##########

function split_path_core ()
{
    echo "$current_path" | {
        while read -d : oneline
        do
            [ '!' "$oneline" = '^' ] && echo "$oneline"
        done
        [ '!' "$oneline" = '^' ] && echo "$oneline"
    }
    unset oneline
}

function split_path () 
{
    coproc split_path_core
    readarray -t -u ${COPROC[0]} patharr
    wait $COPROC_PID
}

function update_path ()
{
    current_path=''
    local -i i=0
    local firsttime="yes"
    while [ "${patharr[$i]}" ]
    do
        if [ '!' "${patharr[$i]}" = "^" ]
        then
            if [ "$firsttime" ] 
            then
                firsttime=''
            else
                current_path+=':'
            fi
            current_path+="${patharr[$i]}"
        fi
        i=$i+1
    done
}

function old_path_editor ()
{
    old_path_editor_core
}

function old_ldpath_editor ()
{
    old_path_editor_core ld
}

function old_path_editor_core ()
{
    if [ "$1" = "ld" ]
    then
        export current_path="$LD_LIBRARY_PATH"
    else
        export current_path="$PATH"
    fi
    local should_continue="yes"
    local command
    local command_sub
    local command_sub2
    local -i i
    while [ "$should_continue" ]
    do
        split_path
        i=0
        echo "========================================"
        while [ "${patharr[$i]}" ]
        do
            echo "$i: ${patharr[$i]}"
            i=$i+1
        done
        [ "$i" = '0' ] && echo "(Empty or not declared)"
        echo "========================================"
        read -e -p "[A]ppend/(D)elete/(E)dit/(M)ove/(R)eset/(Q)uit ? " command
        case "$command" in
            ''|A|a)
                read -e -p "Type a new entry: " patharr[$i]
                update_path
                ;;
            D|d)
                read -e -p "Index: " command_sub
                patharr[$command_sub]='^'
                update_path
                ;;
            E|e)
                read -e -p "Index: " command_sub
                read -e -p "Modify this entry: " -i "${patharr[$command_sub]}" patharr[$command_sub] 
                update_path
                ;;
            M|m)
                read -e -p "From: " command_sub
                read -e -p "To: " command_sub2
                swaptmp="${patharr[$command_sub]}"
                patharr[$command_sub]="${patharr[$command_sub2]}"
                patharr[$command_sub2]="$swaptmp"
                unset swaptmp
                update_path
                ;;
            R|r)
                if [ "$1" = "ld" ]
                then
                    current_path="$LD_LIBRARY_PATH"
                else
                    current_path="$PATH"
                fi
                ;;
            Q|q)  
                if [ "$1" = "ld" ]
                then
                    export LD_LIBRARY_PATH="$current_path"
                    echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
                    history -s "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
                else
                    export PATH="$current_path"
                    echo "PATH=$PATH"
                    history -s "PATH=$PATH"
                fi
                should_continue=''
                ;;
            *)
                printf " \e[33m*** Unknown command ***\e[m \n"
                ;;
        esac
    done
    unset patharr
    unset current_path
}

########## PATH Editor End ##########

########## New PATH Editor ##########

function ldpath_editor ()
{
    path_editor LD_LIBRARY_PATH
}

function newpath_init ()
{
    unset newpath
    local pathsp="$pathorgval"
    local pathentry
    local -i i
    eval pathsp='"${pathsp// /\\}"'
    pathsp="${pathsp//:/ }"
    i=0
    for pathentry in $pathsp
    do
        newpath[$i]="${pathentry//\\/ }"
        i=$i+1
    done
}

function newpath_gen ()
{
    local -i i
    pathmodval=""
    i=0
    while [ "${newpath[$i]}" ]
    do
        if [ "$i" != 0 ]; then pathmodval+=":"; fi
        pathmodval+="${newpath[$i]}"
        i=$i+1
    done
}

function path_editor ()
{
    local newpathvarname
    local badcommand
    local command
    local command_sub
    local command_sub2
    local should_continue="yes"
    local -i i

    if [ -z "$1" ]
    then
        newpathvarname="PATH"
    else
        newpathvarname="$1"
    fi

    eval pathorgval=\${${newpathvarname}}
    newpath_init

    while [ "$should_continue" ]
    do
        i=0
        echo -n $'\e[2J\e[0;0H'
        if [ "$badcommand" = "yes" ]; then
            printf " \e[33m*** Command \`$command' is unknown ***\e[m \n"
            badcommand=""
        fi
        echo "        New PATH Editor for BASH        "
        echo "========================================"
        echo "Environment Variable: $newpathvarname"
        echo "----------------------------------------"
        while [ "${newpath[$i]}" ]
        do
            echo "$i: ${newpath[$i]}"
            i=$i+1
        done
        [ "$i" = '0' ] && echo "(Empty or not declared)"
        echo "========================================"
        read -e -p "[A]ppend/(I)nsert/(D)elete/(E)dit/(M)ove/(S)wap/(R)eset/(Q)uit ? " command
        case "$command" in
            ''|A|a)
                read -e -p "Type a new entry: " newpath[$i]
                ;;
            I|i)
                read -e -p "Type a new entry: " command_sub
                if [ -z "$command_sub" ]; then continue; fi
                newpath_tmp=( "${newpath[@]}" )
                unset newpath
                newpath="$command_sub"
                i=0
                while [ "${newpath_tmp[$i]}" ]
                do
                    newpath[$i+1]="${newpath_tmp[$i]}"
                    i=$i+1
                done
                unset newpath_tmp
                ;;
            D|d)
                read -e -p "Index: " command_sub
                if [ -z "$command_sub" ]; then continue; fi
                i="$command_sub"
                i=$i+1
                while [ "${newpath[$i]}" ]
                do
                    newpath[$i-1]="${newpath[$i]}"
                    i=$i+1
                done
                unset newpath[$i-1]
                ;;
            E|e)
                read -e -p "Index: " command_sub
                read -e -p "Modify this entry: " -i "${newpath[$command_sub]}" newpath[$command_sub] 
                ;;
            M|m)
                read -e -p "From: " command_sub
                read -e -p "To: " command_sub2
                if [ "$command_sub" -eq "$command_sub2" ]; then continue; fi
                cmdsubval="${newpath[$command_sub]}"
                if [ "$command_sub" -gt "$command_sub2" ]; then
                    i="$command_sub"
                    while [ "$i" -gt "$command_sub2" ]
                    do
                        newpath[$i]="${newpath[$i-1]}"
                        i=$i-1
                    done
                    newpath[$command_sub2]="$cmdsubval"
                else
                    i="$command_sub"
                    while [ "$i" -lt "$command_sub2" ]
                    do
                        newpath[$i]="${newpath[$i+1]}"
                        i=$i+1
                    done
                    newpath[$command_sub2]="$cmdsubval"
                fi
                unset cmdsubval
                ;;
            S|s)
                read -e -p "First entry: " command_sub
                read -e -p "Second entry: " command_sub2
                swaptmp="${newpath[$command_sub]}"
                newpath[$command_sub]="${newpath[$command_sub2]}"
                newpath[$command_sub2]="$swaptmp"
                unset swaptmp
                ;;
            R|r)
                read -e -p "Discard all changes [y/N] ? " command_sub
                if [ "$command_sub" = "y" ]; then
                    eval pathorgval=\${${newpathvarname}}
                    newpath_init
                fi
                ;;
            Q|q)  
                newpath_gen
                eval export ${newpathvarname}=\"$pathmodval\"
                echo "${newpathvarname}=$pathmodval"
                history -s "${newpathvarname}=$pathmodval"
                should_continue=''
                ;;
            *)
                badcommand="yes"
                ;;
        esac
    done
    unset newpath
    unset pathorgval
    unset pathmodval
}

########## New PATH Editor End ##########

function varset ()
{
    local varoldvalue
    local varnewvalue
    while [ "$1" ]
    do
        eval varoldvalue=\${$1}
        read -r -e -p "$1=" -i "$varoldvalue" varnewvalue
        eval $1=\"$varnewvalue\"
        shift
    done
}

function is_file_type ()
{
    local filename="$1"
    local typename="$2"
    shift 2
    [ "`"$@" find "$filename" -maxdepth 0 -type "$typename"`" ] && return 0
    return 1
}

function editlink ()
{
    local newdest
    local orgdest
    split_arguments "$@"
    local -i i=0
    while [ "${arglist[$i]}" ]
    do
        if is_file_type "${arglist[$i]}" "l" "${prefixlist[@]}"; then
            orgdest="`${prefixlist[@]} readlink "${arglist[$i]}"`"
            read -e -p "EditLink: ${arglist[$i]} -> " -i "$orgdest" newdest
        else
            printf "\e[1;33mWarning\e[m: ${arglist[$i]} is not a symbolic link.\n"
            i=$i+1
            continue
        fi
        if [ "$newdest" ] && [ "$newdest" '!=' "$orgdest" ]; then       
            "${prefixlist[@]}" rm -f "${arglist[$i]}"
            "${prefixlist[@]}" ln -sv "$newdest" "${arglist[$i]}"
        fi
        i=$i+1
    done
    unset arglist
    unset prefixlist
}

function backup_file ()
{
    split_arguments "$@"
    local current_time=`date +%Y%m%d`
    local rootfilename
    local -i i=0
    local -i j
    while [ "${arglist[$i]}" ]
    do
        if [ '!' -f "${arglist[$i]}" ] 
        then 
            printf "\e[1;31mError\e[m: ${arglist[$i]} does not exist or it is not a regular file.\n"
            i=$i+1
            continue
        fi
        rootfilename="${arglist[$i]}.$current_time"
        if [ -e "$rootfilename" ]
        then
            j=0
            while [ "$j" -lt "10" ]
            do
                if [ -e "$rootfilename.$j" ]
                then
                    j=$j+1
                    continue
                else
                    "${prefixlist[@]}" \cp -p "${arglist[$i]}" "$rootfilename.$j"
                    history -s "${prefixlist[@]}" \cp -p "${arglist[$i]}" "$rootfilename.$j"
                    "${prefixlist[@]}" touch -r "${arglist[$i]}" "$rootfilename.$j"
                    history -s "${prefixlist[@]}" touch -r "${arglist[$i]}" "$rootfilename.$j"
                    break
                fi
            done
            if [ '!' "$j" -lt "10" ]
            then
                printf "\e[1;31mError\e[m: Can not create a backup file for ${arglist[$i]}.\n"
                printf "\e[1;33mPlease delete some backup file because I only use 0 - 9.\e[m\n"
            fi
        else
            "${prefixlist[@]}" \cp -p "${arglist[$i]}" "$rootfilename"
            history -s "${prefixlist[@]}" \cp -p "${arglist[$i]}" "$rootfilename"
            "${prefixlist[@]}" touch -r "${arglist[$i]}" "$rootfilename"
            history -s "${prefixlist[@]}" touch -r "${arglist[$i]}" "$rootfilename"
        fi
        i=$i+1
    done
    unset arglist
    unset prefixlist
}

function keep_sudo_credential ()
{
    if [ "$1" ]
    then
        update_sudo_interval="$1"
    else
        update_sudo_interval="280"
    fi
    while true
    do
        sudo -v
        sleep "$update_sudo_interval"
    done
}

function get_memory_info ()
{
    case "`uname`" in
        "Linux")
            local meminfoline="`free -m | \grep -i mem`"
            local swapinfoline="`free -m | \grep -i swap`"
            local memtotal="`echo "$meminfoline" | awk '{print $2}'`"
            local memused="`echo "$meminfoline" | awk '{print $3}'`"
            local membuf="`echo "$meminfoline" | awk '{print $6}'`"
            local memcache="`echo "$meminfoline" | awk '{print $7}'`"
            local memprog=$(($memused-$membuf-$memcache))
            local swaptotal="`echo "$swapinfoline" | awk '{print $2}'`"
            local swapused="`echo "$swapinfoline" | awk '{print $3}'`"
            echo "Memory: $memused / $memtotal MB (`printf %2d $(($memused*100/$memtotal))`%)"
            echo "Detail:"
            echo "    Used:    `printf %5d $memprog` MB (`printf %2d $(($memprog*100/$memtotal))`%)"
            echo "    Buffers: `printf %5d $membuf` MB (`printf %2d $(($membuf*100/$memtotal))`%)"
            echo "    Cached:  `printf %5d $memcache` MB (`printf %2d $(($memcache*100/$memtotal))`%)"
            if [ "$swaptotal" = "0" ]
            then
                echo "Swap: not available"
            else
                echo "Swap: $swapused / $swaptotal MB (`printf %2d $(($swapused*100/$swaptotal))`%)"
            fi
            ;;
        "FreeBSD")
            local mempagesize="`sysctl -n hw.pagesize`"
            local mempagecount="`sysctl -n hw.availpages`"
            local memactive="`sysctl -n vm.stats.vm.v_active_count`"
            local meminactive="`sysctl -n vm.stats.vm.v_inactive_count`"
            local memwire="`sysctl -n vm.stats.vm.v_wire_count`"
            local memcache="`sysctl -n vm.stats.vm.v_cache_count`"
            local memfree="`sysctl -n vm.stats.vm.v_free_count`"
            local swapenabled="`sysctl -n vm.swap_enabled`"
            echo "Memory (Active):   `printf %5d $(($memactive*$mempagesize/1048576))` MB (`printf %2d $(($memactive*100/$mempagecount))`%)"
            echo "Memory (Inactive): `printf %5d $(($meminactive*$mempagesize/1048576))` MB (`printf %2d $(($meminactive*100/$mempagecount))`%)"
            echo "Memory (Wired):    `printf %5d $(($memwire*$mempagesize/1048576))` MB (`printf %2d $(($memwire*100/$mempagecount))`%)"
            echo "Memory (Cache):    `printf %5d $(($memcache*$mempagesize/1048576))` MB (`printf %2d $(($memcache*100/$mempagecount))`%)"
            echo "Memory (Free):     `printf %5d $(($memfree*$mempagesize/1048576))` MB (`printf %2d $(($memfree*100/$mempagecount))`%)"
            echo "Total Memory:      `printf %5d $(($mempagecount*$mempagesize/1048576))` MB"
            if [ "$swapenabled" = "1" ]; then
                echo ""
                echo "Swap devices:"
                swapinfo -m
            else
                echo "Swap: not enabled"
            fi
            ;;
        *)
            echo "Unsupported operating system."
            ;;
    esac
}

function set_console_title ()
{
    case "$TERM" in
        screen)
            printf "\033]0;"
            echo -n "$*"
            printf "\033\\"
            ;;
        xterm*)
            printf "\033]0;"
            echo -n "$*"
            printf "\007"
            ;;
        *)
            echo "Your terminal may not have the hardstatus line."
            echo "Note: TERM=$TERM"
            ;;
    esac
}

function mvfile ()
{
    local nocheck=0
    [ "$1" = "-n" ] && nocheck=1 && shift
    split_arguments "$@"
    local -i i=0
    while [ "${arglist[$i]}" ] 
    do
        if [ "$nocheck" = "0" ] && [ '!' -e "${arglist[$i]}" ]
        then
            printf "\e[33mWarning\e[m: ${arglist[$i]} does not exist. (Use -n to override)\n"
            i=$i+1
            continue
        fi
        echo "Old name: ${arglist[$i]}"
        read -p "New name: " -e -i "${arglist[$i]}" new_file_name
        if [ "$new_file_name" ] && [ "${arglist[$i]}" != "$new_file_name" ]
        then
            "${prefixlist[@]}" mv -iv "${arglist[$i]}" "$new_file_name"
            history -s "${prefixlist[@]}" mv -iv "${arglist[$i]}" "$new_file_name"
        fi
        i=$i+1
    done
    unset arglist
    unset prefixlist
    unset new_file_name
}

function createdir_askmode ()
{
    newdir_mode="$2"
    if mkdir -p "$1"
    then
        echo "Directory $1 is created." 
        printf "Change the mode of the directory... "
        read -i "$newdir_mode" -p ">>> Mode: " -e newdir_mode
        chmod "$newdir_mode" "$1"
    else
        echo "Cannot create directory $1!"
        return 1
    fi  
}

########## Help ##########

alias helpf='help_function'
alias helpm='help_myself'

function print_iconv ()
{
    [ "$1" = "$2" ] && cat && return 0
    iconv -f "$1" -t "$2" 
}

function help_myself () 
{
    echo "argc = $#"
    echo "argv[0] = $0"
    i=1
    while [ "$1" ]
    do
        echo "argv[$i] = $1"
        i=$(($i+1))
        shift
    done
}

function help_obsolete ()
{
    cat << ENDHELPMSG
 @@@ Obsolete Group: PATH Editor @@@
    old_path_editor
    old_ldpath_editor
 x  split_path
 x  split_path_core
 x  update_path 
 x  old_path_editor_core
ENDHELPMSG
}

function help_function ()
{
    [ "$#" = "0" ] && {
        cat << ENDHELPMSG
 <<< Help >>>
    help_myself [arguments ...]                            (helpm)
    help_function [functions ...]                          (helpf)
    help_obsolete
 x  print_iconv
 <<< Group: Background >>>
    bgrun command [arguments ...]                          (bgr)
    bglist [--full]                                        (bgl, bgls)
    bgview [number]                                        (bgv)
    bgclean [all | numbers ...]                            (bgrm)
    bgcount                                                (bgc)
    bgdu
 <<< Group: Trash >>>
    trash_mv [filenames ...] [-- sudo_prefix ...]     (trash_put, trash_add)
    trash_ls                                          (trash_list)
    trash_cd number
    trash_pushd number
    trash_recover numbers ... [-- sudo_prefix ...]    (trash_restore, trash_rc)
    trash_rm numbers ...                              (trash_drop, trash_clean)
    trash_count                                       (trash_ct)
    trash_du [-- sudo_prefix ...]
 <<< Group: New PATH Editor >>>
    path_editor [variable]
    ldpath_editor
 x  newpath_init
 x  newpath_gen
 <<< Other >>>
    backup_file filename ... [-- sudo_prefix ...]
    check_dmesg seconds
    check_system_status seconds
    check_important_files
    compile_all [-n] filenames ...
    convert_to_html filename ...
    editlink filenames ... [-- sudo_prefix ...]
    get_memory_info
    keep_sudo_credential [seconds]
    mkscreenacl usernames ...
    mvfile [-n] filenames ... [-- sudo_prefix ...]
    prehistory_backup
    set_console_title
    varset variables ...
 x  createdir_askmode dirname
 x  is_file_type filename type [-- sudo_prefix ...]
 x  get_file_size filename [-- sudo_prefix ...]
 x  split_arguments [arguments ...]

Obsolete functions are not printed. Type \`help_obsolete' to print them. 
ENDHELPMSG
    } && return 0
    local current_charset=`echo "$LC_ALL" | cut -d . -f 2`
    local -i i
    while [ "$1" ]
    do
        case "$1" in
            help_myself|helpm)
                cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
help_myself
    一個測試命令列的小函式
ENDHELPMSG
                ;;
            help_function|helpf)
                cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
help_function
    顯示 .bash_include 提供的額外函式清單
    註:前方加上「x」符號者表示此為內部使用的函式,不宜直接使用
ENDHELPMSG
                ;;
            bgrun|bgr)
                cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
bgrun command [arguments ...]
    執行指令 command 並將輸出導入檔案
    註:此函式會自動以目前時間和指令名稱為檔案命名
ENDHELPMSG
                ;;
            bglist|bgl|bgls)
                cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
bglist [--full]
    列出所有使用 bgrun 執行的指令
    若加上 --full 選項,則可同時察看時間
ENDHELPMSG
                ;;
            bgview|bgv)
                cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
bgview [number]
    顯示以 bgrun 執行指令的輸出,若省略 number,表示是最近一次執行的指令
    若 number >  0,
        表示第 number 個指令 (此數值可由 bglist 函式取得)
    若 number <= 0,
        表示第「指令總數-number」個指令 (指令總數可由 bgcount 函式取得)
ENDHELPMSG
                ;;
            bgclean|bgrm)
                cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
bgclean [all | numbers ...]
    bgclean all 可清除所有指令的輸出檔
    bgclean 3 5 7 10 表示清除第 3、5、7、10 個指令輸出檔 (編號可由 bglist 取得)
ENDHELPMSG
                ;;
            bgcount|bgc)
                cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
bgcount
    顯示指令輸出檔總數
ENDHELPMSG
                ;;
            bgdu)
                cat << ENDHELPMSG | print_iconv "UTF-8" "$current_charset"
bgdu
    顯示每個指令輸出檔的檔案大小 (單位:KB)
ENDHELPMSG
                ;;
            *)
                echo "Help message for $1 is not found"
                ;;
        esac
        shift
    done
}

########## Help End ##########

# Doing something

umask 0022

if [ "$interactive_shell" ] 
then
    echo "Running interactive shell configuration"
    check_important_files
    startcolor
    prehistory_backup
    bind '"\e[A":history-search-backward'
    bind '"\e[B":history-search-forward'
    if [ -z "$PROMPT_COMMAND" ] && [ -e "$HOME/.bash_title" ]; then
        case "$TERM" in
            xterm*)
                PROMPT_COMMAND='printf "\033]0;%s@%s:%s (%s)\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" "`date "+%H:%M:%S"`"'
                ;;
            screen)
                PROMPT_COMMAND='printf "\033]0;%s@%s:%s (%s)\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" "`date "+%H:%M:%S"`"'
                ;;
        esac
    fi
fi

if [ "`uname`" = "Linux" ]
then
    [ "$interactive_shell" ] && echo "Setting special things for Linux"
    REALPATH_PROGRAM="readlink -f"
    ulimit -c unlimited
fi

[ "$interactive_shell" ] && echo "Setting shell options"

shopt -s histappend
shopt -s checkwinsize
shopt -s checkjobs
shopt -s checkhash
shopt -s cmdhist
shopt -s mailwarn

[ "$interactive_shell" ] && {
    echo "Done"
    if [ "$UID" = "0" ] || [ "$EUID" = "0" ] 
    then
        printf "\nNote: You may be \e[1;32mprivileged\e[m now!\n\n"
    fi
}