A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

How to transfer files between Windows 7 and Android 4

Settings | Storage | (three dots in top-right) | USB computer connection | Camera (PTP)

Then go to Developer Options (read elsewhere how to get this), and tick 'USB debugging'.

Voila - your device will appear in My Computer | Portable Devices.

Copy the files to a subdirectory of the Android Camera device in Windows, and move them into the right place from within Android. e.g. using ES File Explorer

Good enough software

There's so much software available these days, it's difficult to find which is the best without laboriously downloading, installing, configuring and testing, which I don't often have time for. Unfortunately a large proportion of software is simply not good enough, or its features are poorly described.

Here is some "good enough" software I've found for Windows:
  • To diff directories, e.g. sync music or photos: FreeFileSync 6.3
  • To diff the content of files, e.g. source code: WinMerge
  • Windows Explorer alternative: xplorer 2
  • To encode mp3s: LAME
  • To see where your disk space is being used: Treesize
  • To remove spyware: Spybot: Search & Destroy
  • Torrents: qBittorrent
  • N64 emulator: project64
  • Programmer's text editor: Notepad++
  • ebook management: Calibre
  • Manage iPhone music outside iTunes: Media Monkey
  • Graphics maniplation: GIMP
  • Rename files: Bulk Rename Utility
  • Macro recorder: Autohotkey
  • Media player: VLC, or MPC-HC (not tried)
  • Music player: Winamp
  • Documents and spreadsheets: Microsoft Office
    • (LibreOffice and OpenOffice are NOT good enough)

Why shouldn't you put logic in the template?

The overall reason for keeping business logic separate from presentation is well known, see MVC.

Here are the practical reasons why putting business logic in the template is a really bad idea:
  • You can't re-use it
  • You can't unit test it
  • You can't log
  • You can't validate parameters to subroutines
  • You often can't create subroutines at all (and you shouldn't)
  • You can't use an IDE to look up method definitions
  • You can't "use strict"
  • You can't run a code tidier
  • You can't validate syntax
  • Error messages are different
  • Keyword behaviour can be subtly different, leading to the worst kind of bug - the one you don't notice until it's too late.
  • Now you have two languages to maintain instead of one
Logic which relates directly to the display of the page is borderline okay, although for the reasons stated above it's better to put as much of that as possible in a class/module, which could be called a View Model.

Corollary - don't pass the entire model to the template, only stash what is needed. Reasons for this:

  • Separation of concerns - the template should be editable by a front-end dev without any knowledge of syntax to specify models
  • Performance may be poor - for example if the model opens a new database connection each time it's called


This article was written with Perl and Template Toolkit in mind.

Make it easy to review your code

tldr; It's difficult to arrange for a whole team of developers to follow and participate in code reviews, but if you use dedicated code review software then it's easy.

Of course you want a wide audience reading your code - in order to improve the quality of the code being produced by your team. You don't have anything to hide, do you? ;-)

Problem: Say you're not the "designated reviewer", and you want to see your team mates' code before it's merged to trunk, perhaps the following things have to happen:
    - Configure your email filters to pick out reviews from the hundreds of other update emails
    - Check out the code in your environment
    - Wait some time for the checkout to complete
    - Run a diff command to see the changes
    - Hope that your team is using version control tools which make it easy/possible to see only the commits they made, without mixing them up with all the code that was pulled from trunk/master along the way
    - Read the code
    - Copy and paste the lines of code you want to comment on (for context) into a message to the developer. As it's often easier and faster to use email, instant chat or a face to face meeting than adding comments to a bug tracking system, the rest of the team isn't part of the conversation and is denied the chance to learn about technique, see how to conform to house policy, etc.
    - Write the comments
    - The developer reads the comments and may or not make changes, you don't always know, and the rest of the team certainly doesn't know.
    - In a team where developers are expected to designate a single person to review each feature, attempting to give feedback on someone else's code out of turn could be seen as interfering and a distraction.

