Dos To Unix Command

Dos To Unix Command

Reading time1 min
#IT#Scripting#CrossPlatform#Unix#DOS#CommandLine

Mastering DOS to Unix Command Line Transitions: Techniques for Real-World Cross-Platform Operations

Misinterpreted command lines can trigger silent failures and data loss, especially during migration or hybrid operations. Anyone involved in maintaining mixed Windows (cmd.exe, PowerShell) and Unix-like (Linux, BSD, macOS) systems will eventually run into these hazards. A partial script port, a careless path typo, or the wrong command flag—impact can range from mere annoyance to halted CI/CD pipelines.


Problem Statement: One Script, Two Worlds

Consider a migration project: Windows batch scripts automate data archival, but new workloads are moving to a Linux-based environment. The original batch file assumes %USERNAME% and path delimiters as \. Unix sees those and can’t resolve paths or variables, aborts with errors, or worse—silently truncates data. Simple as it sounds, even the classic:

COPY C:\data\*.* D:\backup\

fails when naively converted as:

cp C:\data\*.* D:\backup\

Yield: cp: cannot stat 'C:\data\*.*': No such file or directory.


DOS vs. Unix Command Line—Operational Differences

The devil is in the details. Table summarizing operational differences:

FeatureDOS/WindowsUnix/Linux
Path Separator\/
Case SensitivityInsensitiveSensitive
Variables%VAR%$VAR
Switch Prefix/-/--
Home Directory%USERPROFILE%$HOME or ~
Wildcards* ? (some shell limitations)* ? [] {} (globbing rules)
Built-insDIR, COPY, MOVEls, cp, mv
Scripting extension.bat or .cmd.sh

Note: PowerShell has its own nuances ($env:VAR, \ paths, etc.), and WSL/MinGW/Cygwin blur lines further.


Command Equivalents and Syntax Adjustments

Real-world scripts rarely stick to trivial patterns. Still, the following equivalence table helps when retrofitting job steps or CI runners:

TaskWindows CommandUnix Command
List directoryDIRls -al
Change directoryCD pathcd path
Copy file(s)COPY src dstcp src dst
Delete fileDEL filerm file
Move/RenameMOVE old newmv old new

Gotcha: Windows COPY won’t handle directories recursively (use XCOPY src dst /E /I), while Unix cp -r is the standard. Path normalization is not automatic between environments.

Example: Converting a Backup Script

Batch:

@echo off
set SRC=C:\data
set DST=D:\backup
xcopy %SRC%\*.* %DST% /E /I

Bash:

#!/bin/bash
SRC="/data"
DST="/backup"
cp -r "$SRC/"* "$DST/"

Trade-off: Recursive copy in Unix is explicit, and globbing matches dotfiles only with shopt -s dotglob (Bash, 4.0+)—not a perfect translation.


Scripting Differences That Bite

Loops

  • Batch:
    FOR %%f IN (*.csv) DO TYPE %%f >> all_data.txt
    
  • Bash:
    for f in *.csv; do cat "$f" >> all_data.txt; done
    

Known issue: Batch variables (%%) vs. shell expansion. Batch error-handling (ERRORLEVEL) doesn’t map directly to $? or set -e in shell scripts.

Environment Variables

Echoing variables breaks if you forget syntax:

  • Batch: %COMPUTERNAME%
  • Bash: $HOSTNAME

Migrating scripts that reference environment variables is a common failure point.


Translating Paths: Details Matter

  • Remove drive letters. Map logical drives to mount points (example: D:\/mnt/d with WSL, or custom mounts in fstab).
  • Replace backslashes with forward slashes.
  • Watch for spaces in filenames—wrap in quotes, or prefer tab-completion.

Practical Example:

Batch:

C:\Users\admin\Documents\My Files\

Bash:

/home/admin/Documents/My\ Files/

Or, for interoperability (spaces):

/home/admin/Documents/"My Files"/

Carriage Return Gotchas: dos2unix Utility

Migrated scripts sometimes throw:

bash: ./deploy.sh: /bin/bash^M: bad interpreter: No such file or directory

Cause: Windows line endings (CRLF) vs. Unix (LF).

Fix:

dos2unix deploy.sh

Alternative: Use sed -i 's/\r$//' deploy.sh for a one-liner.


Non-Obvious Pitfalls

  • Case Sensitivity: Don’t assume readme.txt and README.txt are the same.
  • Permissions: Unix requires chmod +x script.sh for executables.
  • Trailing Slashes: rm -rf /tmp/dir versus rd /s /q C:\tmp\dir.
  • Wildcards: del *.log in Windows vs. rm *.log—but Bash patterns are more powerful (e.g., rm *.{log,txt}).

Tooling Strategies

When true cross-platform scripting is required:

  • PowerShell Core (>= 7.x): Nearly identical across Windows/macOS/Linux, but syntax differs from CMD and Bash.
  • WSL2 (Windows 10/11): Native Linux compatibility, avoids most path issues but still requires context switching.
  • Cygwin/MSYS2: Offers GNU toolchain on Windows, but not always portable to pure Linux.
  • git-bash: Suitable for lightweight Unix commands in Windows-centric DevOps workflows.

Side Note: Not all Windows subsystems handle signals (e.g., SIGINT) or device files the Unix way—build guards into your scripts if signals or device paths matter.


Transition Checklist

  • Map command equivalents: Create a conversion chart for your environment.
  • Normalize paths: Use scripts or text editor macros to convert path delimiters in bulk.
  • Convert line endings: Run dos2unix after code checkout or transfer.
  • Verify variables: Lint scripts for variable reference mismatches.
  • Test under native shell: Don’t trust Cygwin/WSL/PowerShell emulation for production validation.
  • Document known workarounds: Not every construct is portable—keep notes for the next engineer.

Final thought: Cross-platform command line work is rarely perfect. Allow time for iterative adaptation; test edge cases (strange filenames, deep paths, permissions) and document what breaks and why. Gaps will emerge—track them and revisit with each major OS or shell update.