Using XRDP, I am able to do all my development from my office now:
Once temperatures rise, this will be much nicer than doing this in the garage.
Conservative. Tennessee (now). Ex-Idaho. Software engineer. Historian. Trying to prevent Idiocracy from becoming a documentary.
Email complaints/requests about copyright infringement to clayton @ claytoncramer.com. Reminder: the last copyright troll that bothered me went bankrupt.
Using XRDP, I am able to do all my development from my office now:
I s pent most of my career using Unix for software development or being sys admin for a herdof Sun workstationx. Unix/Linux has many virtues.
A friend who is not technical has just switched from Windows 7 (don't laugh, he is moving his email from AOL after 36 years).. He wanted a regular backup of his files to a USB hard drive.
Okay, how hard can this be? Somewhere there is a program either GUI or shell-based that does this, right? Not that I could find. After a lot steps that brought back memories:
1. Set up mount of USB drive in /etc/mount. What? HNo atomount or autodiscovery? You run lsblk to see what devices are attached, determine which is the USB drive, copy its 8 hexadecimal digit UUID and several other close to magic fields. (I started to remember what UID and GID mean as I fiddled.)
You rediscover that mount is a very picky program. How many spaces between parameters, Running sudo mount -a may not identify errors, just silently fail. How would it be to make a mount editor that prompts you for the parameters ands adds them to /etc/mount?
3. The backup script using rsync was fairly straightforward.#!/bin/bash
# Mirror backup to USB drive (vfat friendly)
BACKUP_BASE="/mnt/usb-backup/Backups"
LOGFILE="$HOME/backup.log"
echo "$(date '+%Y-%m-%d %H:%M:%S') - Backup started" >> "$LOGFILE"
# Check if USB is mounted
if ! mount | grep -q " /mnt/usb-backup "; then
echo "$(date) - ERROR: USB not mounted at /mnt/usb-backup" >> "$LOGFILE"
echo "ERROR: Please run: sudo mount /mnt/usb-backup"
exit 1
fi
mkdir -p "$BACKUP_BASE"
# === Directories to mirror - Add more here if needed ===
declare -A DIRS=(
["/home/$(whoami)/Documents"]="$BACKUP_BASE/Documents"
["/home/$(whoami)/Pictures"]="$BACKUP_BASE/Pictures"
)
echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting rsync mirror..." >> "$LOGFILE"
for src in "${!DIRS[@]}"; do
dest="${DIRS[$src]}"
if [ -d "$src" ]; then
echo "→ Mirroring $src" | tee -a "$LOGFILE"
mkdir -p "$dest"
rsync -aAX --delete --info=progress2,stats2 "$src/" "$dest/" >> "$LOGFILE" 2>&1
else
echo "Warning: $src not found" >> "$LOGFILE"
fi
done
echo "$(date '+%Y-%m-%d %H:%M:%S') - Backup completed successfully" >> "$LOGFILE"
echo "✅ Backup finished successfully!"
echo "Log saved to: $LOGFILE"
Adding an entry to crontab was simpler than mount but it still screams for a tool to help you add an entry. Some of why Linux remains user-indifferent is that for a lot of geeks it is the same theory as stick shifts: "It keeps the riff-raff out."
I was was eventually able to install version 2.7.14. I think the ISO was not written correctly first time. Upgrading to latest version seems too hard. 2.7.14 is ancient history but it works.
I had saved my .emacs, .ddd, and .bashrc files along with all my programs and then restored them. But lots of things stopped working. The lisp commands in my .emacs file are not running. make no longer works.
gcc - -g -o mkcircle mkcircle.c -lm
gcc: error: -E or -x required when input is from standard input
make: *** [mkcircle] Error 1
Since when did gcc require these flags?
UPDATE: the compile problem was that I accidentally changed CFLAGS=-g to CFLAGS= -g. That space confused accidentally pretty badly.
My emacs lisp commands are still confused. The binding to compile command is not using directory from which emacs started. I am getting close.
And linuxCNC has some setting for maximum Z wrong.
I have battled a little with my LinuxCNC PC somewhat randomly changing its IP address, even without a reboot. This is odd because DHCP usually reserves the association for some period of time based on the original DHCP request. (This is my memory of porting a DHCP server at a startup for which I worked.)
I finally broke down and fiddled with /etc/network/interfaces/ to tell it to go static. No more fiddling with IP address in FileZilla!
Also, LinuxCNC is notoriously picky about WiFi cards and there is no practical way to run Ethernet to the shop. I finally found a 1300AC WiFi card that is plug'n'play a while back. The data rate has never been impressive. I suspect because line of sight from tower to router goes through the refrigerator. I typically have been seeing 5.5 Mbps. This is adequate for my needs but it seems absurdly slow. So this afternoon, I thought, "What if I move it from the front of tower to the USB port at the rear.? 11 Mbps. The WiFi came with an extension USB cable. Using that and raising in the air gave a slight hint that performance might improve a few feet higher or east of the fridge. I think I have a male USB-A to USB-A cable here somewhere. If it a few feet longer, I may try it.
My cellphone in the same location gives 90 Mbps. This WiFi adapter may just be a bit limited.
It has been almost 20 years since I made heavy use of Unix, but I vaguely recall a construct in some shell where you could
ls {circle*|mkcircle*}
and have it match every file of those two wildcard matches. I cannot find that in any reference work. Was that just an imagined capacity because I wanted it?
I see no point battering my head against OpenSSH. However, I have reached the point where:
smbclient //192.168.4.42/linuxcnc -U clayton%mypassword
gives me access to the Windows directory. Butsudo mount -t cifs -o claytoncramer@192.168.4.42 /mnt/linuxcnc
asks for the same password and rejects it.
Several syntax errors in the mount command. Solved. I wish Linux utilities were a little more specific about where and what is the error.
Then I discovered that I could not write in linuxcnc from Linux. I verified permissions were wide open on Windows and 777 on linuxcnc. It turns out the /etc/fstab entry needed file_mode=0777,dir_mode=0777 as well. Before I forget all this, I need to reboot Linux and make sure it still works.
Yes, I know, RCS is obsolete. I should burn the time learning to use git. But I am a single user and git is already lookimg daunting. I spent much of my career using and maintaining RCS.
All the documents say that RCS's repository is in the RCS directory below current directory. rcs ci -i filename puts nothing in RCS directory. What am I doing wrong?
Never mind. I found a simple git tutorial.
Windows Subsystem for Linux (WSL) is actually sufficiently Linux to run and install many linux commands such as gcc, make, and ddd. This is not a port of Unix tools to Windows but apparently genuine Ubuntu Linux.
I battled endlessly trying to get VMWare and Oracle VirtualBox to run linuxCNC on my PC, so that I code stuff in the cool of the house before ftping it to the shop.
This is sufficient. I can code and debug in the house. It would be nice to run linuxCNC for testing operation in the linuxCNC GUi, but this is good enough.
This should not be this hard. I want to do a while loop on the condition "$xstart < $xend"
while [ "$xstart < $xend" ]
do
...
done
I know that to do a float compare, I need something like
echo "$xstart > $xend" | bc -l
returning a boolean.
Found it:
while [ "$(bc <<< "$xstart < $xend")" == 1 ];
There seem to be no simple explanations that I can find. All add more brackets and parentheses to accomplish what?
if [[ ($yremaining+$millradius \> $yend) ]]; then
I want to see if yremaining + millradius is greater than yend.\
Conditional binary operator expected.
The answer seems to be
Corrected version (as text):
if (( yremaining + millradius > yend )); then
echo "Condition met"
fi
I cannot believe how much I have forgotten. My first three years at HP was maintaining, optimizing, and then factoring a 6000 line bash script.
If 6000 lines in one script sounds stupid, yes it was. It was test tool that verified the functionality of the LaserJet firmware before we loaded into test mules. Eventually, I factored it into several scripts each of which was still too large, but were at least comprehensible as to function.
This should not have been so hard. Many good suggestions. I decided to make a bash script that accepts two strings and returns an exit code (-1, 0, 1 for <,==,>).
Of course, when you echo $?, because the exit code is returned as an unsigned byte it is 255. This lets me do this test in multiple places with little pain.
#!/bin/bash
# rel: calculate <,==,> for two float strings
calculatedx=`echo $1 | bc -l`
calculatedy=`echo $2 | bc -l`
value=`echo "$1 < $2" | bc -l`
if [[ $value -eq 1 ]]; then
exit -1
fi
value=`echo "$1 > $2" | bc -l`
if [[ $value -eq 1 ]]; then
exit 1
fi
value=`echo "$1 == $2" | bc -l`
if [[ $value -eq 1 ]]; then
exit 0
fi
rel '20+.1' 21
echo $?
1
My efforts to get this working reliably in either bash or perl being unavailing, I wrote a program in C:
#include <stdio.h>
#include <float.h>
#include <stdlib.h>
int main (int argc, char* argv[])
{
if ((argc >= 4) || (argc < 2))
{
fprintf(stderr, "rel needs two arguments, both float\n");
exit (4);
}
float arg1;
if (1 != sscanf(argv[1], "%f", &arg1)) {
printf("invalid argument %s\n",
argv[1]);
exit(4);
};
float arg2;
if (1 != sscanf(argv[2], "%f", &arg2)) {
printf("invalid argument %s\n",
argv[2]);
exit(4);
}
if (arg1 < arg2)
{
fprintf(stderr, "<\n");
exit(-1);
}
else if (arg1 == arg2)
{
fprintf(stderr, "==\n");
exit(0);
}
else
{
fprintf(stderr, ">\n");
exit(1);
}
}
Okay, the writes to stderr produce a flood of useless messages but I wanted to see what was happening.
I just installed Linux Cinnamon dual boot on my old laptop and indeed it is very speedy compared to Windows 10. But the TP-Link USB WiFi adapter is not recognized. Okay, it is a year or two old, so I should not expect Linux to recognize it but searching the web for how to install drivers for it has been so far fruitless. I am blogging through an Ethernet cable. I understand sudo apt update etc. and roughly understand git's purpose, but I would not expect any non-techie to have a clue how to get WiFi working.
This seems to indicate that they are not available.
I had another clunkier TP-Link USB adapter which came right up. It is not AC1300 but it works.
The AC1300 does not work in the Linux box in the workshop either. LinuxCNC recognizes it as WiFi but that is as far as it goes. It does not appear as though a/b/g/n work, much less ac.
I think that I am getting this, finally.
I started with th example and some graph paper.
%
g1 g20 g40 f500
g0 x0 y0 f500
g0 y1 f500
g0 y0 f500
g0 x-1 f500
g1 x1 f500
g1 x0
g1 y-1 f500
g0 x0 y1 f500
g2 x1 y0 i0 j-1 f500
g2 x0 y-1 i-1 j0 f500
g1 x0 y0 f250
m2
%
No, I am not cutting 2500 ipm. That might work on air, who knows? But the backplot feature of linuxCNC was taking forever. I altered MAX_VELOCITY in the config file. I am running linuxCNC in VirtualBox.
But VirtualBox seems to work. Of course, I screwed up enough to reinstall. I had some memory of the install on the PC in the shop asking me to create a username and password. It does not seem to under VirtualBox.
I see why now. I was running Live not Install. It is not terribly reliable on boot.
It looks like I need to reinstall and then:
sudo useradd -m clayton
sudo passwd clayton