Shallow Thoughts : : Mar
Akkana's Musings on Open Source Computing and Technology, Science, and Nature.
Sat, 24 Mar 2012
A thread on the Ubuntu-devel-discuss mailing list last month asked
about how
to find out what processes are making outgoing network connectsion
on a Linux machine. It referenced Ubuntu
bug
820895: Log File Viewer does not log "Process Name", which is
specific to Ubuntu's iptables logging of apps that are already blocked
in iptables ... but the question goes deeper.
Several years ago, my job required me to use a program -- never mind
which one -- from a prominent closed-source company. This program was
doing various annoying things in addition to its primary task --
operations that got around the window manager and left artifacts
all over my screen, operations that potentially opened files other
than the ones I asked it to open -- but in addition, I noticed that
when I ran the program, the lights on the DSL modem started going crazy.
It looked like the program was making network connections, when it had
no reason to do that. Was it really doing that?
Unfortunately, at the time I couldn't find any Linux command that would
tell me the answer. As mentioned in the above Ubuntu thread, there are
programs for Mac and even Windows to tell you this sort of information,
but there's no obvious way to find out on Linux.
The discussion ensuing in the ubuntu-devel-discuss thread tossed
around suggestions like apparmor and selinux -- massive, complex ways
of putting up fortifications your whole system. But nobody seemed to
have a simple answer to how to find information about what apps
are making network connections.
Well, it turns out there are a a couple ofsimple way to get that list.
First, you can use ss:
$ ss -tp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 ::1:58466 ::1:ircd users:(("xchat",1063,43))
ESTAB 0 0 192.168.1.6:57526 140.211.166.64:ircd users:(("xchat",1063,36))
ESTAB 0 0 ::1:ircd ::1:58466 users:(("bitlbee",1076,10))
ESTAB 0 0 192.168.1.6:54253 94.125.182.252:ircd users:(("xchat",1063,24))
ESTAB 0 0 192.168.1.6:52167 184.72.217.144:https
users:(("firefox-bin",1097,47))
Update:
you might also want to add listening connections where programs
are listening for incoming connections: ss -tpla
Though this may be less urgent if you have a firewall in place.
-t shows only TCP connections (so you won't see all the interprocess
communication among programs running on your machine). -p prints the
process associated with each connection.
ss can do some other useful things, too, like show all the programs
connected to your X server right now, or show all your ssh connections.
See man ss
for examples.
Or you can use netstat:
$ netstat -A inet -p
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 imbrium.timochari:51800 linuxchix.osuosl.o:ircd ESTABLISHED 1063/xchat
tcp 0 0 imbrium.timochari:59011 ec2-107-21-74-122.:ircd ESTABLISHED 1063/xchat
tcp 0 0 imbrium.timochari:54253 adams.freenode.net:ircd ESTABLISHED 1063/xchat
tcp 0 0 imbrium.timochari:58158 s3-1-w.amazonaws.:https ESTABLISHED
1097/firefox-bin
In both cases, the input is a bit crowded and hard to read. If all you
want is a list of processes making connections, that's easy enough to do
with the usual Unix utilities like grep and sed:
$ ss -tp | grep -v Recv-Q | sed -e 's/.*users:(("//' -e 's/".*$//' | sort | uniq
$ netstat -A inet -p | grep '^tcp' | grep '/' | sed 's_.*/__' | sort | uniq
Finally, you can keep an eye on what's going on by using watch to run
one of these commands repeatedly:
watch ss -tp
Using watch with one of the pipelines to print only process names is
possible, but harder since you have to escape a lot of quotation marks.
If you want to do that, I recommend writing a script.
And back to the concerns expressed on the Ubuntu thread,
you could also write a script to keep logs of which processes made
connections over the course of a day. That's definitely a tool I'll
keep in my arsenal.
Tags: networking, linux, networking, cmdline
[
12:28 Mar 24, 2012
More linux |
permalink to this entry |
]
Fri, 16 Mar 2012
Someone asked me about determining whether an image was "portrait"
or "landscape" mode from a script.
I've long had a script for
automatically rescaling
and rotating images, using
ImageMagick under the hood and adjusting automatically for aspect ratio.
But the scripts are kind of a mess -- I've been using them for over a
decade, and they started life as a csh script back in the pnmscale
days, gradually added ImageMagick and jpegtran support and eventually
got translated to (not very good) Python.
I've had it in the back of my head that I should rewrite this
stuff in cleaner Python using the ImageMagick bindings, rather than
calling its commandline tools. So the question today spurred me to
look into that. I found that ImageMagick isn't the way to go, but
PIL would be a fine solution for most of what I need.
ImageMagick: undocumented and inconstant
Ubuntu has a python-pythonmagick package, which I installed.
Unfortunately, it has no documentation, and there seems to be no
web documentation either. If you search for it, you find a few
other people asking where the documentation is.
Using things like help(PythonMagick)
and
help(PythonMagick.Image)
, you can ferret out a
few details, like how to get an image's size:
import PythonMagick
filename = 'img001.jpg'
img = PythonMagick.Image(filename)
size = img.size()
print filename, "is", size.width(), "x", size.height()
Great. Now what if you want to rescale it to some other size?
Web searching found examples of that, but it doesn't work,
as illustrated here:
>>> img.scale('1024x768')
>>> img.size().height()
640
The built-in help was no help:
>>> help(img.scale)
Help on method scale:
scale(...) method of PythonMagick.Image instance
scale( (Image)arg1, (Geometry)arg2) -> None :
C++ signature :
void scale(Magick::Image {lvalue},Magick::Geometry)
So what does it want for (Geometry)? Strings don't seem to work,
2-tuples don't work, and there's no Geometry object in PythonMagick.
By this time I was tired of guesswork.
Can the Python Imaging Library do better?
PIL -- the Python Imaging Library
PIL,
happily, does have documentation.
So it was easy to figure out how to get an image's size:
from PIL import Image
im = Image.open(filename)
w = im.size[0]
h = im.size[1]
print filename, "is", w, "x", h
It was equally easy to scale it to half its original size, then write
it to a file:
newim = im.resize((w/2, h/2))
newim.save("small-" + filename)
Reading EXIF
Wow, that's great! How about EXIF -- can you read that?
Yes, PIL has a module for that too:
import PIL.ExifTags
exif = im._getexif()
for tag, value in exif.items():
decoded = PIL.ExifTags.TAGS.get(tag, tag)
print decoded, '->', value
There are other ways to read exif --
pyexiv2 seems
highly regarded. It has documentation, a tutorial, and apparently it
can even write EXIF tags.
If neither PIL nor pyexiv2 meets your needs,
here's a Stack Overflow thread on
other
Python EXIF solutions, and
here's
another discussion of Python EXIF.
But since you probably already have PIL, it's certainly an easy
way to get started.
What about the query that started all this: how to find out whether
an image is portrait or landscape? Well, the most important thing is
the image dimensions themselves -- whether img.size[0] > img.size[1].
But sometimes you want to know what the camera's orientation sensor
thought. For that, you can use this code snippet:
for tag, value in exif.items():
decoded = PIL.ExifTags.TAGS.get(tag, tag)
if decoded == 'Orientation':
print decoded, ":", value
Then compare the number you get to this
Exif
Orientation table. Normal landscape-mode photos will be 1.
Given all this, have I actually rewritten resizeall and rotateall
using PIL? Why, no! I'll put it on my to-do list, honest.
But since the scripts are actually working fine (just don't look at the code),
I'll leave them be for now.
Tags: programming, python, imaging, imagemagick,
[
15:33 Mar 16, 2012
More programming |
permalink to this entry |
]
Tue, 13 Mar 2012
The MITx 6.002 "Circuits
and Electronics" class started a week ago Monday. Exciting -- I'm hoping
I'll be able to learn all those electronics concepts that baffle me
while I'm trying to design simple circuits. (Assuming I make it --
I'm struggling and it's only the first week.)
One of the early exercises required integrating a trig function.
No problem -- I used
Wikipedia's
tables of integrals. But subsequent discussion of that problem
in the forums reminded me that when you're after a numeric solution,
we do have computers to do that sort of thing for us.
In particular, someone linked to
Wolfram
Alpha: integral (120sqrt(2)cos(2pi60t))^2/110 from 0 to 1/60
A nifty tool that I should remember to use more often!
Not only does it give you the numeric answer, but it also gives you
a nice symbolic display (so you can make sure you typed in what
you thought you were typing in), and a graph.
There was one hitch, though. In this particular problem, there was some
debate over the integration limits -- should it be 0 to 1/60 or 0 to 1?
If you try the same thing with 0 to 1, you still get the numeric answer,
but you get "Computation timed out", with a link labeled "Try again with
more time" that leads to an exhortation to subscribe to Wolfram Alpha Pro.
Of course, that made me antsy and made me wonder ... aren't there local
solutions? What if I want to calculate an integral when I'm away from
a fast network? Is there some way to do this using Python, Octave or R?
And of course there is. I haven't found an easy way to get the pretty
graphics, but you can get the numerical results fairly easily.
In Octave, it's a bit roundabout: you have to
define
a function, then call quad. The easiest way is to use inline:
octave:2> f = inline("(120 * sqrt(2) * cos(120 * pi * x))^2 / 110");
octave:3> quad(f, 0, 1/60)
ans = 2.1818
though you can also define a function this way:
octave:4> function y = ff(t)
> y = (120 * sqrt(2) * cos(120 * pi * tx))^2 / 110;
> endfunction
octave:5> quad(f, 0, 1/60)
ans = 2.1818
Here's how to do the same thing in Python using
SciPy:
import scipy
import math
scipy.integrate.quad(lambda t: (120 * math.sqrt(2) * math.cos(120 * math.pi * t))**2 / 110., 0, 1./60)[0] * 60
Of course, you don't need to use lambda -- you can also define a
function and pass it to scipy.integrate.quad.
None of this gets the nice graphics of Wolfram Alpha, though of
course either Python or Octave can be programmed to generate them.
I saw a presentation at PyCon about a package called
Sage that can probably
do nice graphics. But it's about a 350Mb download, so trying it
wasn't an option during the conference, and now the site is down
due to an electrical problem. So for now, Wolfram Alpha
wins the graphics war.
Tags: math
[
20:44 Mar 13, 2012
More science |
permalink to this entry |
]
Tue, 06 Mar 2012
I got a request from SVLUG to fill in at the last minute for a speaker
with a health emergency. Fortunately, I'd been slated to give them my
Arduino talk from SCALE in a few months, so I was happy to accept.
I'm always glad for a chance to show off Bruce, my
Arduino-
and Linux-controlled 6-foot flying robotic shark.
And if anyone
reading this happens to be in town for PyCon, Symantec isn't that
far from Santa Clara, roughly a 10-minute drive ... and I promise there
will be at least two interesting Python scripts presented.
It's free, of course, so come hear the talk!
Here are the SVLUG meeting
details and directions.
Tags: speaking, arduino, hardware, robots, radio control, maker
[
19:25 Mar 06, 2012
More speaking |
permalink to this entry |
]
Fri, 02 Mar 2012
Working on projects that might be fun for a proposed Arduino high school
workshop, I realized I hadn't done much with Arduinos and sound.
I'd made clicking noise for my
sonar
echolocation device, but nothing more than that.
But the Arduino library has a nice function to control a speaker:
tone(int pin,
int frequency, int length).
tone()
works much better than trying to make your own
square wave, because it uses interrupts and doesn't glitch when
the processor gets busy doing other things. You can leave off the
length parameter and the tone will continue until you
tell it to stop or change frequency.
Random tones
So you can produce random tones like this (SPEAKER is the pin the
speaker is plugged into):
uint8_t SPEAKER = 8;
void setup()
{
pinMode(SPEAKER, OUTPUT);
// Seed the random number generator from floating analog pin 0:
randomSeed(analogRead(0));
}
void loop()
{
// Random frequency between 20 and 1400 (Hz).
unsigned long freq = random(20, 1400);
long duration = random(5, 50);
tone(SPEAKER, freq, duration);
delay(random(100, 300));
}
Light theremin
Purely random tones aren't very interesting to listen to, though, as
it turns out.
How about taking input from a photo-resistor, to make
a light theremin that wails as I move my hand up and down above the
sensor? The photoresistor I was using typically reads, on the Arduino,
between 110 (with my hand over the sensor) and 800. So I wanted
to map that range to audible frequencies the speaker could handle,
between about 20 Hz and 5000.
uint8_t LIGHTSENSOR = 0;
void loop()
{
// Set the frequency according to the light value read off analog pin 0.
#define MAX_SIGNAL 800
#define MAX_FREQ 5000
#define MIN_SIGNAL 380
#define MIN_FREQ 20
int lightsensor = analogRead(LIGHTSENSOR);
int freq = (lightsensor - MIN_SIGNAL)
* (float)(MAX_FREQ - MIN_FREQ)
/ (MAX_SIGNAL - MIN_SIGNAL)
+ MIN_FREQ;
tone(SPEAKER, freq);
}
Random music (chiptunes)
That was fun, but
I still wanted to try some random music that actually sounded ... musical.
So how about programming the standard scale, and choosing frequencies from
that list?
I looked up the frequency for Middle C, then used fractions to
calculate the rest of the
"just" diatonic
scale for C major:
float middle_c = 262.626;
float just[] = { 1., 9./8, 5./4, 4./3, 3./2, 5./3, 15./8 };
#define NUMNOTES (sizeof(just)/sizeof(*just))
float cur_octave = 1.;
Multiplying the frequency by 2 transposes a note up one octave;
dividing by two, down one octave. cur_octave will keep track
of that.
Now if whichnote is a number from 0 to 7,
cur_octave * just[whichnote] * middle_c
will give the next frequency to play.
Just choosing notes from this list wasn't all that interesting either.
So I adjusted the code to make it more likely to choose a note just one
step up or down from the current note, so you'd get more runs.
rand = random(0, 6);
if (rand == 0)
whichnote = (whichnote + 1) % NUMNOTES;
else if (rand == 1)
whichnote = (whichnote + 1) % NUMNOTES;
else
whichnote = random(0, NUMNOTES);
float freq = middle_c * just[whichnote];
// Change octave?
rand = random(0, 10);
if (rand == 1 && cur_octave <= 3) {
cur_octave *= 2.;
} else if (rand == 2 && cur_octave >= 1) {
cur_octave /= 2.;
}
freq *= cur_octave;
It's still not great music, but it's a fun experiment and I'm looking
forward to adding more rules and seeing how the music improves.
Bach
But this left me hungry for real music. What if I wanted to play
a real piece of music? Certainly I wouldn't want to type in an array
of frequency numbers, or even fractions. I'd like to be able to say
A, Ab (for A-flat), Cs (for C-sharp), etc.
So I defined the frequency for each of the notes in the scale:
#define NOTE_Ab 207.652
#define NOTE_A 220.000
#define NOTE_As 233.082
#define NOTE_Bb NOTE_As
#define NOTE_B 246.942
#define NOTE_C 261.626
#define NOTE_Cs 277.183
#define NOTE_Db NOTE_Cs
#define NOTE_D 293.665
#define NOTE_Ds 311.127
#define NOTE_Eb NOTE_Ds
#define NOTE_E 329.628
#define NOTE_F 349.228
#define NOTE_Fs 369.994
#define NOTE_Gb NOTE_Fs
#define NOTE_G 391.995
#define NOTE_Gs 415.305
#define NOTE_REST 0.0
#define NOTE_SUSTAIN -1.0
Then the first part of Bach's 2-part invention #4 in D minor
looks like this:
float composition[] = {
NOTE_D, NOTE_E, NOTE_F, NOTE_G, NOTE_A*2, NOTE_As*2,
NOTE_Db, NOTE_As*2, NOTE_A*2, NOTE_G, NOTE_F, NOTE_E,
NOTE_F, NOTE_REST, NOTE_A*2, NOTE_REST, NOTE_D*2, NOTE_REST,
NOTE_G, NOTE_REST, NOTE_Cs*2, NOTE_REST, NOTE_E*2, NOTE_REST,
NOTE_D*2, NOTE_E*2, NOTE_F*2, NOTE_G*2, NOTE_A*4, NOTE_As*4,
NOTE_Db*2, NOTE_As*4, NOTE_A*4, NOTE_G*2, NOTE_F*2, NOTE_E*2,
};
And the code to play it looks like:
unsigned long note = composition[i++];
if (note == NOTE_REST)
noTone(SPEAKER);
else if (note == NOTE_SUSTAIN)
; // Don't do anything, just let the current tone continue
else
tone(SPEAKER, note);
It's a bit tedious to type in the notes one by one like that, which
is why I stopped when I did. And as far as I know, the Arduino can
only emit one tone at once -- to play the real 2-part invention,
you either need a second Arduino, or extra hardware like a
wave shield.
Anyway, it was a fun series of experiments, even if none of it
produces great music. You can see the source at
github:
akkana/arduino/music.
Tags: arduino, hardware, music, maker
[
19:54 Mar 02, 2012
More hardware |
permalink to this entry |
]