Solution: A better arrangement could be:
    - Use a code review tool: ReviewBoard, Stash or something similar
    - Click on a URL in the review notification email
    -  Read the code
    - Click on the line you want to comment on
    - Write the comments. The whole team gets notification emails of comments, so they can effortlessly follow along with conversations about the code.
    - The developer replies to the comments publicly, everyone is now aware of what technical decisions were made and why
    - Everyone is expected to review all code - it's not distracting because it becomes part of the general work of the team to ensure high code quality.

How to work around certificate errors in Perl

PERL_LWP_SSL_VERIFY_HOSTNAME=0 perl script.pl

or

my $mech = WWW::Mechanize->new(
    ssl_opts => { SSL_verify_mode => 'SSL_VERIFY_NONE'},
);

Windows macro recorders

List:

  • EZ Macros - good but very old
  • AutoHotkey - very good
  • AutoMate - ?
  • Workspace Macro - ?
  • Auto Macro Recorder - not intuitive, and I don't like the interface. Looks like Windows 3.1


How to set the follow up flag in Outlook 2007

Sometimes I click on the 'follow up' flag icon for an email in the inbox, and nothing happens. Or there's a message to say the flag was set but it doesn't change colour and doesn't appear in the to do list.

Workaround: Click on the follow up flag for a different email, then clear it, then click back on the first one.

Manual automatic accessors in Perl

If you don't have Moose, Mo* or Class::Accessor:

package Foo;

=head1 SYNOPSIS

    my $f = Foo->new(
        bar => 'rab',
        qux => 'xuq',
    );

=cut

use constant ACCESSOR_MAP => {
    'get_bar' => 'bar',
    'get_qux' => 'qux',
};

use constant ACCESSOR_ITEM => qw(ping ting zing);

sub new {
    my ( $c, %args ) = @_;
    my $class = ref $c || $c;
    bless {%args}, $class;
}

sub __mk_accessor {
    my ( $c, $name, $key ) = @_;
    $key ||= $name;
    my $pkg = ref $c || $c;
    my $sym = join( '::', $pkg, $name );
    no strict 'refs';
    *{$sym} = sub {
        my ($self) = @_;
        $self->{$key};
    };
}

# set up ping(), ting(), zing()
__PACKAGE__->__mk_accessor($_) foreach __PACKAGE__->ACCESSOR_ITEM;

# set up get_bar(), get_qux()
for my $k ( keys %{ __PACKAGE__->ACCESSOR_MAP } ) {
    my $v = __PACKAGE__->ACCESSOR_MAP->{$k};
    __PACKAGE__->__mk_accessor( $k, $v );
}

# not tested

Show tabs in GNU screen

~/.screenrc

hardstatus string "%{= g} %{= w}%-Lw%{=r}%n%f* %t%{-}%+LW"

(source)

See also byobu, which is one step better than screen.


Determine differences in an array with Perl

Not just checking whether or not two arrays are the same, but finding out how they are different, i.e. what has been added and what has been taken away:

use Algorithm::Diff 'sdiff';
use Data::Dumper;

my @a = (1, 2, 3, 4);
my @b = (2, 3, 4, 5);

my @c = sdiff(\@a, \@b);

print Dumper(\@c);

Output:

$VAR1 = [
          [ '-',  1, '' ],
          [ 'u',  2,  2 ],
          [ 'u',  3,  3 ],
          [ 'u',  4,  4 ],
          [ '+', '',  5 ]
        ];

You can see that 1 has a '-' indicating it has been removed, and 5 has a '+' indicating it has been added. The other items have a 'u', indicating they are unchanged.

(source)

However, if comparing (a b c) with (c b a), Algorithm::Diff::sdiff will fail to realise that nothing has been added or removed. A simpler algorithm might be:

