Showing posts with label Bash. Show all posts
Showing posts with label Bash. Show all posts

Tuesday, January 17, 2012

Get the PID of a started process in BASH

Sometimes (like when writing init scripts) it is necessary to get the PID of a child process that you started, this one-liner does that by listing processes grepping for the one you created (in this case "ls"), and cutting the PID from the last one in that list:

LPID=$(ps -A | grep ls | grep -v grep | tail -n1 | cut -d\  -f2)

Monday, January 9, 2012

UNIX Utilities III: Yes

This isn't a hugely popular program, but it does have its uses: the basic "yes" command, simply repeats whatever you put in to it, over and over and over again. This can be handy for things like testing buffering on a new shell you're developing.

Note that the usage is incredibly similar to echo, but simply provides it in a for loop:

/**
* A utility that emulates the UNIX command "yes", repeating the input
* until killed.
*
* Used in places like Jurassic Park (the movie) when Nedry leaves a
* trap that outputs the string "You didn't say the magic word!" over
* and over.
*
* Copyright 2011-12-23 Joseph Lewis <joehms22@gmail.com>
*/

#include <iostream>

using namespace std;

int main(int nargs, char* vargs[])
{
string s;

for(int i = 0; i < nargs - 1; i++)
{
if(i != 0)
s += " ";
s += vargs[i + 1];
}
s += "\n";

while(true)
{
cout << s;
}
}

Saturday, January 7, 2012

UNIX Utilities II: True and False

It is occasionally useful to check the outputs of commands in bash scripts; it is even more useful to test your scripts for all eventualities before you release them, to make sure strange errors don't begin occurring once they have been run in a variety of environments; this is where "true" and "false" come in.

These two simple programs simply return 0, or 1 as an exit status when run. This is probably the only case in a UNIX system where you will see 1 denoting a success.

Once compiled, these programs end up being about 8.3 kb on my system, which is almost a third the size of the GNU versions, how this happened, I have no idea; they are in essence the simplest programs in the world:

/**
* true - Probably the simplest program in the world, does nothing, and
* succeeds at it. Not very realistic, I know, but this is UNIX after
* all, not the real world where not doing anything makes you a failure.
*
* Copyright 2011-12-23 Joseph Lewis <joehms22@gmail.com>
*/

int main()
{
return 0;
}

/**
* false
* Probably the (second) simplest program in the world, does nothing,
* and fails at it. Note that this is the second because "true" is the
* first.
*
* Copyright 2011-12-23 Joseph Lewis <joehms22@gmail.com>
*/

int main()
{
return 1; // FAIL
}

Wednesday, December 28, 2011

UNIX Utilities: Echo

This is the first post of what I hope to be many describing UNIX command line utilities, first up is the "echo" command:

/**
* A copy of the "echo" command on UNIX, missing a few options, but it
* does what is normally asked of it.
*
* Copyright 2011-12-23 Joseph Lewis <joehms22 gmail com>
*/
#include <iostream>

using namespace std;

int main(int nargs, char* vargs[])
{
for(int i = 0; i < nargs - 1; i++)
{
if(i != 0)
cout << " ";
cout << vargs[i + 1];
}
cout << "\n";
}

Wednesday, October 26, 2011

Sleep Sort

A kind of neat sorting algorithm if, for some reason, you had a machine that had unlimited interrupts, and unlimited running time, but had almost no CPU power to do other sorts, perhaps biological computing?


 1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
function f() {
sleep "$1"
echo "$1"
}
while [ -n "$1" ]
do
f "$1" &
shift
done
wait

Sunday, September 18, 2011

Fast Ubuntu Tweaks

Over the past few years I went from absolutely loving Ubuntu to liking it, to almost disliking it now. Yes, it is a great distribution; but the teams that make it seem to not be taking UNIX design philosophy seriously.


Ubuntu seems to be building up a pillar of their own custom software. I was disappointed when they removed the option to change the GDM greeter a few years ago. Since then they seem to be obsessed with cohesion by removing options and doing half-ass jobs on building interfaces. (Have you noticed that when you right the indicator applet panel, the gradient is duplicated all the way down the menu?)

Unity is an excellent example of this; sure the desktop needed an overhaul, but don't push untested beta version software to users that has essentially no built-in way to change its options. And let's not even start with the problems it gives me on with my Nvidia!

But talk is cheap, so I'll show you the code. Three lines and a few config options should fix things up:

