DOS vs UNIX - The War rages on


Every mainstream modern OS shares DNA with one or both of those ancient behemoths.  OSX, Android, iOS, Linux - all stem from the Clan UNIX, Windows 11 is the great-great-great grandchild of DOS.  


A single character has fundamentally acted as a dividing force for decades, causing incompatibles and crashes where-ever and when-ever the problem occurred.  That, dear friends, is the ASCII character that was used for a new line. 


UNIX uses "Line Feed" (or "New Line") - ASCII 10.  Hex code 0A.  Escape code "\n"


DOS uses Line Feed and also the extremely Victorian sounding "Carriage Return" - ASCII 13.  Hex code 0D. Escape code "\r" 


The reason they both sound very type-writer related, is because they are.  


"Carriage return" sent the print head back to the left hand side of the page, while "Line Feed" scrolled the paper up one line.   You needed both. 


With the shift to text on a screen rather than paper, DOS kept both "\r\n"   UNIX, trying to be more efficient said "We just need a new line" and just kept "\n" 


This has caused immeasurable problems over the years trying to move files between the systems, and certainly in the 1980s and early 1990s, the two systems were seen as so incompatible that it was rare for files to be shared between them.  (It didn't help that floppy disk formats weren't the same either, so it was physically difficult to move files around) 


With the onset of the mainstream Internet, filesharing obviously became a big deal and, after a few years, the problem seemed to go away.  Many systems auto-compensate these days and will kind of translate between the two formats.  


I literally hadn't thought about it in decades. Until today.  I had a simple shell script running on my Linux server (Debian 12) which is supposed to use the flatbed scanner to scan to a jpeg file, setting the filename to scan_[date].jpg  - simple, right?  Except the filename was getting absolutely scrambled.  I removed the scanning code so the script was just this test code:  


timestamp=$(date '+%Y%m%d_%H%M%S')

extension=".jpg"

echo "Timestamp: $timestamp"

filename="scan_$timestamp$extension"

echo "Filename: $filename"

echo "Saved and tagged: $filename"

Nothing could go wrong with that - surely ?!  

And yet, running datetest.sh would produce this output

Timestamp: 20250823_090932

.jpgname: scan_20250823_090932

.jpgd and tagged: scan_20250823_090932

(You can see where this is going, right?)  So eventually I did a  "cat - v datetest.sh" (the -v is short for 'verbose' - so it shows all hidden ASCII characters. That output showed this:

timestamp=$(date '+%Y%m%d_%H%M%S')^M

extension=".jpg"^M

echo "Timestamp: $timestamp"^M

filename="scan_$timestamp$extension"^M

echo "Filename: $filename"^M

echo "Saved and tagged: $filename"^M

The ancient oversized digital penny dropped.  I had created the script on a Windows laptop in notepad, then SCP-ed it over to my Linux machine, and for whatever reason it doesn't handle the additional carriage return (^M) character in shell scripts.  So I used a command I used to use all the time, but never thought I'd have to run again: 


dos2unix datetest.sh


And with that, it as fixed. 


The additional carriage return characters purged, the script runs perfectly. 


The moral of the story - modern operating systems come and go, with their ultra-high resolution, multi screen graphical user interfaces, augmented reality gesture control, voice commands, AI assistants and predictive algorithms - but ultimately they're still just fancy typewriters. 




Comments