sub determine_changes {
    my ($old, $new) = @_;

    # Compare two lists
    my %old_lookup = map { $_ => 1 } @$old;
    my %new_lookup = map { $_ => 1 } @$new;
    my @added = grep { ! $old_lookup{$_} } @$new;
    my @removed = grep { ! $new_lookup{$_} } @$old;

    my @changes;
    push @changes, map { { item => $_, operation => 'add'    } } @added;
    push @changes, map { { item => $_, operation => 'remove' } } @removed;

    my @sorted_changes = sort { $a->{item} cmp $b->{item} } @changes;
    return \@sorted_changes;
}

Syntax highlight in vim by file extension

How to add file extension syntax highlighting to vi.
Whack this in your ~/.vimrc

au BufNewFile,BufRead *.tt set filetype=perl

(source)

How to use git with an svn repo

Do you have a subversion repo? Think you're stuck with outdated subversion workflows? Not anymore! Use the fabulous git to work with your subversion hosted code:

git svn clone https://example.com/path/to/trunk -T trunk -b branches -t tags

(may take a long time with large repos, e.g. several days)

Now you can rebase your code! You can do all your work with git - easily branch, stash, rebase, blame, etc. - and when you're done, push back to subversion.

(source)

See subversion branches:
git branch -r

Update the git repo (may take several hours for large repos - you don't need to run this more than once):
git svn fetch --fetch-all

Update the current branch (run this on trunk/master instead of "fetch" above):
git svn rebase

(source)

Temporarily skip a test until a specific date

The job of a test suite is to alert the developers of a potential problem. Once that's happened, the only value in continuing to fail is to nag and remind them to make a change. In real life sometimes fixing issues takes a long time. If they're already tracking changes in a ticketing system, or actively working on a fix, the failure becomes noise, and can hide other unexpected failures. There should be no such thing as an "okay failure" which can be ignored - you need to stop it failing if the fix is already planned. But you don't want to risk forgetting about it. So you can disable it for a short time, to allow the developer to fix the underlying issue. In the future, perhaps CI frameworks might feature a Nagios-style "acknowledge" function.

This is one solution for now:

use Test::More;
use DateTime;

my $expected_to_fail = (
    ($test_data = 'foo')
    &&
    ! deadline_has_passed( DateTime->new( year => 2014, month => 11, day => 23 ) # the future
) ? 1 : 0;

SKIP: {
    skip "while we do something (ticket ID)", 1 if $expected_to_fail;
    ok( "some test" );
}

sub deadline_has_passed {
    my ($deadline) = @_;
    my $today = DateTime->now; #->add( days => 30 );
    my $deadline_has_passed = (DateTime->compare( $today, $deadline ) < 1) ? 0 : 1;

    # debug
    #note("today    = ".$today->ymd);
    #note("deadline = ".$deadline->ymd);
    #note("compare today,deadline => ". DateTime->compare( $today, $deadline ));
    #note("has deadline passed? $deadline_has_passed");

    return $deadline_has_passed;
}

See hidden characters in a string

perl -e '$HOSTNAME = `hostname -s`; print $HOSTNAME;' | od -c

Easily add colours to bash scripts

RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
WHITE="$(tput setaf 7)"
RESET=$WHITE

echo "${RED}An error occurred${RESET}"
echo "${YELLOW}Warning: Be careful${RESET}"
echo "${GREEN}Everything is groovy${RESET}"

(source)

Old, naive way:

GREEN="\[\033[32m\]"
YELLOW="\[\033[33m\]"
RESET="\[\033[0m\]"

Outlook 2007 reminder windows always on top

Hit Alt-F11, navigate to Project1 | Microsoft Office Outlook Objects | ThisOutlookSession

Simple way 

Private Sub Application_Reminder(ByVal Item As Object)
    If TypeOf Item Is AppointmentItem Then
    MsgBox "Message text", vbSystemModal, "Message title"
    End If
End Sub


(source)

Sophisticated way

Private Declare PtrSafe Function FindWindowA Lib "user32" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare PtrSafe Function SetWindowPos Lib "user32" ( _
ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long

Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const FLAGS As Long = SWP_NOMOVE Or SWP_NOSIZE
Private Const HWND_TOPMOST = -1

Private Sub Application_Reminder(ByVal Item As Object)
Dim ReminderWindowHWnd As Variant
On Error Resume Next
ReminderWindowHWnd = FindWindowA(vbNullString, "1 Reminder")
SetWindowPos ReminderWindowHWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS

End Sub

(source)

Email me that information, don't tell me out loud!

Why I want you to email me that information instead of telling me out loud. There are so many reasons:

Speaking is inefficient:

  • I could mis-hear and copy it down wrong
  • I have to spend time listening to you and writing it down somewhere
  • If I'm not in front of a computer then it's written on a piece of paper, I have to store it somewhere for future reference, or spend more time typing it up

Email is efficient:

  • You've got a record of the information for the rest of your life, with no further effort (you are using a web-based email system, right?)
  • You can search for and find the information instantly
  • You can forward it to someone else for their reference
  • You can copy and paste with no chance of error
  • Email is so fast that someone can email you while you're speaking on the phone, and you can receive it and verify that it's correct before they hang up


STDERR and STDOUT appear in the wrong order when piping to a file

a Perl script - test.pl:

print "OUT 1\n";
print STDERR "ERR 2\n";
print "OUT 3\n";
print STDERR "ERR 4\n";
print "OUT 5\n";

Run the script, piping all output into a file:

perl test.pl &> file.log

cat file.log

ERR 2
ERR 4
OUT 1
OUT 3
OUT 5

Output is in the wrong order :(

Run it again using unbuffer:

unbuffer perl test.pl &> file.log

cat file.log

OUT 1
ERR 2
OUT 3
ERR 4
OUT 5

Output is in the correct order :)

(source)

Another way:

script -c 'perl ~/temp/stream.pl' file.log

cat file.log

(source)

Cannot scp, but ssh works fine

Maybe your .bashrc or similar prints something to the console? This breaks scp.

e.g. if .bashrc or something it calls contains:
echo "Welcome to the server"

Then scp will just print "Welcome to the server" and not even attempt to copy the file.

Can't install recent Perl: too few arguments to function ‘dbmclose’

When I tried to install perl 5.16.2 or perl 5.20.0:

wget http://www.cpan.org/src/5.0/perl-5.20.0.tar.gz
tar -xpvzf perl-5.20.0.tar.gz
cd perl-5.20.0
sh Configure -Dprefix='/opt' -de
make
...
make[1]: Entering directory `/opt/dweb/home/shepwil/src/perl-5.20.0/ext/ODBM_File'
cp ODBM_File.pm ../../lib/ODBM_File.pm
Running Mkbootstrap for ODBM_File ()
chmod 644 ODBM_File.bs
../../miniperl "-I../../lib" "-I../../lib" ../../lib/ExtUtils/xsubpp -noprototypes -typemap ../../lib/ExtUtils/typemap -typemap typemap  ODBM_File.xs > ODBM_File.xsc && mv ODBM_File.xsc ODBM_File.c
cc -c   -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2   -DVERSION=\"1.12\" -DXS_VERSION=\"1.12\" -fPIC "-I../.."   ODBM_File.c
ODBM_File.xs: In function ‘XS_ODBM_File_DESTROY’:
ODBM_File.xs:128: error: too few arguments to function ‘dbmclose’
make[1]: *** [ODBM_File.o] Error 1
make[1]: Leaving directory `/opt/dweb/home/shepwil/src/perl-5.20.0/ext/ODBM_File'
Unsuccessful make(ext/ODBM_File): code=512 at make_ext.pl line 561.
make: *** [lib/auto/ODBM_File/ODBM_File.so] Error 25

The solution:

sudo diff /usr/include/dbm.h.patched /usr/include/dbm.h
62c62,63
> extern int    dbmclose __P((DBM *));
---
< /* extern int dbmclose __P((DBM *));*/
< extern int    dbmclose __P((void));

sudo cp usr/include/dbm.h.patched /usr/include/dbm.h

(source)

How to communicate within an IT department or tech team

Communication is difficult, it's easy to get wrong. Here are some ideas about how to get it right.
  • Mailing lists: Make them public (within the company). Archive them. Make them discoverable. Let users administer them. See GNU mailman.
  • Wiki: Only have one. Keep the software up-to-date. Have an 'information architect' role, who manages the structure, so that the information is in predictable places. Make sure the search works (test it regularly). Unlock all the permissions. Let people delete pages. React to user feedback.
    • When you upgrade, ideally migrate/import the data to the new version. If that doesn't happen, then export or otherwise safely archive the old content. Publish it internally, make sure it's available, even if static.
    • Use the Gliffy plugin or equivalent (e.g. on Atlassian Confluence an open source wiki) or equivalent to allow users to publish diagrams of unlimited complexity, that can be edited and kept up-to-date by anyone.
  • Issue tracking system: Keep the software up-to-date. Don't install a million plugins (looking at you Jira) that make it difficult to upgrade. Make sure the workflows match reality, give people standard ones and document how they work. Be very careful when making changes to workflows, try to keep them as general and re-usable as possible.
  • Write high quality tickets.
  • Service Desk: Use the same system as the bug tracker, which will allow all staff to track their tickets' progress in a way they understand. If this is not possible, make the service desk ticket system no less usable/visible than the staff issue tracker system.
    • Ensure the service desk issue system is no less usable than email, i.e. original message chain quoted in all replies, and CCs honoured with reply-all.
    • Have a special email address for people to CC which will copy the email to a ticket. Publicise it regularly.
  • Choose software that makes a healthy development environment.
  • Things to publish internally, and regularly re-post:
    • instructions for transferring phonecalls internally
    • instructions for setting up a conference calls (for all phone models in use)
    • instructions for setting up video calls from conference rooms
    • instructions for setting up a laptop/desktop with the big screen in meeting rooms/presentations
  • List all regular non-stream tasks, define roles to triage, co-ordinate and communicate them to the rest of the team, with a view to improving and streamlining the work of the team. Examples:
    • Failing tests
    • Environmental issues
    • Live bugs
    • Supporting the release
    • Inter-team liaison
    • Monitoring reports
    • Business investigations
  • Ideally don't have any remote members of the team. But at the very least, don't inconvenience the co-located members for the sake of remote members. This means:
    • Don't hold scrum via phone or skype, hold it in person. Figure out some way for the remote people to attend that doesn't take anything away from the people in the room. If there's no way, they can attend their own scrum, or not at all.
      • Update: Video chat (e.g. Zoom) works well when there is a large TV screen and dedicated room microphone device. Whoever is in the office goes over to that TV & mic area and starts the video call so anyone working remotely can dial in and participate.
    • Don't force people to communicate via headsets when they're standing next to each other. That would discard the many benefits of face-to-face communication.
    • Make sure everyone actually stands up around a physical board (Update: Jira scrum/kanban board works fine over video chat, if updated outside the meeting). If headset range is too far to work, don't use them.
    • Don't have the scrum at a weird time of day to accommodate other time zones.
    • If it's difficult to hear the remote members then have them email points to the team.
    • Try to arrange for the remote members to work one-on-one with each co-located member, to build rapport
  • Put ALL work in the issue-tracking system to make it visible, even non-development work. If it's not tracked, you didn't really do it. Each task must link back up to team "epics" or long-term goals, and ultimately to a company goal. Must be extremely easy to create tasks with one line of text and no other info, i.e. prevent unnecessary overhead for simple tasks.
  • Specific to large companies:
    • Instant chat client for ALL members of staff, with zero configuration, it's just there waiting to be used. Hooked into Outlook and the O/S so that it knows when you're in a meeting or away from your desk and updates your status accordingly (e.g. MS Office Communicator)
    • Have a meeting room booking system that is painless (is this even possible?) and transparent with regard to: higher-ranked employees permission to "override" bookings, policy for block-booking rooms every week, etc. Above all it should be obvious what is happening and why.
  • IRC/Slack or equivalent for all. Make it clear that all communications will be logged.
  • (crazy idea) Employ a person/team whose sole remit is to make it easier to communicate within the company. This is definitely not the usual "Internal Communications" team that sits with HR and serves the Executive. It's a team that is there to support IT workers.
  • If the office is very large, publish a map of where each team sits. Make sure it's always up-to-date, either by giving a team the responsibility to do it, or making it editable by anyone on the wiki.
  • Link from the team map to official wiki pages, etc. org chart, make everyone's names and roles discoverable and visually represented.
  • Put signs up around each area so you can see which team sits where.
  • Use scrumblr.ca or funretro.io or similar (virtual post-it note boards) for retrospectives, to allow ideas to be captured throughout a sprint, not just on the day. Also a wiki page does just fine. But it's also important to keep real, physical post-it notes and pens in the meeting for people to jot down ideas they just think of at that time.
  • Create the following types of wiki pages, for each team or development group:
    • Tech Debt / Yak Shaving / Infrastructure to-do list / Ideas / Suggestions (use your judgement if this should be one page or several). This is a list of things that people want to do, changes they want to make that are not on the roadmap, or don't obviously provide direct value to the business. The team may need help explaining where the value lies.
    • Proposed technical discussion topics. Topics worthy of group discussion. Schedule a regular meeting (every 2-4 weeks) to discuss whatever is on this list and make a decision as a team about how to proceed.
    • Developer FAQ. Either per-team or per-department.

Source: My own experience working in IT.

What a healthy development environment looks like

In my opinion, the best set up would include:

Software
  • Jira for issue tracking 
  • A wiki for information sharing 
  • Git for version control
  • Continuous integration and continuous deployment (e.g. with Jenkins)
  • Use an existing package provider like Redhat, don't compile publicly available software yourself
Environment
  • Full commit history available with details of developer name and change ticket ID
  • Full ticket history available to read, with no historical tickets in the "old" system and unreadable
  • /etc/init.d scripts ('service') for starting, stopping and restarting software
  • VMs for development 
  • Identical production, development and test environments
  • Continuous Integration: Every check-in to any development branch is run through the test suite, and any failures are emailed to the author
  • Immutable infrastructure: Servers are not changed. All changes begin with pushing to a repo, and a new server is then built and deployed to a subset of users, tested, then to all users.
  • One-touch deployment, identical in both production and development environments 
    • Continuous deployment: Every commit to trunk that passes the test suite is deployed
  • Refactoring code as required, restricted only by the need to pass the test suite
  • All major software components described on wiki with details of source code, restarting, troubleshooting, owner, etc.
Tests
  • Easy to run the entire test suite for any branch
  • Test suite should complete quickly
  • A test suite that is comprehensive and well understood by all
  • Test coverage stats are visible to everyone
  • Tests for hallmarks of quality like 'use strict' and embedded documentation (even if a blacklist of legacy code is required)
Code
  • Clear model-view-controller separation
  • All code contained within re-usable modules (scripts are thin wrappers around classes)
  • No "utility classes" (inherit/use roles if common methods are needed)
  • No "god classes" (split up methods into meaningul sublclasses or roles)
  • All logic contained within meaningful "noun" classes designed for problem domain
  • Meaningful variable names in domain language and no unnecessary abbreviations
  • Plentiful comments, written in the language of the problem domain
  • All classes/modules to have embedded documentation
People
  • For every piece of work, three people should discuss it together for a few minutes after a technical design has been proposed, and before any development work is started - a representative of the business, a QA tester and a developer.
    • They should ask questions like "Are the requirements accurate and high quality?", "Does the proposed solution fulfill the requirements?", "Is the proposed solution high quality?", "Can the proposed solution be easily tested?", etc.
  • The product manager as well as the people coming up with requirements must be readily available to answer questions.
  • To facilitate communication. teams should *not* be split across timezones
    • (separate) Scrums should take place at the beginning of the local day

example gdb command

Use gdb to get a backtrace by attaching to a running process, then detaching immediately like so: sudo gdb /path/to/apache/bin/httpd 12345 -ex bt -ex detach -ex quit Where 12345 is a process ID that is misbehaving. This command should be used with a bit of care as it will pause that process while the backtrace is obtained.

How to forward your SSH key

Windows:

1. Run pageant, put it in startup, and pass it your key

2. Run putty or MobaXterm, configure them both to do "ssh -A" (i.e. forward your key)

3. On the server, check your SSH key is loaded:

ssh-add -l

4. ssh -A to other servers

Linux:

ssh -A to each server


Comparison of private image hosting

  • Facebook - Private albums, but I never quite trust them with my privacy. Interface is tedious and buggy to use. Not geared towards organising lots of images. Upload limit not advertised.
  • Photobucket - Private or password protected albums. Interface is not great as it squashes your thumbnails, has adverts and only shows a few images each page (mobile). 10Gb free, $30/year for 20Gb, more storage available.
  • Flickr - 1Tb free. Pictures can be private, or shared with family. For pictures, this is very good. Uploaded video quality can be poor. Interface is great for uploading and organising many thousands of photos and video.
  • SmugMug - $40/year for unlimited uploads. Advanced privacy/sharing system. They've put a lot of effort into it.
I recommend Flickr.

Fix home and end keys in remote shell

$ od -c

<home key pressed>   ^[[7~
<end key pressed>    ^[[8~

Then put in /etc/inputrc or ~/.inputrc:

"\e[7~": beginning-of-line
"\e[8~": end-of-line

An actual example:

"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[3~": delete-char

(source)

Android: Don't refresh page when no signal

chrome://flags/#enable-offline-mode

and

chrome://flags/#enable-offline-load-stale-cache

Unfortunately this doesn't work anymore - those flags were experimental.
In fact I've switched to Firefox (which is also much faster on Android) because Chrome tabs kept annoyingly reloading when the phone had no signal.

Perl: Disable control-C and control-Z

$SIG{'INT'} = 'IGNORE'; # Ctrl-C
$SIG{'TSTP'} = 'IGNORE'; # Ctrl-Z

Bash script must run as root

# This script must be run as root

if [ "$(id -u)" != "0" ]; then
    echo "This script must be run as root" 1>&2
    exit 1
fi

svn basics, for git users

How to do stuff in subversion, when you're used to git:

# create a new branch
svn copy -m "Branching trunk" https://www.example.com/svn/repos/project/trunk https://www.example.com/svn/repos/project/branches/new_branch_name

# check out new branch
svn checkout https://www.example.com/svn/repos/project/branches/new_branch_name

# check status/diffs of working directory
svn status
svn diff

# show a specific commit
svn diff -c63197
svn diff -c63197 | vim -R -
svn diff -r63196:63197
svn diff -c63197 db/src/securesite/

# commit files
svn commit -m'Commit message' filename.ext

# see your changes after committing
svn update

# find where a branch was cut from trunk (svn equivalent of git mergebase)
# The last commit will be the first one in this branch after it was cut from trunk:
svn log -v --stop-on-copy

# cherry pick
svn merge -cXXXX trunk branch

# revert a commit
svn merge -c -REV .

Perl telnet script OR netcat

When you need to test using telnet, but don't have telnet installed, and you do have Perl:

use strict;
use warnings;

my $usage = "usage: $0 host port\n";

my $host = $ARGV[0] or die $usage;
my $port = $ARGV[1] or die $usage;

use Net::Telnet ();
my $t = new Net::Telnet (
        Port    => $port,
        Timeout => 5,
);
$t->open($host);

my $print_success = $t->print("GET / HTTP/1.0\n");
print "sent command: $print_success\n";

my @lines = $t->getlines(Timeout => 2);

print @lines;

OR an even easier way with netcat:

fprint "GET / HTTP/1.0\n\n" | nc host port

sudo doesn't list files properly

Problem:

You can list a directory using sudo:
$ sudo ls /var/log/apache/
access_log  error_log

But you can't list files with a wildcard using sudo:
$ sudo ls /var/log/apache/*_log
ls: cannot access /var/log/apache/*_log: No such file or directory

Solution:

Ensure parameter expansion happens in the shell run by sudo, not in the user's shell:
$ sudo bash -c 'ls /var/log/apache/*_log'

(source)

Test Kerberos authentication

vi /etc/krb5.conf
/opt/mitk5/bin/kinit [username]

Qemu console output

qemu-system-x86_64 -curses

No help here

Adblock rules

! Stackoverflow network sites
! Don't distract me please
##DIV[class="module community-bulletin"]
##DIV[id="chat-feature"][class="module"]
##DIV[id="hot-network-questions"][class="module"]

Make "x" use Data::Dumper in the Perl debugger

tldr:

$DB::alias{x} = 's/^x\s+(.*)/p Data::Dumper::Dumper($1)/';

Thanks Jim

Full article:

In the guts of the script that runs the Perl command-line debugger (accessible whenever you start a perl script with the '-d' command-line argument), there lives a hash, accessible globally as %DB::alias.  Whenever you enter a command at the debugger command line, the first word in the command is looked up in %DB::alias, and if it is found, the corresponding value is used as a substitution pattern against the entire command line.  The substituted line is then processed as usual.  The examples and explanation in the perldebug man page don't make this terribly clear.  The actual code that is executed by the debugger (after stuffing the first word in the command line into the variable $i) is:

eval "\$cmd =~ $alias{$i}";

This can be used to completely customize the debugger.  For example, the ordinary output of the debugger's built-in "x" command is pretty ugly.  Substituting a different formatter (such as Data::Dumper::Dumper) can be accomplished with the following alias:

$DB::alias{x} = 's/^x\s+(.*)/p Data::Dumper::Dumper($1)/';

This converts the line "x $something" into the line "p Data::Dumper::Dumper($something)".  Incidentally, solving this particular problem was the impetus for this blog post.
More extensive customization is possible.  For instance, alias substitution occurs once in the stock debugger.  Armed with the knowledge of how alias substitution works, you can create an alias that expands aliases iteratively like this:

my $in_exp = 0;
sub expand_db_aliases
{
     die "Recursively expanding the expansion alias" if $in_exp++;
     my $cmdref = shift;
     my $exp_cnt = 0;
     while($cmdref =~ /^(\S+)/ and $DB::alias{$1})
     {
          my $i = $1;
          die "Alias expansion exceeds 100 iterations" if $exp_cnt++ > 100;
          my $cmd = $$cmdref;
          package DB;
          eval "\$cmd = $alias{$i}";
          die $@ if $@;
          $$cmdref = $cmd;
     }
     $in_exp--;
} ;
$DB::alias{exp} = '//; expand_db_aliases(\$cmd);';

The heavy lifting is done in the expand_db_aliases subroutine, which matches the actual instructions used by the debugger to expand aliases as closely as possible.

Loading your customizations automatically

If there is a file named ".perldb" in your home directory, the Perl debugger will load it and interpret its contents as Perl code after it initializes itself.  You can put any code-based customizations you desire into this file.  You can (and should) also use this file to load any dependencies required by your customizations.  For the replacement "x" command, I added the following to my .perldb file:

use Data::Dumper;
$DB::alias{x} = 's/xx\s+(.*)/p Data::Dumper::Dumper($1)/';

Determine a day's ordinal suffix: 1st, 2nd, 3rd, 4th, etc.

e.g. for dates you don't want to display "19 July" but rather "19th July":

my $ordinal;
if ($foo =~ /(?<!1)1$/) {
    $ordinal = 'st';
} elsif ($foo =~ /(?<!1)2$/) {
    $ordinal = 'nd';
} elsif ($foo =~ /(?<!1)3$/) {
    $ordinal = 'rd';
} else {
    $ordinal = 'th';
}

Bonus points if you can integrate this with DateTime's strftime() method neatly.

(source)