Windows vs Linux Differences

Expected level: Working

Windows and Linux differ in small ways that cause real bugs when code or scripts move between them: path separators, case rules, line endings, permissions and tooling.

Quick comparison

Area Windows Linux
Path separator \ (many APIs also accept /) /
Roots Drive letters: C:\, D:\ One root: /
Case in file names Insensitive, preserves case Sensitive
Line endings CRLF (\r\n) LF (\n)
Path list separator (PATH) ; :
Permissions ACLs, elevation (UAC) Owner/group/other bits, sudo
Executables Extension decides (.exe, .ps1) The execute bit decides
Packages winget, MSI installers apt, dnf, …
Default shell PowerShell, Command Prompt Bash (or similar)
Environment variable syntax $env:NAME, %NAME% $NAME

What goes wrong in practice

  • Case sensitivity: import './Utils' works on Windows when the file is utils.js, and fails on Linux. Match the case of file names exactly, everywhere.
  • Hard-coded paths: "data\\config.json" or C:\temp breaks elsewhere. Use your language’s path-joining function and a temp-directory API instead of string concatenation.
  • Line endings: a shell script with CRLF fails on Linux with errors such as bad interpreter: /bin/bash^M. Let Git manage it: set core.autocrlf as your team prefers or use a .gitattributes file (for example *.sh text eol=lf). See Git Fundamentals.
  • Missing execute bit: a script committed from Windows may not be executable on Linux. git update-index --chmod=+x script.sh fixes it in the repository.
  • Reserved names and characters: files named aux, con or containing : cannot be created on Windows, even though Linux allows them.
  • Different commands: dir, type and copy are Command Prompt, Get-ChildItem is PowerShell, ls, cat and cp are Bash. See Command Line Basics.

Try it

In a Linux shell, create Test.txt and test.txt in one folder and list them. Try the same on Windows. Then find a script of yours, check its line endings with file script.sh, and see what a CRLF file does when you run it in WSL.

Common mistakes

  • Importing a file with the wrong case, which works on Windows and fails on Linux.
  • Hard-coding paths such as `C:\temp` instead of using path-joining and temp-directory functions.
  • Committing a shell script with CRLF endings, which fails on Linux with a `bad interpreter` error.
  • Forgetting the execute bit on a script committed from Windows.

Check yourself

  • Why can `import './Utils'` work on Windows and fail on Linux?
  • What does `bad interpreter: /bin/bash^M` mean, and how do you prevent it?
  • Which separator does the `PATH` variable use on each system?

Related topics

Terms

Further reading