Archive

Posts Tagged ‘bash’

extended less usage

June 28th, 2011 Comments off

Ever used grep and wanted to check that file with less? Now it is easy with wrapping functions, they parse grep outputted lines.

So lets say we search for info in rvm packages:

grep -rn '__rvm_use(' ~/.rvm/scripts
/home/mpapis/.rvm/scripts/selector:391:__rvm_use()

So now you want to see what is inside of ‘.rvm/scripts/selector’ at line 391

less -N +j391 /home/mpapis/.rvm/scripts/selector

But wouldn’t be nice to just write less, double click the found line and middle click:

less /home/mpapis/.rvm/scripts/selector:391:__rvm_use

This will work when using following function:

less()
{
  local params=() param parsed
  for param in "$@"
  do
    case $param in
    (*:*)
      parsed=( ${param//:/ } )
      params+=( "-N" "+j${parsed[1]}" "${parsed[0]}" )
      ;;
    (*)
      params+=( "$param" )
      ;;
    esac
  done
  command less "${params[@]}"
}

Put the above code into ~/.functions and source it in ~/.bashrc

test -s ~/.functions && . ~/.functions || true

Now restart your shell and enjoy you extended less function.

Categories: Development, Linux Tags: , , ,

linux server memory management

February 27th, 2011 Comments off

It has been long time since last post, but finally something useful shown up, today I want to present simple script for monitoring memory in Linux.

But first happy news: our server is now sucessfully migrated to nginx, no more apache, now maximal memory usage is 20MB per process.

So here is script, it is almost simple, find some processes, and kill them if to much RAM used:

#!/bin/bash

threshold_mb=25
kill_at_mb=$((threshold_mb*5))
memory=$(free -m | awk '{if (FNR==2) print $2}')
threshold=$((threshold_mb*100/memory))
kill_at=$((kill_at_mb*100/memory))
log=/dev/shm/psaux.log
count=$(ps aux | awk -v threshold=$threshold '{if (FNR==1 || $4>=threshold) print}' | tee $log | wc -l)
[ $count -gt 1 ] && echo "Showing processes over ${threshold_mb}MB, killing processes over ${kill_at_mb}MB" && cat $log

cat $log | awk -v kill_at=$kill_at '{if ($4>kill_at) print $2" "$4 }' | while read pid mem;
do
used_mb=$(($(echo $mem | sed 's/\.//')*memory/1000))
# fix rounding problem in awk
if [ $used_mb -gt $kill_at_mb ]; then
kill -9 $pid
echo "pid $pid used ${used_mb}MB - killed"
fi
done
rm -f $log

Most important in this script are first two variables, threshold_mb which is a limit for showing processes (it is rough comparison) and kill_at_mb which is limit for killing processes, by default this limit is 5 times bigger then showing threshold. Cause killing is more important operation additional check for used memory is more strict to be sure, only processes over the limit are killed.

Save it to disk and in crontab:

sudo crontab -e

add the following lines:

MAILTO=<your @email>
* * * * * /root/bin/psaux.sh

That’s all, now add some filter in your mailbox to ignore mails form server – this is all automatic, but you might want to have this for later check if some important processes are missing.

clean linux tmp

November 2nd, 2010 Comments off

Doing some security check on my laptop I found that some files are kept on disk even I do not want to – /tmp directory. Temp is kind of places in system that should not be kept on encrypted partition, so I have decided to use tmpfs. First define an /etc/fstab entry to keep /tmp on tmpfs:

tmpfs /tmp     tmpfs rw,noexec,noatime,mode=1777 0 0
tmpfs /var/tmp tmpfs rw,noexec,noatime,mode=1777 0 0

Clean all data and mount it:

rm -rf /tmp/* /var/tmp/*
mount /tmp
mount /var/tmp

Now your data is kept only till yours computer is restarted. But wait it keeps growing, I restart my laptop once few months, what then? No problem a handy script might be useful, save it as /root/bin/clean_tmp.sh:

#!/bin/bash

: old_minutes:${old_minutes:=60}

list_used()
{
  lsof +D "$1" 2>/dev/null | awk 'NR>1{print $9}'
}

list_old()
{
  find "$1" -type f -amin +$old_minutes 2>/dev/null
}

list_unused_old()
{
  diff <(list_used "$1") <(list_old "$1") | awk '$1==">"{print $2}'
}

list_empty_dirs()
{
  find "$1" -type d -empty
}

clean_all()
{
  typeset _tmp_dir
  for _tmp_dir in "$@"
  do
    list_unused_old "${_tmp_dir}" | xargs rm -fv
    list_empty_dirs "${_tmp_dir}" | xargs rm -fvr
  done
}

clean_all /tmp /var/tmp

What it does? – remove all files older then 60 minutes and not used by any application. Now connect script in root cron (sudo crontab -e):

5 * * * * /root/bin/clean_tmp.sh

Now your temp is secure and clean. You will get list of removed files on your local mail account, to prevent this email remove just v from xargs rm -fv from the script.

Categories: Linux Tags: , , , , , , ,

linux simple router

June 16th, 2010 Comments off

Had you ever need of simple routing, like sharing your connection to other computer?

I had :) so here is a script which turns my laptop into a router, simple configuration, one command, to run it save the script as router.sh

#!/bin/bash

#configuration
IF_LOC=eth0
IP_LOC=192.168.67
IF_NET=wlan0

#script
IF_NET=$(ifconfig $IF_NET | awk ‘/inet/ {print $2}’ | grep -o ‘[0-9]*\.[0-9]*\.[0-9]*’)

#connect
iptables-save > /dev/shm/old_routes
ifconfig $IF_LOC inet $IP_LOC.1
ip route add $IP_LOC.0/24 dev $IF_LOC src $IP_LOC.1
iptables -t nat -A POSTROUTING -s $IF_NET.0/24 -j MASQUERADE

if ip route | grep $IP_LOC.1 >/dev/null
then
#message
clear
echo “Enter this information in connected machines:”
echo “IP address : $IP_LOC.2-254”
echo “Netmask : 255.255.255.0”
echo “Gateway : $IP_LOC.1”
echo “DNS : $(echo -n $(awk ‘/^nameserver/ {print $2}’ /etc/resolv.conf))”
echo “”
echo “Press ENTER to continue.”
read

#monitor connection
iftop -i $IF_LOC

else
echo “Error setting up network”
fi

#disconnect
ip route del $IP_LOC.0/24 dev $IF_LOC
ifconfig $IF_LOC down
iptables-restore < /dev/shm/old_routes rm /dev/shm/old_routes #end [/sourcecode] and give execute rights to the script: [sourcecode lang="bash"] chmod +x router.sh [/sourcecode] now just run it: [sourcecode lang="bash"] sudo ./router.sh [/sourcecode] Script will show configuration of new created network [sourcecode lang="bash"] Enter this information in connected machines: IP address : 192.168.67.2-254 Netmask : 255.255.255.0 Gateway : 192.168.67.1 DNS : 217.172.224.160 89.228.6.21 Press ENTER to continue. [/sourcecode] and start monitor its traffic, to quit routing hit q or CTRL+C It is simplest way to start sharing internet I know off

Categories: Linux Tags: , ,

my git prompt

May 26th, 2010 2 comments

After long playing around with my prompt I finally made it stable and thought it’s time to share :)

So edit your ~/.bashrc file and add following lines on the end:

shopt -s promptvars dotglob histappend no_empty_cmd_completion cdspell xpg_echo

function parse_git_dirty {
  echo -n $(git status 2>/dev/null | awk -v out=$1 -v std="dirty" '{ if ($0=="# Changes to be committed:") std = "uncommited"; last=$0 } END{ if(last!="" && last!="nothing to commit (working directory clean)") { if(out!="") print out; else print std } }')
}
function parse_git_branch {
  echo -n $(git branch --no-color 2>/dev/null | awk -v out=$1 '/^*/ { if(out=="") print $2; else print out}')
}
function parse_git_remote {
  echo -n $(git status 2>/dev/null | awk -v out=$1 '/# Your branch is / { if(out=="") print $5; else print out }')
}
export PS1='$(ppwd \l)\u@\h:\[33[33m\]\w\[33[0m\]$(parse_git_branch ":")\[33[36m\]$(parse_git_branch)\[33[0m\]$(parse_git_remote "(")\[33[35m\]$(parse_git_remote)\[33[0m\]$(parse_git_remote ")")\[33[0m\]$(parse_git_dirty  "[")\[33[31m\]$(parse_git_dirty )\[33[0m\]$(parse_git_dirty  "]")>'

I know it looks a bit complicated, unfortunately it is … this is wired bash rule that escape sequences are evaluated before evaluation of functions/variables evaluation.

Some examples of prompt using this script:

mpapis@papis:~/old_laptop/nicz-projects/content2:master> touch a
mpapis@papis:~/old_laptop/nicz-projects/content2:master[dirty]> git add .
mpapis@papis:~/old_laptop/nicz-projects/content2:master[uncommited]> git commit -m "added a file"
mpapis@papis:~/old_laptop/nicz-projects/content2:master(ahead)>git push origin master
mpapis@papis:~/old_laptop/nicz-projects/content2:master>

To make it more useful the prompt is also colored to distinguish between states of git repo.

For lazy users the script could be also replaced by very easy version, which prints git status before each prompt line (only where git is applicable):

export PS1='$(git status 2>/dev/null)\[33[0m\]\n$(ppwd \l)\u@\h:\[33[33m\]\w\[33[0m\]>'

Note: download the code from here http://niczsoft.com/files/2010/05/my-git-prompt.txt

Categories: Development, Linux Tags: , ,