sudo apt-get purge ubuntuone*
sudo apt-get remove indicator-me indicator-messages
sudo apt-get purge zeitgeist*

Those three lines remove the ubuntuone client (do you use it? is it worth the program running in the background and trying to phone home?) Removes the indicator applet (that thing with the mail button, and your social media accounts), and removes zeitgeist (who uses it, really?)

Next: edit your "Startup Applications", what is this, Windows? Few people want VNC to be started when their computer does, if they do, they'll enable it manually.

With all this hate out, I'll say that my next computer system will either be Elementary OS (cohesive, yet follows UNIX design) or Windows 8.

Saturday, May 14, 2011

SVN Branch Copy

I was recently in the position of needing a particular SVN branch copied including history. However I didn't have administrator access on the SVN machine, and using the SVNSYNC command was going to copy all eighteen thousand revisions, mine were about fifty scattered within the last thousand. That was less than ideal.

I devised a way to do it though, and in a few hours came up with a handy script (yeah yeah, a few hours isn't exactly a one hour hack, but downloading the SVN branch you want should be).


Essentially the script does this:
  1. INIT a new repo at the desired location.
  2. Check out the most current branch of the old repo.
  3. Check the history of the old repo to check which revisions to sync (the changed ones).
  4. For each changed one, check it out, rsync it to the checked out new repo, and commit it to the new repo with the old log message.
  5. Finish some time later after you have made yourself a cup of tea and watched the most recent Doctor Who.

#!/bin/bash

# Check for proper args
if [ -z "$1" ];
then
echo -e "Usage:\n$0 URL_TO_COPY_FROM URL_TO_COPY_TO" && exit 1
fi;

SVNFROM=$1
SVNTO=$2

echo "Fetching branch from: $SVNFROM"
echo "Copying branch to: $SVNTO"

# Set up environment.
if [ -e tempsvn ];
then
rm -rf tempsvn
fi;

mkdir tempsvn tempsvn/download tempsvn/upload tempsvn/current
cd tempsvn

echo "Checking out current..."
svn co $SVNFROM current
HISTORY=`svn log current | grep \| | cut -d\ -f1 | sed 's/r\([0-9]*\).*/\1/' | sort -k1,1n`

# Init the new repo at the given location.
svn import upload $SVNTO -m ""
svn co $SVNTO upload

num=`echo $HISTORY | wc -w`
echo "There are $num revisions in this branch."


for REVNO in $HISTORY; do
rm -rf download
echo "-----------------------------------------------------------------------"
echo "Revision: $REVNO"
echo "Fetching..."
ENTRIES=`svn co $SVNFROM@$REVNO download`
CHANGES=`echo $ENTRIES | wc -l`
echo "Found $CHANGES change(s)."

echo "Change Log:"
cd download
LOG=`svn log -r $REVNO | grep \- -v`
echo $LOG
echo ""
cd ..

echo "Exporting..."
rsync -a --exclude='.svn' download/ upload/

cd upload

IFS_BAK=$IFS
IFS=$'\n'
for E in $ENTRIES; do
BEGIN=`echo $E | cut -d\ -f1`
END=`echo $E | cut -d\ -f5- | cut -d/ -f2-`

case "$BEGIN" in
'A') svn add -q $END ;;
'D') svn del $END ;;
esac
done
IFS=$IFS_BAK

if [ -e log.log ]; then rm log.log; fi;

echo $LOG > log.log
echo "Commiting new..."
svn commit -F log.log
cd ..
done
# Tear down environment.
cd ..
rm -rf tempsvn

One slight problem though, it removes and re-checks out the branch it is copying from every time because I was getting strange errors about branches being out of date, if anyone could fix that, it would increase the speed greatly.

Tuesday, April 5, 2011

Ubuntu Firewall Alerts

Notification of an attempted connection.
At the university I study at, every machine is assigned a net-accessible IP address; as you can imagine this is immensely useful as you don't need to worry about trying to bypass firewalls when you need to SSH somewhere.  There is a catch though, save for torrents (including LiveCDs that take hours to download manually, but minutes by torrent) there is no firewall.

That is okay by me though, I use Ubuntu; meaning I don't get viruses, and the only port I have remotely open is for the IPP because the network is Windows.  Recently I have wanted to see all of the garbage that is coming in.  I originally hacked something up in nc, but decided that wasn't good enough, here is my solution, that includes notifying you when someone attempts to connect to your port (this is a feature missing in all of the Linux firewalls I have found and seems to be a common complaint)  the finished product will look something like the photo above.

