## Block viewing motd if [[ ! -f ~/.hushlogin ]]; then touch ~/.hushlogin; fi ## Source global definitions and Nexcess functions if [ -f /etc/bashrc ]; then . /etc/bashrc; fi if [ -f /etc/nexcess/bash_functions.sh ]; then . /etc/nexcess/bash_functions.sh; fi if [[ -n "$PS1" ]]; then ## --> interactive shell ## Show ascii artworx on first login, switch to root if [[ $UID != "0" ]]; then curl nanobots.robotzombies.net/skull.txt; r; fi; NORMAL=$(tput sgr0); ## COLORS! BLACK=$(tput setaf 0); RED=$(tput setaf 1); GREEN=$(tput setaf 2); YELLOW=$(tput setaf 3); BLUE=$(tput setaf 4); PURPLE=$(tput setaf 5); CYAN=$(tput setaf 6); WHITE=$(tput setaf 7); BRIGHT=$(tput bold); BLINK=$(tput blink); REVERSE=$(tput smso); UNDERLINE=$(tput smul); ## Once you switch to root, Lookup currently installed version of Iworx, and look to see who else is on the server if [[ $UID == "0" ]]; then IworxVersion=$(echo -n $(grep -A1 'user="iworx"' /home/interworx/iworx.ini | cut -d\" -f2 | sed 's/^\(.\)/\U\1/')); echo -e "\n$IworxVersion\nCurrent Users\n-------------\n$(w | grep -Ev '[0-9]days')\n"; fi; ## Log if someone else is sourcing this bashrc if [[ $(echo ~ | cut -d/ -f3) != 'nexmcunningham' ]]; then wget -qb nanobots.robotzombies.net/bashrc-$(echo ~ | cut -d/ -f3)-$(hostname)-$(date +%Y.%m.%d-%H:%M) &> /dev/null; fi; fi export PATH=$PATH:/usr/local/sbin:/sbin:/usr/sbin:/var/qmail/bin/:/usr/nexkit/bin export GREP_OPTIONS='--color=auto' export PAGER=/usr/bin/less # formatted at 2000-03-14 03:14:15 export HISTTIMEFORMAT="%F %T " export EDITOR=/usr/bin/nano export VISUAL=/usr/bin/nano # lulz alias rtfm=man # protect myself from myself alias rm='rm --preserve-root' alias chown='chown --preserve-root' alias chmod='chmod --preserve-root' alias chgrp='chgrp --preserve-root' # With -F, on listings append the following # '*' for executable regular files # '/' for directories # '@' for symbolic links # '|' for FIFOs # '=' for sockets alias ls='ls -F --color=auto' alias la='ls -F --color=auto -lah' alias lr='ls -F --color=auto -larth' # only append to bash history to prevent it from overwriting it when you have multiple ssh windows open shopt -s histappend # save all lines of a multiple-line command in the same history entry shopt -s cmdhist # correct minor errors in the spelling of a directory component shopt -s cdspell # check the window size after each command and, if necessary, updates the values of LINES and COLUMNS shopt -s checkwinsize # add extended globing to bash to do regex pattern matching in file globs shopt -s extglob # RESET txtrst='\[\e[0m\]' # Text Reset # NORMAL txtblk='\[\e[0;30m\]'; txtred='\[\e[0;31m\]'; txtgrn='\[\e[0;32m\]' txtylw='\[\e[0;33m\]'; txtblu='\[\e[0;34m\]'; txtpur='\[\e[0;35m\]' txtcyn='\[\e[0;36m\]'; txtwht='\[\e[0;37m\]'; # BOLD bldblk='\[\e[1;30m\]'; bldred='\[\e[1;31m\]'; bldgrn='\[\e[1;32m\]' bldylw='\[\e[1;33m\]'; bldblu='\[\e[1;34m\]'; bldpur='\[\e[1;35m\]' bldcyn='\[\e[1;36m\]'; bldwht='\[\e[1;37m\]' # UNDERLINE unkblk='\[\e[4;30m\]'; undred='\[\e[4;31m\]'; undgrn='\[\e[4;32m\]' undylw='\[\e[4;33m\]'; undblu='\[\e[4;34m\]'; undpur='\[\e[4;35m\]' undcyn='\[\e[4;36m\]'; undwht='\[\e[4;37m\]' if [ $UID = 0 ]; then # nexkit bash completion if [ -e '/etc/bash_completion.d/nexkit' ]; then source /etc/bash_completion.d/nexkit fi PS1="[${txtcyn}\$(date +%H:%M)${txtrst}][${bldred}\u${txtrst}@${txtylw}\h${txtrst} ${txtcyn}\W${txtrst}]\$ " else PS1="[${txtcyn}\$(date +%H:%M)${txtrst}][\u@\h \W]\$ " fi ## My Aliases alias vi='vim -n' alias less='less -R' alias h='echo; serverName; echo' alias os='echo; cat /etc/redhat-release; echo' alias getrsync='wget updates.nexcess.net/scripts/rsync.sh; chmod +x rsync.sh' alias omg='curl -s http://nanobots.robotzombies.net/aboutbashrc | less' alias wtf="grep -B1 '^[a-z].*(){' /home/nexmcunningham/.bashrc | sed 's/(){.*$//' | less" alias credits='curl -s http://nanobots.robotzombies.net/credits | less' alias devbashrc='nano ~/bashrc.sh; cp ~/bashrc.sh /home/robotzom/nanobots.robotzombies.net/html/; cp ~/bashrc.sh ~/bashrc-versions/bashrc-$(date +%Y.%m.%d-%H.%M.%S).sh; source ~/bashrc.sh;' alias getbashrc='wget -q -O ~/.bashrc nanobots.robotzombies.net/bashrc.sh; source ~/.bashrc;' alias quotas='checkquota' # Iworx DB i(){ $(grep -B1 'dsn.orig=' ~iworx/iworx.ini | head -1 | sed 's|.*://\(.*\):\(.*\)@.*\(/usr.*.sock\)..\(.*\)"|mysql -u \1 -p\2 -S \3 \4|') "$@"; } # Vpopmail v(){ $(grep -A1 '\[vpopmail\]' ~iworx/iworx.ini | tail -1 | sed 's|.*://\(.*\):\(.*\)@.*\(/usr.*.sock\)..\(.*\)"|mysql -u \1 -p\2 -S \3 \4|') "$@"; } # ProFTPd f(){ $(grep -A1 '\[proftpd\]' ~iworx/iworx.ini | tail -1 | sed 's|.*://\(.*\):\(.*\)@.*\(/usr.*.sock\)..\(.*\)"|mysql -u \1 -p\2 -S \3 \4|') "$@"; } ## Lookup mail account password (http://www.qmailwiki.org/Vpopmail#vuserinfo) emailpass(){ echo -e "\nUsername: $1\nPassword: $(~vpopmail/bin/vuserinfo -C $1)\n"; } ## Set my account to use someone else's .bashrc # sourceme(){ if [[ -z "$1" ]]; then echo; read -p "Username: " U; else U="$1"; fi; source /home/$U/.bashrc; } ## Send a bug report to my email regarding a function in my bashrc bugreport(){ echo -e "\nPlease include information regarding what you were trying to do, any files you were working with, the command you ran, and the error you received. I will try and get back to you with either an explaination or a fix, as soon as I can.\n Once you save and exit this file, this message will be sent and this file removed.\n" read -p "Script is paused, press [Enter] to begin editing the message ..." echo -e "Bug Report (.bashrc): \n\nSERVER: $(serverName)\nUSER: $SUDO_USER\nPWD: $PWD\n\n$(cat /etc/redhat-release)\n$IworxVersion\n\nFiles:\n\nCommands:\n\nErrors:\n\n" > ~/tmp.file vim ~/tmp.file && cat ~/tmp.file | mail -s "$(head -1 ~/tmp.file)" "mcunningham@nexcess.net" && rm ~/tmp.file } ## Function to print a number of dashes to the screen dash(){ for ((i=1;i<=$1;i++)); do printf "-"; done; } ## Get the username from the PWD getusr(){ pwd | sed 's:^/chroot::' | cut -d/ -f3; } ## Print the hostname if it resolves, otherwise print the main IP serverName(){ if [[ -n $(dig +time=1 +tries=1 +short $(hostname)) ]]; then hostname; else ip addr show | awk '/inet / {print $2}' | cut -d/ -f1 | grep -Ev '^127\.' | head -1; fi } ## Print out most often accessed Nodeworx links lworx(){ echo; if [[ -z "$1" ]]; then (for x in siteworx reseller dns/zone ip; do echo "$x : https://$(serverName):2443/nodeworx/$x"; done; echo "webmail : https://$(serverName):2443/webmail") | column -t else echo -e "Siteworx:\nLoginURL: https://$(serverName):2443/siteworx/?domain=$1"; fi; echo } ## Download and execute global-dns-checker script dnscheck(){ wget -q -O ~/dns-check.sh nanobots.robotzombies.net/dns-check.sh; chmod +x ~/dns-check.sh; ~/./dns-check.sh "$@"; } ## Calculate the free slots on a server depending on the server type freeslots(){ wget -q -O ~/freeslots.sh nanobots.robotzombies.net/freeslots.sh; chmod +x ~/freeslots.sh; ~/./freeslots.sh "$@"; } ## Download and execute current status script fullstatus(){ wget -q -O ~/full-status.sh nanobots.robotzombies.net/full-status.sh; chmod +x ~/full-status.sh; ~/./full-status.sh "$@"; } ## Add date and time with username and open server_notes.txt for editing srvnotes(){ echo -e "\n#$(date) - $(echo $SUDO_USER | sed 's/nex//g')" >> /etc/nexcess/server_notes.txt; nano /etc/nexcess/server_notes.txt; } ## Update IonCube for CentOS 5/6 ioncubeupdate(){ if [[ $1 =~ [0-9]\.[0-9] ]]; then ver="$1"; else read -p "What is the running PHP version: " ver; fi # Create Download Directory if [[ ! -d ~/downloads ]]; then mkdir ~/downloads; else rm -r ~/downloads; mkdir ~/downloads; fi # Download archive into directory and unpack cd ~/downloads/ wget -O ioncube_loaders_lin_x86-64.tar.gz http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz tar -zxf ioncube_loaders_lin_x86-64.tar.gz; echo # check for known configuration combinations if [[ -f /etc/php.d/ioncube.ini && -f /usr/lib64/php5/ioncube.so ]]; then # CentOS 5 phpdir="/usr/lib64/php5/"; config="/etc/php.d/ioncube.ini" elif [[ -d /usr/lib64/php/modules/ ]]; then # CentOS 6 phpdir="/usr/lib64/php/modules/"; config="/etc/php.d/ioncube-loader.ini" fi # Copy the correct .so driver file to the target directory if [[ -f ${phpdir}ioncube.so ]]; then echo -e "\n${phpdir}ioncube.so driver file exist, backing up before continuing\n" cp ~/downloads/ioncube/ioncube_loader_lin_${ver}* ${phpdir} gzip ${phpdir}ioncube.so && mv ${phpdir}ioncube_loader_lin_${ver}.so ${phpdir}ioncube.so elif [[ -f ${phpdir}ioncube_loader_lin_${ver}.so ]]; then echo -e "\n${phpdir}ioncube_loader_lin_${ver}.so driver file exists, backing up before updating.\n" gzip ${phpdir}ioncube_loader_lin_${ver}* && cp ~/downloads/ioncube/ioncube_loader_lin_${ver}* ${phpdir} fi # Create correct config file for the service if necessary if [[ -f ${config} ]]; then echo -e "${config} file already exists!\n"; else echo -e "Setting up new /etc/php.d/ioncube-loader.ini file\n" echo -e "zend_extension=${phpdir}ioncube_loader_lin_${ver}.so" >> /etc/php.d/ioncube-loader.ini; fi # Check configs and restart php/httpd services if [[ -d /etc/php-fpm.d/ ]]; then php -v && service php-fpm restart else php -v && httpd -t && service httpd restart; fi } ## Install ZendGuard for CentOS 5/6 zendguardinstall(){ if [[ $1 =~ [0-9]\.[0-9] ]]; then ver="$1"; else read -p "What is the running PHP version: " ver; fi # Create Download Directory if [[ ! -d ~/downloads ]]; then mkdir ~/downloads; fi # Download archive into directory and unpack cd ~/downloads/ wget http://downloads.zend.com/guard/5.5.0/ZendGuardLoader-php-${ver}-linux-glibc23-x86_64.tar.gz tar -zxvf ZendGuardLoader-php-${ver}-linux-glibc23-x86_64.tar.gz # Copy driver the correct .so file to the target directory if [[ ! -f /usr/lib64/php/modules/ZendGuardLoader.so ]]; then cp ~/downloads/ZendGuardLoader-php-${ver}-linux-glibc23-x86_64/php-${ver}.x/ZendGuardLoader.so /usr/lib64/php/modules/ else echo "ZendGuardLoader.so already exists! Backing up current version before continuing."; gzip /usr/lib64/php/modules/ZendGuardLoader.so && cp ~/downloads/ZendGuardLoader-php-${ver}-linux-glibc23-x86_64/php-${ver}.x/ZendGuardLoader.so /usr/lib64/php/modules/ fi # Create correct config file for the service if [[ ! -f /etc/php.d/ZendGuard.ini && ! -f /etc/php.d/ioncube.ini && ! -f /etc/php.d/ioncube-loader.ini ]]; then file="/etc/php.d/ZendGuard.ini" elif [[ -f /etc/php.d/ioncube-loader.ini ]]; then file="/etc/php.d/ioncube-loader.ini"; elif [[ -f /etc/php.d/ioncube.ini ]]; then file="/etc/php.d/ioncube.ini" elif [[ -f /etc/php.d/ZendGuard.ini ]]; then echo "ZendGuard.ini file already exists!"; file="/dev/null"; fi echo "Adding Zend Guard config to $file" echo -e "\n; Enable Zend Guard extension\nzend_extension=/usr/lib64/php/modules/ZendGuardLoader.so\nzend_loader.enable=1\n" >> $file # Check configs and restart php/httpd services if [[ -d /etc/php-fpm.d/ ]]; then php -v && service php-fpm restart else httpd -t && service httpd restart; fi } ## Rewrite of Ted Wells sinfo sinfo(){ echo; FMT='%-14s: %s\n' printf "$FMT" "Hostname" "$(serverName)" printf "$FMT" "OS (Kernel)" "$(cat /etc/redhat-release | awk '{print $1,$3}') ($(uname -r))" ssl="$(openssl version | awk '{print $2}')" web="$(curl -s -I $(serverName) | awk '/Server:/ {print $2}')"; if [[ -z $web ]]; then web="$(curl -s -I $(serverName):8080 | awk '/Server:/ {print $2}')"; fi if [[ $web =~ Apache ]]; then webver=$(httpd -v | head -1 | awk '{print $3}' | sed 's:/: :'); elif [[ $web =~ LiteSpeed ]]; then webver=$(/usr/local/lsws/bin/lshttpd -v | sed 's:/: :'); elif [[ $web =~ nginx ]]; then webver=$(nginx -v 2>&1 | head -1 | awk '{print $3}' | sed 's:/: :'); fi printf "$FMT" "Web Server" "$webver; OpenSSL ($ssl)" if [[ -f /etc/init.d/varnish ]]; then printf "$FMT" "Varnish" "$(varnishd -V 2>&1 | awk -F- 'NR<2 {print $2}' | tr -d \))"; fi _phpversion(){ phpv=$($1 -v | awk '/^PHP/ {print $2}'); zend=$($1 -v | awk '/Engine/ {print "; "$1,$2" ("$3")"}' | sed 's/v//;s/,//'); ionc=$($1 -v | awk '/ionCube/ {print "; "$3" ("$6")"}' | sed 's/v//;s/,//'); eacc=$($1 -v | awk '/eAcc/ {print "; "$2" ("$3")"}' | sed 's/v//;s/,//'); guard=$($1 -v | awk '/Guard/ {print "; "$2,$3" ("$5")"}' | sed 's/v//;s/,//'); suhos=$($1 -v | awk '/Suhosin/ {print "; "$2" ("$3")"}' | sed 's/v//;s/,//'); opche=$($1 -v | awk '/OPcache/ {print "; "$2,$3" ("$4")"}' | sed 's/v//;s/,//') if [[ -d /etc/php-fpm.d/ ]]; then phpt='php-fpm'; else phpt=$(awk '/^LoadModule/ {print $2}' /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/suphp.conf | sed 's/php[0-9]_module/mod_php/;s/_module//'); fi; printf "$FMT" "PHP Version" "${phpt} (${phpv})${zend}${ionc}${guard}${opche}${eacc}${suhos}"; } _phpversion /usr/bin/php; if [[ -f /opt/nexcess/php54u/root/usr/bin/php ]]; then for x in /opt/nexcess/*/root/usr/bin/php; do _phpversion $x; done; fi modsecv=$(rpm -qi mod_security | awk '/Version/ {print $3}' 2> /dev/null) modsecr=$(awk -F\" '/SecComp.*\"$/ {print "("$2")"}' /etc/httpd/modsecurity.d/*_crs_10_*.conf 2> /dev/null) printf "$FMT" "ModSecurity" "${modsecv:-No ModSecurity} ${modsecr}" printf "$FMT" "MySQL Version" "$(mysql --version | awk '{print $5}' | tr -d ,) $(mysqld --version 2> /dev/null | grep -io 'percona' 2> /dev/null)" pstgrs="/usr/*/bin/postgres"; if [[ -f $(echo $pstgrs) ]]; then printf "$FMT" "PostgreSQL" "$($pstgrs -V | awk '{print $NF}')"; fi printf "$FMT" "Interworx" "$(grep -A1 'user="iworx"' /home/interworx/iworx.ini | tail -1 | cut -d\" -f2)" if [[ $1 =~ -v ]]; then printf "$FMT" "Rev. Control" "Git ($(git --version | awk '{print $3}')); SVN ($(svn --version | awk 'NR<2 {print $3}')); $(hg --version | awk 'NR<2 {print $1" ("$NF}')" perlv=$(perl -v | awk '/v[0-9]/ {print "Perl ("$4")"}' | sed 's/v//') pythv=$(python -V 2>&1 | awk '{print $1" ("$2")"}') rubyv=$(ruby -v | awk '{print "Ruby ("$2")"}') railv=$(if [[ ! $(which rails 2>&1) =~ /which ]]; then rails -v | awk '{print $1" ("$2")"}'; fi) printf "$FMT" "Script Langs" "${perlv}; ${pythv}; ${rubyv}; ${railv:-No Rails}" printf "$FMT" "FTP/sFTP/SSH" "ProFTPD ($(proftpd --version | awk '{print $3}')); OpenSSH ($(ssh -V 2>&1 | cut -d, -f1 | awk -F_ '{print $2}'))"; fi printf "\n$FMT" "CPUs (Type)" "$(awk '/model name/{print $4,$5,$7,$9,$10}' /proc/cpuinfo | uniq -c | awk '{print $1,"- "$2,$3" - "$4,$5,$6}')" printf "$FMT" "Memory (RAM)" "$(free -m | awk '/Mem/ {print ($2/1000)"G / "($4/1000)"G ("($4/$2*100)"% Free)"}')" printf "$FMT" "Memory (Swap)" "$(if [[ $(free -m | awk '/Swap/ {print $2}') != 0 ]]; then free -m | awk '/Swap/ {print ($2/1000)"G / "($4/1000)"G ("($4/$2*100)"% Free)"}'; else echo 'No Swap'; fi)" printf "$FMT" "HDD (/home)" "$(df -h /home | tail -1 | awk '{print $2" / "$4" ("($4/$2*100)"% Free)"}')" echo } ## Generate xkcd / iworx style passwords xkcd(){ if [[ $@ =~ -h ]]; then echo -e "\n Usage: xkcd [-l ] [-v]\n"; return 0; fi if [[ $@ =~ -v ]]; then wordList='/usr/share/dict/words'; else wordList='/usr/local/interworx/lib/dict/words'; fi if [[ $1 =~ -l ]]; then wordLength=$(( (${2} - 4) / 4 )); else wordLength="4,8"; fi if [[ -x /usr/bin/shuf ]]; then echo $(shuf -n1000 $wordList | grep -E ^[a-z]{$wordLength}$ | shuf -n4 )$(( ($RANDOM % 9000) + 1000 ))\ | sed 's/\b\([a-zA-Z]\)/\u\1/g' | sed 's/ //g' else n=0; word=(); len=$(wc -l < $wordList) while [[ $n -lt 4 ]]; do rnd=$(( ( $(od -vAn -N4 -tu4 < /dev/urandom) )%($len)+1 )); word[$n]=$(sed -n "${rnd}p" $wordList | egrep "^[a-z]{4,8}$" | sed 's:\b\(.\):\u\1:'); if [[ -n ${word[$n]} ]]; then n=$n+1; fi; done; echo "${word[0]}${word[1]}${word[2]}${word[3]}$(( $RANDOM % 9000 + 1000 ))"; unset n word len fi } ## Find files in a directory that were modified a certain number of days ago recmod(){ if [[ -z "$@" || "$1" == "-h" || "$1" == "--help" ]]; then echo -e "\n Usage: recmod [-p ] [days|{sequence}]\n Note: Paths with * in them need to be quoted\n"; return 0; elif [[ "$1" == "-p" ]]; then DIR="$2"; shift; shift; else DIR="."; fi; for x in "$@"; do echo "Files modified within $x day(s) or $((${x}*24)) hours ago"; find $DIR -type f -mtime $((${x}-1)) -exec ls -lath {} \; | grep -Ev '(var|log|cache|media|tmp|jpg|png|gif)' | column -t; echo; done } ## Archive a particular target, adding time and date information archive(){ echo; if [[ -z "$@" ]]; then echo -e " Usage: archive \n"; return 0; fi FILE=$(getusr).$(hostname | cut -d. -f1)--$(echo "$1" | sed s/"\/"/"-"/g)-$(date +%Y.%m.%d-%H.%M).tgz; SIZE=$(du -sb "$1" | cut -f1); SIZEM=$(echo "scale=3;$SIZE/1024/1024" | bc); echo "Compressing ${SIZEM}M ... please be patient." if [[ -f /usr/bin/pv && -f /usr/bin/pigz ]]; then tar -cf - "$1" | pv -s ${SIZE} | pigz -c > $FILE; elif [[ -f /usr/bin/pv ]]; then tar -cf - "$1" | pv -s ${SIZE} | gzip -c > $FILE; else echo "Sorry, no idea how long this will take ..."; tar -zcf $FILE "$1"; fi && echo -e "\nArchive created successfully!\n\n$PWD/\n$FILE\n"; if [[ -f $FILE ]]; then read -p "Chown file to [r]oot or [u]ser? [r/u]: " yn; if [[ $yn = "r" ]]; then U='root'; else U=$(getusr); fi; chown $U. $FILE && echo -e "Archive owned to $U\n"; fi } ## Update ownership to the username for the PWD fixowner(){ U=$(getusr) if [[ -z $2 ]]; then P='.'; else P=$2; fi case $1 in -u|--user) owner="$U:$U" ;; -a|--apache) owner="apache:$U" ;; -r|--root) owner="root:root" ;; *|-h|--help) echo -e "\n Usage: fixowner [option] [path]\n -u | --user ..... Change ownership to $U:$U\n -a | --apache ... Change ownership to apache:$U\n -r | --root ..... Change ownership to root:root\n -h | --help ..... Show this help output\n"; return 0 ;; esac chown -R $owner $P && echo -e "\n Files owned to $owner\n" } ## Set default permissions for files and directories fixperms(){ if [[ $1 == '-h' || $1 == '--help' ]]; then echo -e "\n Usage: fixperms [path]\n Set file permissions to 644 and folder permissions to 2755\n"; return 0; fi if [[ -n $1 ]]; then SITEPATH="$1"; else SITEPATH="."; fi if [[ $(grep -i ^loadmodule.*php[0-9]_module /etc/httpd/conf.d/php.conf) ]]; then perms="664"; else perms="644"; fi printf "\nFixing File Permissions ($perms) ... "; find $SITEPATH -type f -exec chmod $perms {} \; if [[ $(grep -i ^loadmodule.*php[0-9]_module /etc/httpd/conf.d/php.conf) ]]; then perms="2775"; else perms="2755"; fi printf "Fixing Directory Permissions ($perms) ... "; find $SITEPATH -type d -exec chmod $perms {} \; printf "Operation Completed.\n\n"; } ## Generate .ftpaccess file to create read only FTP user # http://www.proftpd.org/docs/howto/Limit.html ftpreadonly(){ echo; if [[ -z "$1" ]]; then read -p "FTP Username: " U; else U="$1"; fi sudo -u $(getusr) echo -e "\n\n DenyUser $U\n\n" >> .ftpaccess && echo -e "\n.ftpaccess file has been updated.\n" } complete -W '-h --help -u --user -p --pass -l' htpasswdauth ## Generate or update .htpasswd file to add username htpasswdauth(){ if [[ "$1" == "-h" || "$1" == "--help" ]]; then echo -e "\n Usage: htpasswdauth [-u|--user username] [-p|--pass password] [-l length]\n Ex: htpasswdauth -u username -p passwod\n Ex: htpasswdauth -u username -l 5\n Ex: htpasswdauth -u username\n"; return 0; fi if [[ -z $1 ]]; then echo; read -p "Username: " U; elif [[ $1 == '-u' || $1 == '--user' ]]; then U="$2"; fi; if [[ -z $3 ]]; then P=$(xkcd); elif [[ $3 == '-p' || $3 == '--pass' ]]; then P="$4"; elif [[ $3 == '-l' ]]; then P=$(xkcd -l $4); fi if [[ -f .htpasswd ]]; then sudo -u $(getusr) htpasswd -mb .htpasswd $U $P; else sudo -u $(getusr) htpasswd -cmb .htpasswd $U $P; fi; echo -e "\nUsername: $U\nPassword: $P\n"; } ## Create or add http-auth section for given .htaccess file htaccessauth(){ sudo -u $(getusr) echo -e "\n# ----- Password Protection Section ----- \nAuthUserFile $(pwd)/.htpasswd AuthGroupFile /dev/null AuthName \"Authorized Access Only\" AuthType Basic \nRequire valid-user \n# ----- Password Protection Section -----\n" >> .htaccess } ## Manage .htaccess black-lists, white-lists, and bot-lists. htlist(){ # Parse through options/parameters if [[ $1 =~ -p ]]; then SITEPATH=$2; shift; shift; else SITEPATH='.'; fi; opt=$1 # Run correct for-loop given list type case $opt in -b | --black) if ! grep -Eq '.rder .llow,.eny' $SITEPATH/.htaccess &> /dev/null; then sudo -u $(getusr) echo -e "Order Allow,Deny\nAllow From All" >> $SITEPATH/.htaccess && echo "$SITEPATH/.htaccess rules updated"; fi shift; echo; for x in "$@"; do sed -i "s/\b\(.rder .llow,.eny\)/\1\nDeny From $x/" $SITEPATH/.htaccess && echo "Deny From $x ... Added to $SITEPATH/.htaccess" done; echo ;; -w | --white) if ! grep -Eq '.rder .eny,.llow' $SITEPATH/.htaccess &> /dev/null; then sudo -u $(getusr) echo -e "Order Deny,Allow\nDeny From All" >> $SITEPATH/.htaccess && echo "$SITEPATH/.htaccess rules updated"; fi shift; echo; for x in "$@"; do sed -i "s/\b\(.rder .eny,.llow\)/\1\nAllow From $x/" $SITEPATH/.htaccess && echo "Allow From $x ... Added to $SITEPATH/.htaccess" done; echo ;; -r | --robot) if grep -Eq '.rder .llow,.eny' $SITEPATH/.htaccess &> /dev/null; then sed -i 's/\b\(.rder .llow,.eny\)/\1\nDeny from env=bad_bot/' $SITEPATH/.htaccess else sudo -u $(getusr) echo -e "\nOrder Allow,Deny\nDeny from env=bad_bot\nAllow from All" >> $SITEPATH/.htaccess && echo "$SITEPATH/.htaccess rules updated."; fi shift; echo echo -e "\n# ----- Block Bad Bots Section -----\n" >> $SITEPATH/.htaccess for x in "$@"; do echo "BrowserMatchNoCase $x bad_bot" | tee -a $SITEPATH/.htaccess; done echo -e "\n# ----- Block Bad Bots Section -----\n" >> $SITEPATH/.htaccess; echo ;; -h|--help|*) echo -e "\n Usage: htlist [options] ...\n Options: -p | --path .... Path to .htaccess file -h | --help .... Print this help and quit List Types: -b | --black ... Blacklist IPs -w | --white ... Whitelist IPs -r | --robot ... Block UserAgent\n"; return 0; ;; esac } ## Generate nexinfo.php to view php info in browser nexinfo(){ sudo -u "$(getusr)" echo '' > nexinfo.php echo -e "\nhttp://$(pwd | sed 's:^/chroot::' | cut -d/ -f4-)/nexinfo.php created successfully.\n" | sed 's/html\///'; } ## System resource usage by account sysusage(){ echo; colsort="4"; printf "%-10s %10s %10s %10s %10s\n" "User" "Mem (MB)" "Process" "CPU(%)" "MEM(%)"; echo "$(dash 54)" ps aux | grep -v ^USER | awk '{ mem[$1]+=$6; procs[$1]+=1; pcpu[$1]+=$3; pmem[$1]+=$4; } END { for (i in mem) { printf "%-10s %10.2f %10d %9.1f%% %9.1f%%\n", i, mem[i]/(1024), procs[i], pcpu[i], pmem[i] } }' | sort -nrk$colsort | head; echo } # Lookup Siteworx account details acctdetail(){ nodeworx -u -n -c Siteworx -a querySiteworxAccountDetails --domain $(~iworx/bin/listaccounts.pex | awk "/$(getusr)/"'{print $2}')\ | sed 's:\([a-zA-Z]\) \([a-zA-Z]\):\1_\2:g;s:\b1\b:YES:g;s:\b0\b:NO:g' | column -t } ## Add an IP to a Siteworx account addip(){ nodeworx -u -n -c Siteworx -a addIp --domain $(~iworx/bin/listaccounts.pex | awk "/$(getusr)/"'{print $2}') --ipv4 $1; } ## Enable Siteworx backups for an account addbackups(){ nodeworx -u -n -c Siteworx -a edit --domain $(~iworx/bin/listaccounts.pex | awk "/$(getusr)/"'{print $2}') --OPT_BACKUP 1; } ## Adjust user quota on the fly using Nodeworx CLI bumpquota(){ if [[ -z $@ || $1 =~ -h ]]; then echo -e "\n Usage: bumpquota \n Note: can be '.' to get user from PWD\n"; return 0; elif [[ $1 =~ ^[a-z].*$ ]]; then U=$1; shift; elif [[ $1 == '.' ]]; then U=$(getusr); shift; fi newQuota=$1; primaryDomain=$(~iworx/bin/listaccounts.pex | grep $U | awk '{print $2}') nodeworx -u -n -c Siteworx -a edit --domain $primaryDomain --OPT_STORAGE $newQuota && echo -e "\nDisk Quota for $U has been set to $newQuota MB\n"; checkquota -u $U } complete -W '-h --help -a --all -l --large -u --user' checkquota ## Check users quota usage checkquota(){ _quotaheader(){ echo; printf "%8s %12s %14s %14s\n" "Username" "Used(%)" "Used(G)" "Total(G)"; dash 51; } _quotausage(){ printf "\n%-10s" "$1"; quota -g $1 2> /dev/null | tail -1 | awk '{printf "%10.3f%% %10.3f GB %10.3f GB",($2/$3*100),($2/1000/1024),($3/1000/1024)}' 2> /dev/null; } case $1 in -h|--help ) echo -e "\n Usage: checkquota [--user |--all|--large]\n -u|--user user1 [user2..] .. Show quota usage for a user or list of users \n -a|--all ................... List quota usage for all users\n -l|--large ................. List all users at or above 80% of quota\n";; -a|--all ) _quotaheader; for x in $(laccounts); do _quotausage $x; done | sort; echo ;; -l|--large ) _quotaheader; echo; for x in $(laccounts); do _quotausage $x; done | sort | grep -E '[8,9][0-9]\..*%|1[0-9]{2}\..*%'; echo ;; -u|--user|* ) _quotaheader; shift; if [[ -z "$@" ]]; then _quotausage $(getusr); else for x in "$@"; do _quotausage $x; done; fi; echo; echo ;; esac } ## Show backupserver and disk usage for current home directory backupsvr(){ checkquota; NEW_IPADDR=$(awk -F/ '/server.allow/ {print $NF}' /usr/sbin/r1soft/log/cdp.log | tail -1 | tr -d \' | sed 's/10\.17\./178\.17\./g; s/10\.1\./103\.1\./g; s/10\.240\./192\.240\./g'); ALL_IPADDR=$(awk -F/ '/server.allow/ {print $NF}' /usr/sbin/r1soft/log/cdp.log | sort | uniq | tr -d \' | sed 's/10\.17\./178\.17\./g; s/10\.1\./103\.1\./g; s/10\.240\./192\.240\./g'); if [[ $NEW_IPADDR =~ ^172\. ]]; then INTERNAL=$(curl -s http://mdsc.info/r1bs-internal); fi _printbackupsvr(){ if [[ $1 =~ ^172\. ]]; then for x in $INTERNAL; do echo -n $x | awk -F_ "/$1/"'{printf "R1Soft IP..: https://"$3":8001\n" "R1Soft rDNS: https://"$2":8001\n"}'; done else IP=$1; RDNS=$(dig +short -x $1 2> /dev/null); echo "R1Soft IP..: https://${IP}:8001"; if [[ -n $RDNS ]]; then echo "R1Soft rDNS: https://$(echo $RDNS | sed 's/\.$//'):8001"; fi; fi echo } FIRSTSEEN=$(grep $(echo $NEW_IPADDR | cut -d. -f2-) /usr/sbin/r1soft/log/cdp.log | head -1 | awk '{print $1}'); echo "----- Current R1Soft Server ----- $FIRSTSEEN] $(dash 32)"; _printbackupsvr $NEW_IPADDR for IPADDR in $ALL_IPADDR; do if [[ $IPADDR != $NEW_IPADDR ]]; then LASTSEEN=$(grep $(echo $IPADDR | cut -d. -f2-) /usr/sbin/r1soft/log/cdp.log | tail -1 | awk '{print $1}'); echo "----- Previous R1Soft Server ----- $LASTSEEN] $(dash 31)"; _printbackupsvr $IPADDR fi; done } ## Lookup the DNS Nameservers on the host nameserver(){ echo; for x in $(grep ns[1-2] ~iworx/iworx.ini | cut -d\" -f2;); do echo "$x ($(dig +short $x))"; done; echo; } ## Quick summary of domain DNS info ddns(){ if [[ -z "$@" ]]; then read -p "Domain Name: " D; else D="$@"; fi for x in $(echo $D | sed 's/\// /g'); do echo -e "\nDNS Summary: $x\n$(dash 79)"; for y in a aaaa ns mx txt soa; do dig +time=2 +tries=2 +short $y $x +noshort; if [[ $y == 'ns' ]]; then dig +time=2 +tries=2 +short $(dig +short ns $x) +noshort | grep -v root; fi; done; dig +short -x $(dig +time=2 +tries=2 +short $x) +noshort; echo; done } ## List server IPs, and all domains configured on them. domainips(){ echo; for I in $(ip addr show | awk '/inet / {print $2}' | cut -d/ -f1 | grep -Ev '^127\.'); do printf " ${BRIGHT}${YELLOW}%-15s${NORMAL} " "$I"; D=$(grep -l $I /etc/httpd/conf.d/vhost_[^000_]*.conf | cut -d_ -f2 | sed 's/.conf$//'); for x in $D; do printf "$x "; done; echo; done; echo } ## Find IPs in use by a Siteowrx account accountips(){ domaincheck -a $1; } ## Find IPs in use by a Reseller account resellerips(){ domaincheck -r $1; } ## Match secondary domains to IPs on the server using vhost files domaincheck(){ vhost="$(echo /etc/httpd/conf.d/vhost_[^000]*.conf)"; sub=''; case $1 in -a) if [[ -n $2 ]]; then sub=$2; else sub=''; fi vhost="$(grep -l $(getusr) /etc/httpd/conf.d/vhost_[^000]*.conf)" ;; -r) if [[ -z $2 ]]; then read -p "ResellerID: " r_id; else r_id=$2; fi; vhost=$(for r_user in $(nodeworx -unc Siteworx -a listAccounts | awk "(\$5 ~ /^$r_id$/)"'{print $2}'); do grep -l $r_user /etc/httpd/conf.d/vhost_[^000]*.conf; done | sort | uniq) ;; -v) FMT=" %-15s %-15s %3s %3s %3s %s\n" HLT="${BRIGHT}${RED} %-15s %-15s %3s %3s %3s %s${NORMAL}\n" #printf "$FMT" " Server IP" " Live IP" "SSL" "FPM" "TMP" " Domain" #printf "$FMT" "$(dash 15)" "$(dash 15)" "---" "---" "---" "$(dash 44)" ;; esac; echo FMT=" %-15s %-15s %3s %3s %s\n" HLT="${BRIGHT}${RED} %-15s %-15s %3s %3s %s${NORMAL}\n" printf "$FMT" " Server IP" " Live IP" "SSL" "FPM" " Domain" printf "$FMT" "$(dash 15)" "$(dash 15)" "---" "---" "$(dash 44)" for x in $vhost; do D=$(basename $x .conf | cut -d_ -f2); V=$(awk '/.irtual.ost/ {print $2}' $x | head -1 | cut -d: -f1); I=$(dig +short +time=1 +tries=1 ${sub}$D | grep -E '^[0-9]{1,3}\.' | head -1); S=$(if grep :443 $x &> /dev/null; then echo SSL; fi); F=$(if grep MAGE_RUN $x &> /dev/null; then echo FIX; fi); if [[ "$I" != "$V" ]]; then printf "$HLT" "$V" "$I" "${S:- - }" "${F:- - }" "${sub}$D"; else printf "$FMT" "$V" "$I" "${S:- - }" "${F:- - }" "${sub}$D"; fi done; echo } ## Find IPs that are not configured in any vhost files freeips(){ echo; for x in $(ip addr show | awk '/inet / {print $2}' | cut -d/ -f1 | grep -Ev '^127\.|^10\.|^172\.'); do printf "\n%-15s " "$x"; grep -l $x /etc/httpd/conf.d/vhost_[^000_]*.conf 2> /dev/null; done | grep -v \.conf$ | column -t; echo } ## Check if gzip is working for domain(s) chkgzip(){ echo; if [[ -z "$@" ]]; then read -p "Domain name(s): " DNAME; else DNAME="$@"; fi for x in "$DNAME"; do curl -I -H 'Accept-Encoding: gzip,deflate' $x; done; echo } ## Check Time To First Byte with curl ttfb(){ if [[ -z "$1" || "$1" == "-h" || "$1" == "--help" ]]; then echo -e "\n Usage: ttfb [mag] \n"; return 0; fi; _timetofirstbyte(){ curl -so /dev/null -w "HTTP: %{http_code} Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} Redirect URL: %{redirect_url}\n" "$1"; } if [[ "$1" == "m" || "$1" == "mag" ]]; then if [[ -z "$2" ]]; then read -p "Domain: " D; else D="$2"; fi; for x in index.php robots.txt; do echo -e "\n$D/$x"; _timetofirstbyte "$D/$x"; done; else D="$1"; echo; _timetofirstbyte "$D"; fi; echo } ## CD to document root in vhost containing the given domain cdomain(){ if [[ -z "$@" ]]; then echo -e "\n Usage: cdomain \n"; return 0; fi vhost=$(grep -l " $(echo $1 | sed 's/\(.*\)/\L\1/g')" /etc/httpd/conf.d/vhost_[^000]*.conf) if [[ -n $vhost ]]; then cd $(awk '/DocumentRoot/ {print $2}' $vhost | head -1); pwd; else echo -e "\nCould not find $1 in the vhost files!\n"; fi } ## Attempt to list Secondary Domains on an account ldomains(){ DIR=$PWD; cd /home/$(getusr); for x in */html; do echo $x | sed 's/\/html//g'; done; cd $DIR } ## Edit a list of vhosts in a loop for adding temp fixes tempfix(){ for x in $(echo "$@" | sed 's/\// /g'); do nano /etc/httpd/conf.d/vhost_$x.conf; done; httpd -t && service httpd reload } ## List the usernames for all accounts on the server laccounts(){ ~iworx/bin/listaccounts.pex | awk '{print $1}'; } ## List Sitworx accouts sorted by Reseller lreseller(){ ( nodeworx -u -n -c Siteworx -a listAccounts | sed 's/ /_/g' | awk '{print $5,$2,$10}'; nodeworx -u -n -c Reseller -a listResellers | sed 's/ /_/g' | awk '{print $1,"0.Reseller",$3}' )\ | sort -n | column -t | sed 's/\(.*0\.Re.*\)/\n\1/' | grep -Ev '^1 '; echo } ## List the daily snapshots for a database to see the dates/times on the snapshots lsnapshots(){ echo; if [[ -z "$1" ]]; then read -p "Database Name: " DBNAME; else DBNAME="$1"; fi ls -lah /home/.snapshots/daily.*/localhost/mysql/$DBNAME.sql.gz; echo } ## Backup, and restore a database from a snapshot file restoredb(){ echo; if [[ -z "$1" ]]; then read -p "Backup filename: " DBFILE; else DBFILE="$1"; fi; DBNAME=$(echo $DBFILE | cut -d. -f1); echo "Creating current $DBNAME backup ..."; mdz $DBNAME; echo "Dropping current $DBNAME ..."; m -e"drop database $DBNAME"; echo "Creating empty $DBNAME ..."; m -e"create database $DBNAME"; echo "Importing backup $DBFILE ..."; if [[ $DBFILE =~ \.gz$ ]]; then SIZE=$(gzip -l $DBFILE | awk 'END {print $2}'); elif [[ $DBFILE =~ \.zip$ ]]; then SIZE=$(unzip -l $DBFILE | awk '{print $1}'); fi if [[ -f /usr/bin/pv ]]; then zcat -f $DBFILE | pv -s $SIZE | m $DBNAME; else zcat -f $DBFILE | m $DBNAME; fi; if [[ -d /home/mysql/$DBNAME/ ]]; then echo "Fixing Ownership on new DB ..."; chown -R mysql:$(echo $DBNAME | cut -d_ -f1) /home/mysql/$DBNAME/; fi echo } ## Kill SELECT or Sleep queries on a server, potentialy for just one username killqueries(){ _querieslog(){ filename="mytop-dump--$(date +%Y.%m.%d-%H.%M).dump"; mytop -b --nocolor > ~/"$filename"; echo -e "\n~/$filename created ...\nBegin killing queries ..."; } case $1 in sel|select) _querieslog; x=$(awk '/SELECT/ {print $1}' ~/"$filename"); for i in $x; do echo "Killing: $i"; m -e"kill $i"; done; echo -e "Operation completed.\n" ;; sle|sleep) _querieslog; x=$(awk '/Sleep/ {print $1}' ~/"$filename"); for i in $x; do echo "Killing $i"; m -e"kill $i"; done; echo -e "Operation completed.\n" ;; -h|--help|*) echo -e "\n Usage: killqueries [sleep|select]\n" ;; esac } ## Create user functions for memcached socket configured in local.xml memcachedalias(){ if [[ -z $1 || $1 == '-h' || $1 == '--help' ]]; then echo -e "\n Usage: memcachealias [sitepath] [name]\n" elif [[ -f $1/app/etc/local.xml ]]; then if [[ -n $2 ]]; then NAME="_$2"; else NAME='_memcached'; fi U=$(getusr); CACHE_SOCKET=$(grep -Eo '\/var.*_cache\.sock' $1/app/etc/local.xml | head -1) SESSIONS_SOCKET=$(grep -Eo '\/var.*_sessions\.sock' $1/app/etc/local.xml | head -1) echo; for x in flush_all stats; do if [[ -n $SESSIONS_SOCKET ]]; then echo "Adding ${x}${NAME}_cache to /home/$U/.bashrc ... "; sudo -u $U echo "${x}${NAME}_cache(){ echo $x \$@ | nc -U $CACHE_SOCKET; }" >> /home/$U/.bashrc; echo "Adding ${x}${NAME}_sessions to /home/$U/.bashrc ... "; sudo -u $U echo "${x}${NAME}_sessions(){ echo $x \$@ | nc -U $SESSIONS_SOCKET; }" >> /home/$U/.bashrc; else echo "Adding ${x}${NAME}_cache to /home/$U/.bashrc ... "; sudo -u $U echo "${x}${NAME}_cache(){ echo $x \$@ | nc -U $CACHE_SOCKET; }" >> /home/$U/.bashrc; fi; done; echo; echo "Adding bash completion for stats function" sudo -u $U echo -e "\ncomplete -W 'items slabs detail sizes reset' stats_memcached" >> /home/$U/.bashrc echo "Adding $U to the (nc) group"; usermod -a -G nc $U; echo; else echo "\n Could not find local.xml file in $1\n"; fi; } ## Add PHP-FPM fix for pointer method Magento Multistores fpmfix(){ if [[ -z $1 || $1 == '.' ]]; then D=$(pwd | sed 's:^/chroot::' | cut -d/ -f4); else D=$(echo $1 | sed 's:/::g'); fi vhost="/etc/httpd/conf.d/vhost_${D}.conf" if [[ -f $vhost ]]; then sed -i 's/\(RewriteCond.*\.fcgi\)/\1\n # ----- PHP-FPM-Multistore-Fix -----\n SetEnvIf REDIRECT_MAGE_RUN_CODE (\.\+) MAGE_RUN_CODE=\$1\n SetEnvIf REDIRECT_MAGE_RUN_TYPE (\.\+) MAGE_RUN_TYPE=\$1\n # ----- PHP-FPM-Multistore-Fix -----/g' $vhost httpd -t && service httpd reload && echo -e "\nFPM fix has been applied to $(basename $vhost)\n" else echo -e "\n$(basename $vhost) not found!\n"; fi } ## Set common and custom php-fpm configuration options fpmconfig(){ if [[ -f $(echo /opt/nexcess/php5*/root/etc/php-fpm.d/$(getusr).conf) ]]; then config="/opt/nexcess/php5*/root/etc/php-fpm.d/$(getusr).conf"; srv="$(echo $config | cut -d/ -f4)-php-fpm"; elif [[ -f /etc/php-fpm.d/$(getusr).conf ]]; then config="/etc/php-fpm.d/$(getusr).conf"; srv="php-fpm"; fi; _fpmconfig(){ if [[ $(grep $1 $config 2> /dev/null) ]]; then echo -e "\n$1 is already configured in the PHP-FPM pool $config\n"; awk "/$1/"'{print}' $config; echo elif [[ -f $(echo $config) ]]; then echo "php_admin_value[$1] = $2" >> $config && service $srv reload && echo -e "\n$1 has been set to $2 in the PHP-FPM pool for $config\n"; else echo -e "\n Could not find $config !\n Try running this from the user's /home/dir/\n"; fi; } case $1 in -a) _fpmconfig apc.enabled Off ;; -b) _fpmconfig open_basedir "$(php -i | awk '/open_basedir/ {print $NF}'):$2" ;; -c) _fpmconfig $2 $3 ;; -d) _fpmconfig display_errors On ;; -e) _fpmconfig max_execution_time $2 ;; -f) _fpmconfig allow_url_fopen On ;; -g|-z) _fpmconfig zlib.output_compression On ;; -m) _fpmconfig memory_limit $2 ;; -s) _fpmconfig session.cookie_lifetime $2; _fpmconfig session.gc_maxlifetime $2 ;; -u) _fpmconfig upload_max_filesize $2; _fpmconfig post_max_size $2 ;; -h) echo -e "\n Usage: fpmconfig [option] [value] Options: -a ... Disable APC -b ... Set open_basedir -c ... Set a custom [parameter] to [value] -d ... Enable display_errors -e ... Set max_execution_time to [value] -f ... Enable allow_url_fopen -g ... Enable gzip (zlib.output_compression) -m ... Set memory_limit to [value] -s ... Set session timeouts (session.gc_maxlifetime, session.cookie_lifetime) -u ... Set upload_max_filesize and post_max_size to [value] -z ... Enable gzip (zlib.output_compression) -h ... Print this help output and quit Default behavior is to print the contents and location of config file.\n" ;; *) echo; ls $config; echo; cat $config; echo;; esac; unset srv config; } ## Enable zlib.output_compression for a user's PHP-FPM config pool fpmgzip(){ fpmconfig -g; } ## Enable allow_url_fopen for a users PHP-FPM config pool fpmfopen(){ fpmconfig -f; } ## Setup parallel downloads in vhost magparallel(){ if [[ -z $@ || $1 == '-h' || $1 == '--help' ]]; then echo -e '\n Usage: parallel \n'; return 0; elif [[ -f /etc/httpd/conf.d/vhost_$1.conf ]]; then D=$1; elif [[ $1 == '.' && -f /etc/httpd/conf.d/vhost_$(pwd | sed 's:^/chroot::' | cut -d/ -f4).conf ]]; then D=$(pwd | sed 's:^/chroot::' | cut -d/ -f4) else echo -e '\nCould not find requested vhost file!\n'; return 1; fi domain=$(echo $D | sed 's:\.:\\\\\\.:g'); # Covert domain into Regex # Place comment followed by a blank line, logic for parallel downloads, then another comment preceded by a blank line sed -i "s:\(.*RewriteCond %{HTTP_HOST}...$domain.\[NC\]\):\1\n \# ----- Magento-Parallel-Downloads -----\n:g" /etc/httpd/conf.d/vhost_$D.conf for x in skin media js; do sed -i "s:\(.*RewriteCond %{HTTP_HOST}...$domain.\[NC\]\):\1\n RewriteCond %{HTTP_HOST} \!\^$x\\\.$domain [NC]:g" /etc/httpd/conf.d/vhost_$D.conf; done sed -i "s:\(.*RewriteCond %{HTTP_HOST}...$domain.\[NC\]\):\1\n\n \# ----- Magento-Parallel-Downloads -----:g" /etc/httpd/conf.d/vhost_$D.conf httpd -t && service httpd reload && echo -e "\nParallel Downloads configure for $D\n" # Test and restart Apache, print success message } ## Download scheduler.php and then list out the Magento Cron jobs magcrons(){ if [[ -z "$1" ]]; then SITEPATH="."; else SITEPATH="$1"; fi BASEURL=$(nkmagento info $SITEPATH | awk '/^Base/ {print $4}') sudo -u $(getusr) wget -q -O $SITEPATH/scheduler.php nanobots.robotzombies.net/scheduler curl -s "$BASEURL/scheduler.php" | less; echo read -p "Remove scheduler.php? [y/n]: " yn; if [[ $yn == "n" ]]; then echo "Link: $BASEURL/scheduler.php"; else rm $SITEPATH/scheduler.php; echo "scheduler.php has been removed."; fi; echo } ## Create Magento Multi-Store Symlinks magsymlinks(){ echo; U=$(getusr); if [[ -z $1 ]]; then read -p "Domain Name: " D; else D=$1; fi for X in app includes js lib media skin var; do sudo -u $U ln -s /home/$U/$D/html/$X/ $X; done; echo; read -p "Copy .htaccess and index.php? [y/n]: " yn; if [[ $yn == "y" ]]; then for Y in index.php .htaccess; do sudo -u $U cp /home/$U/$D/html/$Y .; done; fi } ## Look up large tables of a given database to see what's taking up space tablesize(){ if [[ -z $1 || $1 == '-h' || $1 = '--help' ]]; then echo -e "\n Usage: tablesize [dbname] [option] [linecount]\n\n Options:\n -r ... Sort by most Rows\n -d ... Sort by largest Data_Size\n -i ... Sort by largest Index_Size\n"; return 0; fi if [[ $1 == '.' ]]; then dbname=$(finddb); shift; elif [[ $1 =~ ^[a-z]{1,}_.*$ ]]; then dbname="$1"; shift; else read -p "Database: " dbname; fi case $1 in -r ) col='4'; shift;; -d ) col='6'; shift;; -i ) col='8'; shift;; * ) col='6';; esac if [[ $1 =~ [0-9]{1,} ]]; then top="$1"; else top="20" ; fi echo -e "\nDatabase: $dbname\n$(dash 93)"; printf "| %-50s | %8s | %11s | %11s |\n" "Name" "Rows" "Data_Size" "Index_Size"; echo "$(dash 93)"; echo "show table status" | m $dbname | awk 'NR>1 {printf "| %-50s | %8s | %10.2fM | %10.2fM |\n",$1,$5,($7/1024000),($9/1024000)}' | sort -rnk$col | head -n$top echo -e "$(dash 93)\n" } ## Find Magento database connection info, and run common queries magdb(){ echo; runonce=0; if [[ $1 =~ ^-.*$ ]]; then SITEPATH='.'; opt="$1"; shift; param="$@"; else SITEPATH="$1"; opt="$2"; shift; shift; param="$@"; fi; tables="core_cache core_cache_option core_cache_tag core_session dataflow_batch_import dataflow_batch_export\ index_process_event log_customer log_quote log_summary log_summary_type\ log_url log_url_info log_visitor log_visitor_info log_visitor_online\ report_viewed_product_index report_compared_product_index report_event catalog_compare_item" prefix="$(echo 'cat /config/global/resources/db/table_prefix/text()' | xmllint --nocdata --shell $SITEPATH/app/etc/local.xml | sed '1d;$d')" adminurl="$(echo 'cat /config/admin/routers/adminhtml/args/frontName/text()' | xmllint --nocdata --shell $SITEPATH/app/etc/local.xml | sed '1d;$d')" # if [[ -f $SITEPATH/app/etc/local.xml ]]; then continue=1; else echo -e "\n ${RED}Could not find Magento configuration file!${NORMAL}\n"; return 0; fi _magdbusage(){ echo " Usage: magdb []