I’ve always done almost everything from the terminal. Way back from CP/M through Windows 95, XP, 7, and now 10, and all the random Linux variations I played with. Oh, and Sun OS at University, but I dunno if that counts here.
Clicking through a gazillion menus (folders) to do anything at all is truly obnoxious. I can fire up my terminal prompt and have everything at my fingertips.
As an aside, I can’t stand PowerShell. It took the terminal idea and goobered it to be as painful as possible.
The key to using the terminal is managing your
PATH
. The next is to keep utilities handy. I set my terminal startup to automatically run
C:\Users\Michael\bin\prompt.bat
, which is actually pretty simple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
@echo off
cls
path C:\Users\Michael\bin;%PATH%
chcp 65001 > nul
if "%ConEmuDir%"=="" (
prompt $E[33;1m$P$G$E[90m
)
set DIRCMD=/ogn
:: Macro Aliases
doskey apath=for %%F in ($1) do @path %%~fF;%%PATH%%
doskey mpath=for %%A in ("%%PATH:;=";"%%") do @if not "%%~A"=="" @echo %%~A
doskey rpath=for %%F in ($1) do @for /F "usebackq delims=" %%M in (`echo set "PATH=%%PATH:%%~fF=%%"`) do @%%M
doskey deltree=rd/s/q $*
doskey dira=dir/a $*
doskey dird=dir/a-hd $*
doskey mcd=@md $* $T @cd $*
doskey 7z="C:\Program Files (x86)\7-Zip\7z.exe" $*
doskey npp="C:\Program Files (x86)\Notepad++\Notepad++" $*
... and so on.
| |
`doskey` is the Windows version of the *nix `alias`. It works a little differently, though, so make sure to type help doskey
before you use it. (And it is a much easier read than searching through man bash
to read up on alias
.)
Then I populate my
C:\Users\Michael\bin directory with a bunch of useful little batch files. For example, I can look at all my macros (aliases) with:
C:\Users\Michael\bin\macros.bat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
::if 0 {
@echo off
tclsh "%~f0" %*
goto :EOF
}
set f [open "|doskey /macros"]
set s [read $f]
if {[catch {close $f} err]} {
puts $err
exit
}
set lines []
set max 0
foreach line [lsort -dictionary [split $s \n]] {
if {$line eq {}} continue
lassign [split $line "="] alias command
lappend lines [list $alias $command]
set max [expr {max($max, [string length $alias])}]
}
foreach alias_command $lines {
lassign $alias_command alias command
puts "[format %${max}s $alias] = $command"
}
| |
C:\Users\Michael> macros
7z = "C:\Program Files (x86)\7-Zip\7z.exe" $*
apath = for %F in ($1) do @path %~fF;%PATH%
astyle = C:\m\bin\AStyle\bin\astyle.exe -A1 -s2 $*
blender = title blender 3.0 $T "C:\Program Files\Blender Foundation\Blender 3.0\blender.exe" $*
npp = "C:\Program Files (x86)\Notepad++\Notepad++" $*
... |
In order to keep the path clean when
programming, I’ll actually
nest invocations of
cmd.exe. So, for example, I can type:
C:\Users\Michael> msvc x64 |
and
C:\Users\Michael\bin\msvc.bat will start a new shell in the same terminal (
cmd /k ...
) and find and run
vsvarsall.bat for an AMD-64 toolchain. (
msvc.bat is actually rather lengthy, being both DOS batch script
and being smart enough to complain if it has already been invoked
and being able to find and invoke the correct
vsvarsall.bat script — I have multiple versions of VS installed.)
That way when I am done I can get back to a “clean” prompt by simply typing
exit
. Here’s a useful script to report how many times the command shell has been nested for a particular terminal:
C:\Users\Michael\bin\levels.bat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
::if 0 {
@echo off
::
:: Report the number of cmd.exe processes running in this Windows Console window
:: (You can 'exit' n-1 times before this Windows Console closes.)
::
set source=%~f0
if exist %source%.bat set source=%source%.bat
tclsh %source% %*
goto :EOF
}
set pss [exec {*}[auto_execok wmic] process get processid,parentprocessid,executablepath]
foreach ps [split $pss \n] {
lassign [lreverse [string map {\\ /} $ps]] pid ppid exename
set PARENTS($pid) $ppid
set EXES($pid) [file tail $exename]
}
set p [pid]
set n 0
while {$p in [array names PARENTS]} {
if {$EXES($PARENTS($p)) ne "cmd.exe"} break
incr n
set p $PARENTS($p)
}
puts $n
| |
You may have noticed that I tend to use
tclsh
(Tcl shell) for a lot of useful stuff when DOS batch is either insufficient or just too obnoxious and clumsy. It doesn’t really matter
which shell/interpreter you recur to —
VisualBasicSript is already installed on Windows systems and you could use that —
Python is also a useful alternative. Heck, you could even make
PowerShell scripts if that floats your boat. You could even compile little C++ programs to do stuff. The point is to have useful tools.
All this can be easily duplicated in a Linux prompt. I have WSL2 up and running (complete with an X Server so I can run graphical Linux programs from the Ubuntu prompt as well). I add aliases to my
~/.bashrc (or
~/.profile, if needed) to make switching between the two easy and convenient.
For example, I use
Notepad++ regularly. Since it is a Windows program (and because notepadqq is currently garbage, sorry), I add it to my list of aliases.
~/.bashrc snippet
1 2 3 4 5
|
...
alias dir='ls -CF --color'
alias dira='ls -A'
alias npp='/mnt/c/Program\ Files\ \(x86\)/Notepad\+\+/Notepad\+\+.exe'
...
| |
Now, whether I am on Windows or Linux, I can simply type:
npp somefile.cpp
to begin editing
somefile.cpp.
One interesting trick is to
automagically add a utility to the path when it is first used. For example:
C:\Users\Michael\bin\python.bat
1 2 3
|
@echo off
path C:\Python37\Scripts;C:\Python37;%PATH%
python.exe %*
| |
Now I don’t have to care whether
Python is already in the path or not. I just type
python quux.py
and
quux.py runs properly, every time.
This works because the
python.bat is initially the only thing found in the
PATH
, but after executing it, it is now listed
after the actual
python.exe executable in the
PATH
, so it never gets called by mistake.
Once you get everything set up, open a terminal and type
mpath
and look at all the junk in there. A lot of it can be removed. For example, I don’t need
C:\gtkmm64\bin sitting in there. (I should have
properly installed any programs using GTK!) Copy and save the list somewhere before the next step:
Click on
Start (or the little hourglass on Windows 10) and type “environment variables” to get a suggestion to edit the system environment variables. (Where this actually is differs on Windows versions, so use the finder to find it.)
Be careful how aggressively you cull stuff from the list. In general,
do not remove stuff from the global environment variables —
especially anything in any subdirectory of
C:\Windows! But feel free to remove anything you want from the
local user’s (your) environment variables. If something you want stops working, you can add it back. (You
did copy and save your original list, right?)
A lot of programs just add themselves to the path when they install, even when they don’t need to. Sometimes you will find stuff listed multiple times. And you will occasionally find something weird, like multiple semicolons. Feel free to fix all that, until
mpath
gives you a short, pretty list of
essential items, with your
bin directory listed right at the top.