Shallow Thoughts : : Mar
Akkana's Musings on Open Source Computing and Technology, Science, and Nature.
Fri, 31 Mar 2017
Used to be that you could see your mounted filesystems by typing
mount
or df
. But with modern Linux kernels,
all sorts are implemented as virtual filesystems -- proc, /run,
/sys/kernel/security, /dev/shm, /run/lock, /sys/fs/cgroup -- I have
no idea what most of these things are except that they make it
much more difficult to answer questions like "Where did that ebook
reader mount, and did I already unmount it so it's safe to unplug it?"
Neither mount
nor df
has a simple option
to get rid of all the extraneous virtual filesystems and only show
real filesystems.
http://unix.stackexchange.com/questions/177014/showing-only-interesting-mount-p
oints-filtering-non-interesting-types
had some suggestions that got me started:
mount -t ext3,ext4,cifs,nfs,nfs4,zfs
mount | grep -E --color=never '^(/|[[:alnum:]\.-]*:/)'
Another answer there says it's better to use
findmnt --df
,
but that still shows all the tmpfs entries
(
findmnt --df | grep -v tmpfs
might do the job).
And real mounts are always mounted on a filesystem path starting with /,
so you can do mount | grep '^/'
.
But it also turns out that mount will accept a blacklist of types
as well as a whitelist: -t notype1,notype2...
I prefer the idea of excluding a blacklist of filesystem types
versus restricting it to a whitelist; that way if I mount something
unusual like curlftpfs that I forgot to add to the whitelist,
or I mount a USB stick with a filesystem type I don't use very
often (ntfs?), I'll see it.
On my system, this was the list of types I had to disable (sheesh!):
mount -t nosysfs,nodevtmpfs,nocgroup,nomqueue,notmpfs,noproc,nopstore,nohugetlbfs,nodebugfs,nodevpts,noautofs,nosecurityfs,nofusectl
df
is easier: like findmnt
, it excludes
most of those filesystem types to begin with, so there are only a few
you need to exclude:
df -hTx tmpfs -x devtmpfs -x rootfs
Obviously I don't want to have to type either of those commands every
time I want to check my mount list.
SoI put this in my .zshrc.
If you call mount or df with no args, it applies the filters,
otherwise it passes your arguments through.
Of course, you could make a similar alias for findmnt
.
# Mount and df are no longer useful to show mounted filesystems,
# since they show so much irrelevant crap now.
# Here are ways to clean them up:
mount() {
if [[ $# -ne 0 ]]; then
/bin/mount $*
return
fi
# Else called with no arguments: we want to list mounted filesystems.
/bin/mount -t nosysfs,nodevtmpfs,nocgroup,nomqueue,notmpfs,noproc,nopstore,nohugetlbfs,nodebugfs,nodevpts,noautofs,nosecurityfs,nofusectl
}
df() {
if [[ $# -ne 0 ]]; then
/bin/df $*
return
fi
# Else called with no arguments: we want to list mounted filesystems.
/bin/df -hTx tmpfs -x devtmpfs -x rootfs
}
Update: Chris X Edwards suggests
lsblk
or lsblk -o 'NAME,MOUNTPOINT'
.
it wouldn't have solved my problem because it only shows /dev devices,
not virtual filesystems like sshfs, but it's still a command
worth knowing about.
Tags: linux, cmdline
[
12:25 Mar 31, 2017
More linux |
permalink to this entry |
]
Sat, 25 Mar 2017
As part of preparation for Everyone Does IT, I was working on a silly
hack to my
Python
script that plays notes and chords:
I wanted to use the computer keyboard like a music keyboard, and play
different notes when I press different keys. Obviously, in a case like
that I don't want line buffering -- I want the program to play notes
as soon as I press a key, not wait until I hit Enter and then play the
whole line at once. In Unix that's called "cbreak mode".
There are a few ways to do this in Python. The most straightforward way
is to use the curses library, which is designed for console based
user interfaces and games. But importing curses is overkill just to do
key reading.
Years ago, I found a guide on the official Python Library and
Extension FAQ:
Python:
How do I get a single keypress at a time?.
I'd even used it once, for a one-off Raspberry Pi project that I didn't
end up using much. I hadn't done much testing of it at the time, but
trying it now, I found a big problem: it doesn't block.
Blocking is whether the read() waits for input or returns immediately.
If I read a character with
c = sys.stdin.read(1)
but there's been no character typed yet,
a non-blocking read will throw an IOError exception, while a blocking
read will wait, not returning until the user types a character.
In the code on that Python FAQ page, blocking looks like it should be
optional. This line:
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
is the part that requests non-blocking reads. Skipping that should
let me read characters one at a time, block until each character
is typed. But in practice, it doesn't work. If I omit the O_NONBLOCK flag,
reads never return, not even if I hit Enter; if I set O_NONBLOCK, the read
immediately raises an IOError. So I have to call read() over
and over, spinning the CPU at 100% while I wait for the user to type something.
The way this is supposed to work is documented in the termios
man page. Part of what tcgetattr returns is something called the
cc structure, which includes two members called Vmin
and Vtime. man termios is very clear on how they're
supposed to work: for blocking, single character reads, you set Vmin
to 1 (that's the number of characters you want it to batch up before
returning), and Vtime to 0 (return immediately after getting that one
character). But setting them in Python with tcsetattr
doesn't make any difference.
(Python also has a module called
tty
that's supposed to simplify this stuff, and you should be able to call
tty.setcbreak(fd)
. But that didn't work any better
than termios: I suspect it just calls termios under the hood.)
But after a few hours of fiddling and googling, I realized that even
if Python's termios can't block, there are other ways of blocking on input.
The select
system call lets you wait on any file
descriptor until has input. So I should be able to set stdin to be
non-blocking, then do my own blocking by waiting for it with select.
And that worked. Here's a minimal example:
import sys, os
import termios, fcntl
import select
fd = sys.stdin.fileno()
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON
newattr[3] = newattr[3] & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldterm = termios.tcgetattr(fd)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
print "Type some stuff"
while True:
inp, outp, err = select.select([sys.stdin], [], [])
c = sys.stdin.read()
if c == 'q':
break
print "-", c
# Reset the terminal:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
A less minimal example:
keyreader.py,
a class to read characters, with blocking and echo optional.
It also cleans up after itself on exit, though most of the time
that seems to happen automatically when I exit the Python script.
Update, 2017:
It turns out this doesn't work in Python 3: 3 needs some extra semantics
when opening the file. For a nice example of nonblocking read in
Python 3, see
ballingt:
Nonblocking stdin read works differently in Python 3.
Tags: programming, python
[
12:42 Mar 25, 2017
More programming |
permalink to this entry |
]
Mon, 20 Mar 2017
I've been quiet for a while, partly because I've been busy preparing
for a booth at the upcoming
Everyone Does IT
event at PEEC, organized by
LANL.
In addition to booths from quite a few LANL and community groups,
they'll show the movie "CODE: Debugging the Gender Gap" in the planetarium,
I checked out the movie last week (our library has it) and it's a good
overview of the problem of diversity, and especially the problems
women face in in programming jobs.
I'll be at the Los Alamos Makers/Coder Dojo booth, where we'll be
showing an assortment of Raspberry Pi and Arduino based projects.
We've asked the Coder Dojo kids to come by and show off some of their projects.
I'll have my RPi crittercam there (such as it is) as well as another
Pi running motioneyeos, for comparison. (Motioneyeos turned out to be
remarkably difficult to install and configure, and doesn't seem to
do any better than my lightweight scripts at detecting motion without
false positives. But it does offer streaming video, which might be
nice for a booth.) I'll also be demonstrating cellular automata and
the Game of Life (especially since the CODE movie uses Life as a
background in quite a few scenes), music playing in Python,
a couple of Arduino-driven NeoPixel LED light strings, and possibly
an arm-waving penguin I built a few years ago for GetSET, if I can
get it working again: the servos aren't behaving reliably, but I'm not
sure yet whether it's a problem with the servos and their wiring or a
power supply problem.
The music playing script turned up an interesting Raspberry Pi problem.
The Pi has a headphone output, and initially when I plugged a powered
speaker into it, the program worked fine. But then later, it didn't.
After much debugging, it turned out that the difference was that I'd
made myself a user so I could have my normal shell environment.
I'd added my user to the audio group and all the other groups the
default "pi" user is in,
but the Pi's pulseaudio is set up to allow audio only from users
root and pi, and it ignores groups.
Nobody seems to have found a way around that, but
sudo apt-get purge pulseaudio
solved the problem nicely.
I also hit a minor snag attempting to upgrade some of my older Raspbian
installs: lightdm can't upgrade itself (Errors were encountered
while processing: lightdm
). Lots of people on the web have hit
this, and nobody has found a way around it; the only solution seems to
be to abandon the old installation and download a new Raspbian image.
But I think I have all my Raspbian cards installed and working now;
pulseaudio is gone, music plays, the Arduino light shows run.
Now to play around with servo power supplies and see if I can get
my penguin's arms waving again when someone steps in front of him.
Should be fun, and I can't wait to see the demos the other booths will have.
If you're in northern New Mexico, come by Everyone Does IT this Tuesday
night! It's 5:30-7:30 at PEEC,
the Los Alamos Nature Center, and everybody's welcome.
Tags: programming, education, chix
[
12:29 Mar 20, 2017
More education |
permalink to this entry |
]
Fri, 10 Mar 2017
We live in what seems like wonderful roadrunner territory.
For the three years we've lived here, we've hoped to see a roadrunner,
and have seen them a few times at neighbors' places, but never in our
own yard.
Until this morning. Dave happened to be looking out the window at just
the right time, and spotted it in the garden. I grabbed the camera,
and we watched it as it came out from behind a bush and went into
stalk mode.
And it caught something!
We could see something large in its bill as it triumphantly perched on
the edge of the garden wall, before hopping off and making a beeline
for a nearby juniper thicket.
It wasn't until I uploaded the photo that I discovered what it had
caught: a fence lizard. Our lizards only started to come out of
hibernation about a week ago, so the roadrunner picked the perfect
time to show up.
I hope our roadrunner decides this is a good place to hang around.
Tags: roadrunner, birds
[
14:33 Mar 10, 2017
More nature/birds |
permalink to this entry |
]
Sun, 05 Mar 2017
Dave called from an upstairs bedroom. "You'll probably want to see this."
He had gone up after dinner to get something, turned the light on, and
been surprised by an agitated junco, chirping and fluttering on the sill
outside the window. It evidently was tring to fly through the window
and into the room. Occasionally it would flutter backward to the
balcony rail, but no further.
There's a piñon tree whose branches extend to within a few feet of the
balcony, but the junco ignored the tree and seemed bent on getting
inside the room.
As we watched, hoping the bird would calm down, instead it became
increasingly more desperate and stressed. I remembered how, a few
months earlier, I opened the door to a deck at night and surprised a
large bird, maybe a dove, that had been roosting there under the
eaves. The bird startled and flew off in a panic toward the nearest
tree. I had wondered what happened to it -- whether it had managed to
find a perch in the thick of a tree in the dark of night. (Unlike San
Jose, White Rock gets very dark at night.)
And that thought solved the problem of our agitated junco. "Turn the
porch light on", I suggested. Dave flipped a switch, and the porch light
over the deck illuminated not only the deck where the junco was, but
the nearest branches of the nearby piñon.
Sure enough, now that it could see the branches of the tree, the junco
immediately turned around and flew to a safe perch. We turned the porch
light back off, and we heard no more from our nocturnal junco.
Tags: nature, birds
[
11:27 Mar 05, 2017
More nature/birds |
permalink to this entry |
]