3 # redirect output to log file. this doesn't work. todo figure out why
4 #exec 1>>/a/tmp/bashlog
5 #exec 2>>/a/tmp/bashlog
8 # By default this file is sourced for ALL ssh commands. This is wonky.
9 # Normally, this file is not sourced when a script is run, but we can
10 # override that by having #!/bin/bash -l. I want something similar for ssh
11 # commands. when a local script runs an ssh command, this file should not be
12 # sourced by default, but we should be able to override that.
14 # so here we test for conditions of a script under ssh and return if so. To test
15 # for an overriding condition, we have a few options. one is to use an
16 # environment variable. env variables sent across ssh are strictly limited. ssh
17 # -t which sets $SSH_TTY, but within a script that won't work because tty
18 # allocation will fail. We could override an obscure unused LC_var, like
19 # telephone, but I don't want to run into some edge case where that messes
20 # things up. we could transfer a file which we could test for, but I can't think
21 # of a way to make that inherently limited to a single ssh command. I choose to
22 # set SendEnv and AcceptEnv ssh config vars to allow the environment variable
23 # BASH_LOGIN_SHELL to propagate across ssh.
25 # assume we want ssh commands to source this file if we are sourcing it,
26 # and we haven't specified otherwise already
27 [[ ! $BASH_LOGIN_SHELL ]] && export BASH_LOGIN_SHELL=true
29 # first conditions show that we are an ssh command without an interactive shell
30 if [[ $SSH_CONNECTION ]] \
34 && [[ ! $BASH_LOGIN_SHELL == true ]]; then
42 # note, to catch errors in functions but not outside, do:
45 # trap 'trap ERR' RETURN
55 # remove all aliases. aliases provided by the system tend to get in the way,
56 # for example, error happens if I try to define a function the same name as an alias
59 # remove gnome keyring warning messages
60 # there is probably a more proper way, but I didn't find any easily on google
61 # now using xfce+xmonad instead of vanilla xmonad, so disabling this
62 #unset GNOME_KEYRING_CONTROL
64 # use extra globing features.
66 # include .files when globbing, but ignore files name . and ..
67 # setting this also sets dotglob
68 export GLOBIGNORE=*/.:*/..
70 # broken with bash_completion package. Saw a bug for this once. Don't anymore.
71 # still broken in wheezy
72 # still buggered in latest stable from the web, version 2.1
73 # perhaps its fixed in newer git version, which fails to make for me
74 # this note is from 6-2014.
75 # Also, enabling this before sourcing .bashrc makes PATH be empty.
78 # make tab on an empty line do nothing
79 shopt -s no_empty_cmd_completion
82 # http://bash-completion.alioth.debian.org/
83 # might be sourced by the system already, but I've noticed it not being sourced before
84 if ! type _init_completion &> /dev/null && [[ -r "/usr/share/bash-completion/bash_completion" ]]; then
85 . /usr/share/bash-completion/bash_completion
89 # fix spelling errors for cd, only in interactive shell
91 # append history instead of overwritting it
93 # for compatibility, per gentoo/debian bashrc
95 # attempt to save multiline single commands as single history entries.
101 if [[ $INSIDE_EMACS ]]; then
102 # EMACS is used by bash on startup, but we don't need it anymore.
103 # plus I hit a bug in a makefile which inherited it
108 # scp completion does not work, but this doesn't fix it. todo, figure this out
109 complete -r scp &> /dev/null
110 # todo, remote file completion fails, figure out how to turn it off
114 if [[ $- == *i* ]]; then
115 # for readline-complete.el
116 if [[ $INSIDE_EMACS ]]; then
117 # all for readline-complete.el
119 bind 'set horizontal-scroll-mode on'
120 bind 'set print-completions-horizontally on'
121 bind '"\C-i": self-insert'
123 # arrow keys. for other terminals, see http://unix.stackexchange.com/questions/10806/how-to-change-previous-next-word-shortcut-in-bash
124 if [[ $TERM == "xterm" ]]; then
125 bind '"\e[1;5C": shell-forward-word' 2>/dev/null
126 bind '"\e[1;5D": shell-backward-word' 2>/dev/null
128 bind '"\eOc": shell-forward-word'
129 bind '"\eOd": shell-backward-word'
131 # terminal keys: C-c, C-z. the rest defined by stty -a are, at least in
132 # gnome-terminal, overridden by bash, or disabled by the system
133 stty werase undef lnext undef stop undef start undef
140 # history number. History expansion is good.
142 # history file size limit, set to unlimited.
143 # this needs to be different from the default because
144 # default HISTFILESIZE is 500 and could clobber our history
146 # max commands 1 session can append/read from history
148 # my own history size limit based on lines
149 HISTFILELINES=1000000
151 # the time format display when doing the history command
152 # also, setting this makes the history file record time
153 # of each command as seconds from the epoch
154 HISTTIMEFORMAT="%I:%M %p %m/%d "
155 # consecutive duplicate lines don't go in history
156 HISTCONTROL=ignoredups
157 # works in addition to HISTCONTROL to do more flexible things
158 # it could also do the same things as HISTCONTROL and thus replace it,
162 export BC_LINE_LENGTH=0
165 # note, if I use a machine I don't want files readable by all users, set
166 # umask 077 # If fewer than 4 digits are entered, leading zeros are assumed
175 for _x in /a/bin/distro-functions/src/* /a/bin/bash-programs-by-ian/repos/*/*-function; do
179 source /a/bin/semi-private # so I can share my bashrc
180 source $(dirname $(readlink -f $BASH_SOURCE))/path_add-function
181 path_add --ifexists --end /a/opt/adt-bundle*/tools /a/opt/adt-bundle*/platform-tools
182 # todo, these need to be renamed to be less generic.
183 # sync overrode something else useful
184 #path_add $HOME/bin/bash-programs-by-ian/utils
186 [[ -e $HOME/mw_vars ]] && source $HOME/mw_vars
192 # disabled for now, but these are generally good
193 # if [[ $- == *i* ]]; then
198 # remove any default aliases for these
199 alias ls > /dev/null 2>&1 && unalias ls
200 alias ll > /dev/null 2>&1 && unalias ll
201 alias grep > /dev/null 2>&1 && unalias grep
205 command mkdir -p "$@"
210 complete -A stopped -P '"%' -S '"' d
215 # note: gksudo is recommended for X apps because it does not set the
216 # home directory to the same, and thus apps writing to ~ fuck things up
217 # with root owned files.
220 # alias s='SUDOD="$PWD" sudo -i '
221 # because this is an alias, and the extra space at the end, it would allow
222 # aliases to be used with it. but aliases aren't used in scripts,
223 # better to eliminate inconsistencies. Plus, you can't do s=s; $s command
224 # with an alias, which I like to do in some functions
225 # extra space at the end allows aliases to work
227 if [[ $EUID != 0 || $1 == -* ]]; then
228 SUDOD="$PWD" sudo -i "$@"
236 if [[ $OS == Windows_NT ]]; then
237 alias ffs='cygstart "/c/Program Files (x86)/Mozilla Firefox/firefox.exe" -P scratch'
239 alias j='command cygpath'
240 alias t='command cygstart'
241 alias cygstart='echo be quick, use the alias "t" instead :\)'
242 alias cygpath='echo be quick, use the alias "j" instead :\)'
250 #####################
252 #####################
259 debian_pick_mirror () {
260 # netselect-apt finds a fast mirror.
261 # but we need to replace the mirrors ourselves,
262 # because it doesn't do that. best it can do is
263 # output a basic sources file
264 # here we get the server it found, get the main server we use
265 # then substitute all instances of one for the other in the sources file
266 # and backup original to /etc/apt/sources.list-original.
267 # this is idempotent. the only way to identify debian sources is to
268 # note the original server, so we put it in a comment so we can
270 local file=$(mktemp -d)/f # safe way to get file name without creating one
271 sudo netselect-apt -o "$file" || return 1
272 url=$(grep ^\\w $file | head -n1 | awk '{print $2}')
273 sudo cp -f /etc/apt/sources.list /etc/apt/sources.list-original
275 sudo sed -ri "/http.us.debian.org/ s@( *[^ #]+ +)[^ ]+([^#]+).*@\1$url\2# http.us.debian.org@" /etc/apt/sources.list
285 du -sh ${@:-*} | sort -h
291 if type -t trash-put >/dev/null; then
292 # skip args that don't exist, or else it's an err
293 for x in "$@"; do [[ ! -e $x ]] || args+=("$x"); done
294 [[ ! ${args[@]} ]] || trash-put "${args[@]}"
300 ccat () { # config cat. see a config without extra lines.
301 grep '^\s*[^[:space:]#]' "$@"
305 if type ack-grep >/dev/null 2>&1; then
313 [[ $EUID == 0 ]] || s=s
314 $s postconf -ev "${MAPFILE[@]}"
322 # this goes to full width
323 #len=${1:-$((COLUMNS -7))}
326 if (( x == len )); then
335 for ((i=0; i<x; i++)); do
353 grep -iIP --color=auto "$@"
357 if [[ ${#@} == 1 ]]; then
358 grep -riIP --color=auto "$@" .
360 grep -riIP --color=auto "$@"
365 rld /a/h/_site/ li:/var/www/iankelling.org/public_html
374 local startdir="$PWD"
377 ssh $x mkdir -p bin/distro-functions/src
378 tar cz bin/bash-programs-by-ian bin/semi-private bin/distro-functions/src | ssh $x tar xz
381 command cp /a/c/repos/bash/!(.git) ~/.gitconfig .
383 tar cz * | ssh $x tar xz
389 for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done
392 whatismyip() { curl ipecho.net/plain ; echo; }
395 k() { grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 40; }
397 calc() { echo "scale=3; $*" | bc -l; }
398 # no having to type quotes, but also no command history:
402 echo "scale=3; $x" | bc -l
406 # setup for format of postfix
412 local unified="$(mktemp)"
416 _cdiff-prep "$1" "$f1"
417 _cdiff-prep "$2" "$f2"
418 cat "$f1" "$f2" | grep -Po '^[^=]+=' | sort | uniq > "$unified"
419 while IFS= read -r line; do
420 # the default bright red / blue doesn't work in emacs shell
421 dwdiff -cblue,red -A best -d " ," <(grep "^$line" "$f1" || echo ) <(grep "^$line" "$f2" || echo ) | colordiff
434 # 2086 = unquoted $var
435 # 2046 = unquoted $(cmd)
436 # i had -x as an arg, but debian testing(stretch) doesn't support it
437 shellcheck -e 2086,2046,2068,2006,2119 "$@"
440 # join options which are continued to multiples lines onto one line
443 grep -vE '^([ \t]*#|^[ \t]*$)' "$1" | while IFS= read -r line; do
444 # remove leading spaces/tabs. assumes extglob
445 if [[ $line == "[ ]*" ]]; then
451 elif [[ $line == *=* ]]; then
452 echo "$pastline" >> "$2"
455 pastline="$pastline $line"
458 echo "$pastline" >> "$2"
461 # makes it so chown -R symlink affects the symlink and its target.
463 if [[ $1 == -R ]]; then
465 command chown -h "$@"
467 command chown -RH "$@"
477 if [[ $# == 0 ]]; then
478 cp /a/bin/data/COPYING .
480 cp /a/bin/data/COPYING "$@"
486 diff --strip-trailing-cr -w "$@" # diff content
491 date "+%A, %B %d, %r" "$@"
498 envload() { # load environment from a previous: export > file
499 local file=${1:-$HOME/.${USER}_env}
500 eval "$(export | sed 's/^declare -x/export -n/')"
501 while IFS= read -r line; do
502 # declare -x makes variables local to a function
503 eval ${line/#declare -x/export}
509 # havn't tested these:
510 #file cut copy and paste, like the text buffers :)
511 _fbufferinit() { # internal use by
512 ! [[ $my_f_tempdir ]] && my_f_tempdir=$(mktemp -d)
513 rm -rf "$my_f_tempdir"/*
517 cp "$@" "$my_f_tempdir"/
521 mv "$@" "$my_f_tempdir"/
523 fpst() { # file paste
524 [[ $2 ]] && { echo too many arguments; return 1; }
526 cp "$my_f_tempdir"/* "$target"
530 # find array. make an array of file names found by find into $x
531 # argument: find arguments
532 # return: find results in an array $x
534 while read -rd ''; do
536 done < <(find "$@" -print0);
540 git_empty_branch() { # start an empty git branch. carefull, it deletes untracked files.
541 [[ $# == 1 ]] || { echo 'need a branch name!'; return 1;}
543 gitroot || return 1 # function to set gitroot
544 builtin cd "$gitroot"
545 git symbolic-ref HEAD refs/heads/$1
552 if type -P firefox &>/dev/null; then
560 firefox -P default "$@" >/dev/null 2>&1
564 firefox -P alt "$@" >/dev/null 2>&1
571 # horizontal row. used to break up output
572 hr() { printf "$(tput setaf 5)â–ˆ$(tput sgr0)%.0s" $(seq $COLUMNS); }
578 # modified from ~/local/bin/git-completion.bash
579 # other completion commands are mostly taken from bash_completion package
580 complete -o bashdefault -o default -o nospace -F _git i 2>/dev/null \
581 || complete -o default -o nospace -F _git i
590 find -L . -iname "*$**" 2>/dev/null
597 if [[ $PWD == /[iap] ]]; then
598 command ls -A --color=auto -I lost+found "$@"
600 command ls -A --color=auto "$@"
606 lld() { ll -d "$@"; }
609 low() { # make filenames all lowercase
612 y=$(tr "[A-Z]" "[a-z]" <<<"$x")
613 [[ $y != $x ]] && mv "$x" "$y"
618 lower() { # make first letter of filenames lowercase.
621 if [[ ${x::1} == [A-Z] ]]; then
622 y=$(tr "[A-Z]" "[a-z]" <<<"${x::1}")"${x:1}"
623 safe_rename "$x" "$y"
629 if [[ $# != 2 ]]; then
630 echo safe_rename error: $# args, need 2 >2
632 elif [[ $1 != $2 ]]; then
634 echo Cannot rename "$1" to "$2" as it already exists.
645 safe_rename "$x" "$y"
653 # test existence / exists
657 [[ -e "$x" || -L "$x" ]] || ret=1
662 # show make targets, via http://stackoverflow.com/questions/3063507/list-goals-targets-in-gnu-make
664 make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
668 # fix root file ownership for FILE argument.
669 # check if parent or grandparent is not root and if the dir of FILE is also
670 # owned by that user, and change ownership to that user
673 if [[ $EUID == 0 ]]; then
674 te "$1" || touch "$1"
675 if [[ $(stat -c "%u" "$1") == 0 ]] ; then
676 argdir=$(dirname "$1")
677 if [[ $(stat -c "%u" "$argdir") != 0 ]] ; then
678 if ! chown "--reference=$argdir" "$1"; then
679 echo failed to fix bad ownership file permissons
687 # see notes for usage
690 local dname="${PWD##*/}"
691 local m="/a/tmp/$dname-missing"
692 local d="/a/tmp/$dname-diff"
693 [[ -e $d ]] && rm "$d"
694 [[ -e $m ]] && rm "$m"
697 while read -r line; do
699 if [[ -e "$fsfile" ]]; then
700 md5diff "$line" "$fsfile" && tee -a "/a/tmp/$dname-diff" <<< "$fsfile $line"
706 done < <(find -type f )
709 (( msize <= 100 )) && cat $m
721 echo different > $x/c/d
725 # expected output, with different tmp dirs
726 # /tmp/tmp.HDPbwMqdC9/c/d ./c/d
727 # /a/tmp/tmp.qLDkYxBYPM-missing
731 # test whether missing files were renamed, generally for use with fsdiff
732 # $1 = fsdiff output file, $2 = directory to compare to. pwd = fsdiff dir
733 # echos non-renamed files
738 { sums+=( "$(md5sum < "$x")" ) ; } 2>/dev/null
740 while read -r line; do
741 { missing_sum=$(md5sum < "$line") ; } 2>/dev/null
743 for x in "${sums[@]}"; do
744 if [[ $missing_sum == "$x" ]]; then
749 $renamed || echo "$line"
755 # get a random string
756 #par2rbase=$(head -c 50 /dev/urandom | tr -cd '[:alpha:]')
758 [[ $par2rbase ]] || { echo "set \$par2rbase first"; return 1; }
763 par2 c QDLDeDJ6z4.par2 *
771 [[ $(md5sum < "$1") != $(md5sum < "$2") ]]
775 pfind() { #find *$1* in $PATH
776 [[ $# != 1 ]] && { echo requires 1 argument; return 1; }
778 IFS=: pathArray=($PATH); unset IFS
779 find "${pathArray[@]}" -iname "*$1*"
782 # do pwd + some other info.
783 #pwd() { echo "$(ll -d "$PWD") $USER@$HOSTNAME $(date +%r)"; }
785 q() { # start / launch a program in the backround and redir output to null
790 apg -s -m 10 -x 14 -t
794 exit "$@" 2>/dev/null
797 # connect to vms made with virt-install
799 spicy -p $(sudo virsh dumpxml "$1"|grep "<graphics.*type='spice'"|\
800 sed -r "s/.*port='([0-9]+).*/\1/")
802 rspicy() { # HOST DOMAIN
803 local port=$(ssh $1<<EOF
804 sudo virsh dumpxml $2|grep "<graphics.*type='spice'" | \
805 sed -rn "s/.*port='([0-9]+).*/\1/p"
811 echo "error: no port found. check that the domain is running."
816 # trash-restore lists everything that has been trashed at or below CWD
817 # This picks out files just in CWD, not subdirectories,
818 # which also match grep $1, usually use $1 for a time string
819 # which you get from running restore-trash once first
823 # last condition is to not ask again for ones we skipped
824 while name="$( echo | restore-trash | gr "$PWD/[^/]\+$" | gr "$1" )" \
825 && [[ $name ]] && (( $(wc -l <<<"$name") >= nth )); do
826 name="$(echo "$name" | head -n $nth | tail -n 1 )"
827 read -p "$name [Y/n] " ask
828 if [[ ! $ask || $ask == [Yy] ]]; then
829 x=$( echo "$name" | gr -o "^\s*[0-9]*" )
830 echo $x | restore-trash > /dev/null
831 elif [[ $ask == [Nn] ]]; then
839 # rsync, root is required to keep permissions right.
840 # rsync --archive --human-readable --verbose --itemize-changes --checksum \(-ahvic\) \
841 # --no-times --delete
842 # basically, make an exact copy, use checksums instead of file times to be more accurate
843 rl() { rsync -ahvic --delete "$@"; }
844 # don't delete files on the target end which do not exist on the original end:
845 rld() { rsync -ahvic "$@"; }
846 # useful for selectively sending dirs which have been synced with unison,
847 # where the path is the same on both hosts.
848 rlu() { # [OPTS] HOST PATH
849 # eg rlu -opts frodo testpath
851 opts=("${@:1:$#-2}") # 1 to last -2
854 if [[ $host == lj ]]; then
857 # rync options are without -g for group
858 s rsync -rlpthvi$o "${opts[@]}" "$path" "root@$host:$path";
861 lcn() { locate -i "*$**"; }
864 s systemctl start openvpn@client&
865 journalctl --unit=openvpn@client -f -n0
868 s systemctl stop openvpn@client
872 complete -F _rsync -o nospace rld rlt fl
873 # rl without preserving modification time. for some reason I had this as default before.
874 # perhaps that reason will come up again and I will document it.
875 rlt() { rsync -ahvic --delete --no-t "$@"; }
877 if ! type service &>/dev/null; then
879 echo actually running: systemctl $2 $1
884 # use sb instead of s is for sudo redirections, eg. sb 'echo "ok fine" > /etc/file'
889 complete -F _root_command s sb
891 # use -ll, less secure but faster.
896 # sudo redo. be aware, this command may not work right on strange distros or earlier software
898 if [[ $# == 0 ]]; then
899 sudo -E bash -c -l "$(history -p '!!')"
901 echo this command redos last history item. no argument is accepted
905 rbpipe() { rbt post -o --diff-filename=- "$@"; }
906 rbp() { rbt post -o "$@"; }
909 # log with script. timing is $1.t and script is $1.s
910 # -l to save to ~/typescripts/
911 # -t to add a timestamp to the filenames
913 local logdir do_stamp arg_base
914 (( $# >= 1 )) || { echo "arguments wrong"; return 1; }
917 while getopts "lt" option
920 l ) arg_base=$logdir ;;
924 shift $(($OPTIND - 1))
926 [[ -e $logdir ]] || mkdir -p $logdir
927 $do_stamp && arg_base+=$(date +%F.%T%z)
928 script -t $arg_base.s 2> $arg_base.t
930 splay() { # script replay
931 #logRoot="$HOME/typescripts/"
932 #scriptreplay "$logRoot$1.t" "$logRoot$1.s"
933 scriptreplay "$1.t" "$1.s"
937 # like -e for functions. returns on error.
938 # at the end of the function, disable with:
941 trap 'echo "${BASH_COMMAND:+BASH_COMMAND=\"$BASH_COMMAND\" }
942 ${FUNCNAME:+FUNCNAME=\"$FUNCNAME\" }${LINENO:+LINENO=\"$LINENO\" }\$?=$?"
949 (sleep $(calc "$@ * 60") && mpv --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 &
953 local s; [[ $EUID != 0 ]] && s=sudo
954 if type -p systemctl &>/dev/null; then
964 if type -p systemctl &>/dev/null; then
974 s virsh dumpxml $vm | sed -r "s/(<listen.*address=')([^']+)/\1$ip/" | \
975 sed -r "s/listen='[^']+/listen='$ip/"> $t
982 vm-set-listen $1 0.0.0.0
986 vm-set-listen $1 127.0.0.1
992 local dir="$(dirname "$1")"
993 if [[ -e $1 && ! -w $1 || ! -w $(dirname "$1") ]]; then
998 ts() { # start editing a new file
999 [[ $# != 1 ]] && echo "I need a filename." && return 1
1001 if [[ $- != *i* ]]; then
1004 if [[ $1 == *.c ]]; then
1005 e '#include <stdio.h>' >"$1"
1006 e '#include <stdlib.h>' >>"$1"
1007 e 'int main(int argc, char * argv[]) {' >>"$1"
1008 e ' printf( "hello world\n");' >>"$1"
1009 e ' return 0;' >>"$1"
1011 e "${1%.c}: $1" > Makefile
1012 e " g++ -ggdb -std=gnu99 -o ${1%.c} $<" >> Makefile
1013 e "#!/bin/bash" >run.sh
1014 e "./${1%.c}" >>run.sh
1016 elif [[ $1 == *.java ]]; then
1017 e "public class ${1%.*} {" >"$1"
1018 e ' public static void main(String[] args) {' >>"$1"
1019 e ' System.out.println("Hello, world!");' >>"$1"
1024 echo "#!/bin/bash" > "$1"
1027 [[ $quiet ]] || g "$1"
1032 [[ ${#@} == 2 ]] || { echo "error: ediff requires 2 arguments"; return 1; }
1033 emacs --eval "(ediff-files \"$1\" \"$2\")"
1036 tx() { # toggle set -x, and the prompt so it doesn't spam
1037 if [[ $- == *x* ]]; then
1039 PROMPT_COMMAND=prompt_command
1041 unset PROMPT_COMMAND
1048 dat() { # do all tee, for more complex scripts
1049 tee >(ssh frodo bash -l) >(bash -l) >(ssh x2 bash -l) >(ssh tp bash -l)
1054 for host in x2 tp treetowl; do
1062 grep -Il "" "$@" &>/dev/null
1065 if [[ $OS == Windows_NT ]]; then
1076 (( ${#x[#]} > 1 )) && { echo "warning ${#x[#]} matches found"; sleep 1; }
1081 if type gvfs-open &> /dev/null ; then
1086 # another alternative is run-mailcap
1090 khfix() { # known hosts fix
1093 ssh-keygen -R ${x##* }
1099 complete -F _longopt la lower low rlt rld rl lld ts ll dircp ex fcp fct fpst gr
1103 hl() { # history limit. Write extra history to archive file.
1104 local max_lines linecount tempfile prune_lines x
1105 local harchive="${HISTFILE}_archive"
1106 for x in "$HISTFILE" "$harchive"; do
1107 [[ -e $x ]] || { touch "$x" && echo "notice from hl(): creating $x"; }
1108 if [[ ! $x || ! -e $x || ! -w $x || $(stat -c "%u" "$x") != $EUID ]]; then
1109 echo "error in hl: history file \$x:$x no good"
1113 history -a # save history
1114 max_lines=$HISTFILELINES
1115 [[ $max_lines =~ ^[0-9]+$ ]] || { echo "error in hl: failed to get max line count"; return 1; }
1116 linecount=$(wc -l < $HISTFILE) # pipe so it doesn't output a filename
1117 [[ $linecount =~ ^[0-9]+$ ]] || { echo "error in hl: wc failed"; return 1; }
1118 if (($linecount > $max_lines)); then
1119 prune_lines=$(($linecount - $max_lines))
1120 head -n $prune_lines "$HISTFILE" >> "$harchive" \
1121 && sed -ie "1,${prune_lines}d" $HISTFILE
1125 ############## work stuff #############
1128 pushd /sdx/test/sandbox/;
1129 ./setup.sh && ./run.sh
1141 ############# some other section
1142 if [[ $- == *i* ]]; then
1143 # commands to run when bash exits normally
1144 trap "hl; _smh" EXIT
1148 # temporary variables to test colorization
1149 # some copied from gentoo /etc/bash/bashrc,
1151 # dircolors --print-database uses its own built-in database
1152 # instead of using /etc/DIR_COLORS. Try to use the external file
1153 # first to take advantage of user additions.
1154 safe_term=${TERM//[^[:alnum:]]/?} # sanitize TERM
1156 [[ -f ~/.dir_colors ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
1157 [[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
1158 [[ -z ${match_lhs} ]] \
1159 && type -P dircolors >/dev/null \
1160 && match_lhs=$(dircolors --print-database)
1161 # test if our $TERM is in the TERM values in dircolor
1162 [[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true
1165 if ${use_color} && [[ $- == *i* ]]; then
1167 if [[ $XTERM_VERSION == Cygwin* ]]; then
1171 underl) echo -n $'\E[4m' ;;
1172 bold) echo -n $'\E[1m' ;;
1173 red) echo -n $'\E[31m' ;;
1174 green) echo -n $'\E[32m' ;;
1175 blue) echo -n $'\E[34m' ;;
1176 cyan) echo -n $'\E[36m' ;;
1177 yellow) echo -n $'\E[33m' ;;
1178 purple) echo -n $'\E[35m' ;;
1179 nocolor) echo -n $'\E(B\E[m' ;;
1188 underl) echo -n $(tput smul) ;;
1189 bold) echo -n $(tput bold) ;;
1190 red) echo -n $(tput setaf 1) ;;
1191 green) echo -n $(tput setaf 2) ;;
1192 blue) echo -n $(tput setaf 4) ;;
1193 cyan) echo -n $(tput setaf 6) ;;
1194 yellow) echo -n $(tput setaf 3) ;;
1195 purple) echo -n $(tput setaf 5) ;;
1196 nocolor) echo -n $(tput sgr0) ;; # no font attributes
1206 # Try to keep environment pollution down, EPA loves us.
1207 unset safe_term match_lhs use_color
1219 if [[ $- == *i* ]]; then
1220 # git branch/status prompt function
1221 if [[ $OS != Windows_NT ]]; then
1222 GIT_PS1_SHOWDIRTYSTATE=true
1224 # arch source lopip show -fcation
1225 [[ -r /usr/share/git/git-prompt.sh ]] && source /usr/share/git/git-prompt.sh
1226 # fedora/debian source
1227 [[ -r /usr/share/git-core/contrib/completion/git-prompt.sh ]] && source /usr/share/git-core/contrib/completion/git-prompt.sh
1229 # in case we didn't source git-prompt.sh
1230 if ! declare -f __git_ps1 > /dev/null; then
1236 # this needs to come before next ps1 stuff
1237 # this stuff needs bash 4, feb 2009,
1238 # old enough to no longer condition on $BASH_VERSION anymore
1242 if [[ $- == *i* ]] && [[ ! $INSIDE_EMACS ]]; then
1244 bind -m vi-command B:shell-backward-word
1245 bind -m vi-command W:shell-forward-word
1248 if [[ $SSH_CLIENT ]]; then
1253 local return=$? # this MUST COME FIRST
1255 local ps_char ps_color
1257 history -a # save history
1258 if [[ ! $DESKTOP_SESSION == xmonad && $TERM == *(screen*|xterm*|rxvt*) ]]; then
1259 # from the screen man page
1260 if [[ $TERM == screen* ]]; then
1261 local title_escape="\033]..2;"
1263 local title_escape="\033]0;"
1265 echo -ne "$title_escape${PWD/#$HOME/~} $USER@$HOSTNAME\007"
1269 0) ps_color="$(get_term_color blue)"
1272 1) ps_color="$(get_term_color green)"
1273 ps_char="$return \\$"
1275 *) ps_color="$(get_term_color yellow)"
1276 ps_char="$return \\$"
1279 if [[ ! -O . ]]; then # not owner
1280 if [[ -w . ]]; then # writable
1281 ps_color="$(get_term_color bold red)"
1283 ps_color="$(get_term_color bold green)"
1286 PS1="${PS1%"${PS1#*[wW]}"} \[$ps_color\]$ps_char\[$(get_term_color nocolor)\] "
1287 # emacs completion doesn't like the git prompt atm, so disabling it.
1288 #PS1="${PS1%"${PS1#*[wW]}"}$(__git_ps1 ' (%s)') \[$ps_color\]$ps_char\[$(get_term_color nocolor)\] "
1290 PROMPT_COMMAND=prompt_command
1297 ###########################################
1298 # stuff that makes sense to be at the end #
1299 ###########################################
1300 if [[ "$SUDOD" ]]; then
1303 elif [[ -d /a ]] && [[ $PWD == $HOME ]] && [[ $- == *i* ]]; then
1312 # if someone exported $SOE, catch errors
1317 # I'd prefer to have system-wide, plus user ruby, due to bug in it
1318 # https://github.com/rubygems/rubygems/pull/1002
1319 # further problems: installing multi-user ruby and user ruby,
1320 # you don't get multi-user ruby when you sudo to root, unless its sudo -i.
1321 # There a third hybrid form, which passenger error suggested I use,
1322 # but it didn't actually work.
1324 # in cased I never need this
1325 # rvm for non-interactive shell: modified from https://rvm.io/rvm/basics
1326 #if [[ $(type -t rvm) == file && ! $(type -t ruby) ]]; then
1327 # source $(rvm 1.9.3 do rvm env --path)
1330 # based on warning from rvmsudo
1331 export rvmsudo_secure_path=1
1334 if [[ -s "/usr/local/rvm/scripts/rvm" ]]; then
1335 source "/usr/local/rvm/scripts/rvm"
1336 elif [[ -s $HOME/.rvm/scripts/rvm ]]; then
1337 source $HOME/.rvm/scripts/rvm
1340 # https://wiki.archlinux.org/index.php/Xinitrc#Autostart_X_at_login
1341 # i added an extra condition as gentoo xorg guide says depending on
1342 # $DISPLAY is fragile.
1343 if [[ ! $DISPLAY && $XDG_VTNR == 1 ]] && shopt -q login_shell && isarch; then
1346 # ensure no bad programs appending to this file will have an affect