Ingredients:
  • Ubuntu / Distro of your choice.
  • iptables (installed by default in Ubuntu 10.10)
  • gufw (sudo apt-get install gufw)
  • notify-send / espeak / xmessage / zenity / other communication interface

Instructions:
  1. Install all of the above.
  2. Under System > Administration > Firewall Configuration, set Incoming to Reject; and turn on the Firewall.
  3. Copy the shell script below to your machine:
  4. #!/bin/bash

    lastlog=$(dmesg | grep UFW\ BLOCK | tail -1)

    while [ 1 -gt 0 ]; do

    sleep 1

    curlog=$(dmesg | grep UFW\ BLOCK | tail -1)

    if [ "$curlog" != "$lastlog" ]; then
    #get information.
    ip=$( echo $curlog | cut -d = -f5 | cut -d \ -f1)
    port=$( echo $curlog | cut -d = -f14 | cut -d \ -f1)
    portfrom=$( echo $curlog | cut -d = -f13 | cut -d \ -f1)
    lastlog=$(dmesg | grep UFW\ BLOCK | tail -1)

    #send message.
    notify-send "Src: $ip:$portfrom Dest: $port" -u critical -i security-low
    fi

    done
  5. For this to work though, you will need the program notify-send, if it is not installed, you could replace it with espeak (to have your computer announce that you dropped a connection), xmessage, or zenity.
  6. Watch how many times you are attacked.  (You might want to consider posting/looking up your findings to dshield)

    Friday, October 29, 2010

    Make a GUI wrapper for your favorite CLI program.

    Quick, what is your favorite Posix command line program?  What do you mean you don't have one?

    In this tutorial I'll show you how to write quick and dirty Python GUIs to wrap some of those programs you use often, but not often enough to remember all of the arguments.  I will be using the apropos command to demonstrate.


    If you try to stay out of the command line interfaces as much as possible it's very understandable, was it -r or -R for recursive?  Oftentimes a gui is very comforting because you can see all of the options displayed very spatially rather than in a long string of confusing arguments.  This spacial layout slows the process down for anyone that really knows what they are doing, but honestly is that you?  I use man pages and --help commands extensively while working with unfamiliar commands, which is slower than a GUI.

    Materials:
    Procedure:
    1. Download and install Python, wxPython, and wxGlade.  For me that was sudo apt-get install python-wxversion python-wxglade , (Ubuntu 10.10)
    2. Start up wxGlade, and design a gui around your application, for me (apropos) I needed a search box, and a results box, with some fancy labels to point out which was which.
    3. General Layout
      Program Preview



    4. Rather than having the user click a button when they want to search, we will have apropos search each time the text box is changed, this is a waste of system resources, but apropos is fast and I like instantaneous results.  So add a listener to your tiny list box in the Events tab of the Properties box when you select it.  Because you want this event called any time new text is entered put a method name in the EVT_TEXT handler box, this method will be called when new text is entered. 
    5. Adding A Method
    6. Select Application in the Tree, your properties box will now change to the export options.  Choose Python, and add an output path for the generated code. Then press Generate Code.
    7. The Code Generation Box
    8. You can now run your newly created Python program, it will have the shape of an application but no functionality yet.
    9. Open the python file in your favorite text editor, and replace the method that you called in EVT_TEXT with one that you make.  Mine looks like this:
    10. def enter_search_text(self, event): # wxGlade: MainFrame.<event_handler>

      import subprocess
      #Call an os function with each arg a separate list element
      process = subprocess.Popen(["apropos", self.text_ctrl_1.GetValue()], stdout=subprocess.PIPE)
      output, unused_err = process.communicate()
      #clear output
      self.text_ctrl_2.Clear()
      #Add the results to the output text control
      self.text_ctrl_2.AppendText(output)

      event.Skip()
    11. You could have named your text controls in wxGlade, I chose not to due to laziness.
    12. Close the program out and run it, you will now be able to search the man pages for programs and settings available on your system.  If I wanted to find all of the calculators on my system I would type in calculator and apropos would find them.
    xcalc looks interesting

    Conclusions:
    Building a GUI for CLI programs is a great way to learn more about the programs themselves, while making life easier for yourself.  You also get to discover new programs and learn Python GUI programming.