More ways to help Linux users hate Windows less

Evil Computer Laptop - Openclipart

Ok, so obviously if you hate Windows, you probably just shouldn’t be using it. But what if you love the way Linux operates, but have a plethora of Windows-only applications you have to have at your fingertips at any moment’s notice?

Here are some ways the discerning Linux user who’s stuck by vendor lock-in can make Windows a little more palatable in the command line:

1) Install a package manager.

If you haven’t already, install Chocolatey package manager for Windows https://docs.chocolatey.org/en-us/choco/setup

Don’t even bother reading up on it, just do it. Chocolatey is the most accepted and proliferate package manager for Windows. There’s other options out there, but none that have as many packages, or that have as large of a community.

Almost anything you can imagine has been packaged using it, it can automatically manage their updates (with varying success), and it’ll give you an all-in-one place to install and uninstall software, (almost) just like using a Linux distro.

The basic commands are choco search <packageName>, choco install <packageName> and choco uninstall <packageName>. There’s also choco info <packageName> to read a package’s description, and choco list --local-only to list all the software you’ve installed using it.

Easy, right? You’ll be feeling more at home in no time. If you’re looking for a GUI management tool, there’s one of those, too, but it kind of defeats the purpose: https://community.chocolatey.org/packages/ChocolateyGUI

2) Get git-bash and put its posix tool folders in your %PATH%:

A while back I wrote a post on PowerBash, and while it had some nice features, they were limited, worked with varying success, and you had to be in PowerShell to use them.

Before that, I had written about git-bash and how awesome it is, but using its posix utilities appeared to be relegated to only its terminal.

Well, now I found a way you can use the posix utils in any terminal, regardless of what kind it is!

Now that you have Chocolatey installed, you can install git-bash by invoking the following in an administrative terminal – if you haven’t installed git-bash, you are totally missing out, so do this now:

 choco install -y git

Now that you have git-bash installed, add its primary posix util folders to your path, like this (must be administrative command prompt):

setx /m '%PATH%;C:\Program Files\Git\bin;C:\Program Files\Git\usr;C:\Program Files\Git\usr\bin;C:\Program Files\Git\usr\libexec;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\mingw64\libexec\git-core'

As always, you can check your path in Windows with:

echo %PATH%

Here’s mine as an example from cmd:

C:\>echo %PATH%
C:\Python39\Scripts\;C:\Python39\;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\ProgramData\chocolatey\bin;C:\Program Files\Git\cmd;C:\Program Files\PowerShell\7\;C:\Program Files\Microsoft VS Code\bin;C:\Program Files\OpenSSH-Win64;C:\Program Files\Git\bin;C:\Program Files\Git\usr;C:\Program Files\Git\usr\bin;C:\Program Files\Git\usr\libexec;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\mingw64\libexec\git-core;C:\ProgramData\chocolatey\lib\mpv.install\tools;C:\tools\BCURRAN3;C:\Program Files\Go\bin;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VisualStudio\NodeJs;C:\Program Files\CMake\bin;C:\Program Files (x86)\ClockworkMod\Universal Adb Driver;C:\Users\avery\bin\cmdline-tools\bin;C:\Program Files\Java\jdk1.8.0_211\bin;C:\Android\android-sdk\tools;C:\Android\android-sdk\platform-tools;C:\Android\android-sdk\tools\bin;C:\Program Files (x86)\dotnet\;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VisualStudio\NodeJs\;%PATH;C:\Program Files (x86)\gedit\bin;C:\Program Files\Microsoft VS Code;C:\Users\avery\.dotnet\tools;C:\ProgramData\chocolatey\lib\psutils\tools\psutils-master\;C:\Users\avery\AppData\Roaming\npm

By putting the posix tools from git-bash in your %PATH%, you can use pretty much all of them the same way as on a Linux machine, in any type of terminal window – cmd.exe, pwsh.exe, bash.exe – and they’ll be available in any current working directory. Most of them work just fine, you just have to remember to use backslashes for directories instead of forward slashes if you’re in cmd or powershell, but git-bash even uses forward slashes for maximum comfort and compatibility.

All your favs are there – ssh scp sed sha256sum grep which sort cat cut awk gawk vim nano ls rm wc du df less more etc. The only one I can think of that doesn’t work correctly is the find command – probably because it creates a command conflict with the MS-DOS equivalent (here’s proof):

C:\>which find
/c/Windows/system32/find

If you want to install tree, that’s not included, but now you can install it with:

C:\>choco install tree

And if you were discerning enough to search for sudo, you’d notice that was there, too, allowing you to install software from a non-administrative prompt (requires UAC administrative privileges).

Here’s the tree of the git-bash usr/bin dir – check it out, it’s pretty comprehensive!:

$ tree usr/bin | grep .exe

$ tree usr/bin | grep .exe
|-- [.exe
|-- arch.exe
|-- awk.exe
|-- b2sum.exe
|-- base32.exe
|-- base64.exe
|-- basename.exe
|-- basenc.exe
|-- bash.exe
|-- bunzip2.exe
|-- bzcat.exe
|-- bzip2.exe
|-- bzip2recover.exe
|-- captoinfo.exe
|-- cat.exe
|-- chattr.exe
|-- chcon.exe
|-- chgrp.exe
|-- chmod.exe
|-- chown.exe
|-- chroot.exe
|-- cksum.exe
|-- clear.exe
|-- cmp.exe
|-- column.exe
|-- comm.exe
|-- cp.exe
|-- csplit.exe
|-- cut.exe
|-- cygcheck.exe
|-- cygpath.exe
|-- cygwin-console-helper.exe
|-- d2u.exe
|-- dash.exe
|-- date.exe
|-- dd.exe
|-- df.exe
|-- diff.exe
|-- diff3.exe
|-- dir.exe
|-- dircolors.exe
|-- dirmngr-client.exe
|-- dirmngr.exe
|-- dirname.exe
|-- dos2unix.exe
|-- du.exe
|-- dumpsexp.exe
|-- echo.exe
|-- env.exe
|-- envsubst.exe
|-- ex.exe
|-- expand.exe
|-- expr.exe
|-- factor.exe
|-- false.exe
|-- fido2-assert.exe
|-- fido2-cred.exe
|-- fido2-token.exe
|-- file.exe
|-- find.exe
|-- fmt.exe
|-- fold.exe
|-- funzip.exe
|-- gapplication.exe
|-- gawk-5.0.0.exe
|-- gawk.exe
|-- gdbus.exe
|-- gencat.exe
|-- getconf.exe
|-- getfacl.exe
|-- getopt.exe
|-- gettext.exe
|-- gio-querymodules.exe
|-- gkill.exe
|-- glib-compile-schemas.exe
|-- gobject-query.exe
|-- gpg-agent.exe
|-- gpg-connect-agent.exe
|-- gpg-error.exe
|-- gpg-wks-server.exe
|-- gpg.exe
|-- gpgconf.exe
|-- gpgparsemail.exe
|-- gpgscm.exe
|-- gpgsm.exe
|-- gpgsplit.exe
|-- gpgtar.exe
|-- gpgv.exe
|-- grep.exe
|-- groups.exe
|-- gsettings.exe
|-- gzexe
|-- gzip.exe
|-- head.exe
|-- hmac256.exe
|-- hostid.exe
|-- hostname.exe
|-- iconv.exe
|-- id.exe
|-- infocmp.exe
|-- infotocap.exe
|-- install.exe
|-- join.exe
|-- kbxutil.exe
|-- kill.exe
|-- ldd.exe
|-- ldh.exe
|-- less.exe
|-- lessecho.exe
|-- lesskey.exe
|-- link.exe
|-- ln.exe
|-- locale.exe
|-- locate.exe
|-- logname.exe
|-- ls.exe
|-- lsattr.exe
|-- mac2unix.exe
|-- md5sum.exe
|-- minidumper.exe
|-- mintty.exe
|-- mkdir.exe
|-- mkfifo.exe
|-- mkgroup.exe
|-- mknod.exe
|-- mkpasswd.exe
|-- mktemp.exe
|-- mount.exe
|-- mpicalc.exe
|-- msgattrib.exe
|-- msgcat.exe
|-- msgcmp.exe
|-- msgcomm.exe
|-- msgconv.exe
|-- msgen.exe
|-- msgexec.exe
|-- msgfilter.exe
|-- msgfmt.exe
|-- msggrep.exe
|-- msginit.exe
|-- msgmerge.exe
|-- msgunfmt.exe
|-- msguniq.exe
|-- mv.exe
|-- nano.exe
|-- nettle-hash.exe
|-- nettle-lfib-stream.exe
|-- nettle-pbkdf2.exe
|-- ngettext.exe
|-- nice.exe
|-- nl.exe
|-- nohup.exe
|-- nproc.exe
|-- numfmt.exe
|-- od.exe
|-- openssl.exe
|-- p11-kit.exe
|-- passwd.exe
|-- paste.exe
|-- patch.exe
|-- pathchk.exe
|-- perl.exe
|-- perl5.32.1.exe
|-- pinentry-w32.exe
|-- pinentry.exe
|-- pinky.exe
|-- pkcs1-conv.exe
|-- pldd.exe
|-- pluginviewer.exe
|-- pr.exe
|-- printenv.exe
|-- printf.exe
|-- ps.exe
|-- psl.exe
|-- ptx.exe
|-- pwd.exe
|-- readlink.exe
|-- realpath.exe
|-- rebase.exe
|-- recode-sr-latin.exe
|-- regtool.exe
|-- reset.exe
|-- rm.exe
|-- rmdir.exe
|-- rnano.exe
|-- runcon.exe
|-- rview.exe
|-- rvim.exe
|-- scp.exe
|-- sdiff.exe
|-- sed.exe
|-- seq.exe
|-- setfacl.exe
|-- setmetamode.exe
|-- sexp-conv.exe
|-- sftp.exe
|-- sh.exe
|-- sha1sum.exe
|-- sha224sum.exe
|-- sha256sum.exe
|-- sha384sum.exe
|-- sha512sum.exe
|-- shred.exe
|-- shuf.exe
|-- sleep.exe
|-- sort.exe
|-- split.exe
|-- ssh-add.exe
|-- ssh-agent.exe
|-- ssh-keygen.exe
|-- ssh-keyscan.exe
|-- ssh-pageant.exe
|-- ssh.exe
|-- sshd.exe
|-- ssp.exe
|-- stat.exe
|-- strace.exe
|-- stty.exe
|-- sum.exe
|-- sync.exe
|-- tabs.exe
|-- tac.exe
|-- tail.exe
|-- tar.exe
|-- tclsh.exe
|-- tclsh8.6.exe
|-- tee.exe
|-- test.exe
|-- tic.exe
|-- tig.exe
|-- timeout.exe
|-- toe.exe
|-- touch.exe
|-- tput.exe
|-- tr.exe
|-- true.exe
|-- truncate.exe
|-- trust.exe
|-- tset.exe
|-- tsort.exe
|-- tty.exe
|-- tzset.exe
|-- u2d.exe
|-- umount.exe
|-- uname.exe
|-- unexpand.exe
|-- uniq.exe
|-- unix2dos.exe
|-- unix2mac.exe
|-- unlink.exe
|-- unzip.exe
|-- unzipsfx.exe
|-- users.exe
|-- vdir.exe
|-- view.exe
|-- vim.exe
|-- vimdiff.exe
|-- watchgnupg.exe
|-- wc.exe
|-- which.exe
|-- who.exe
|-- whoami.exe
|-- winpty-agent.exe
|-- winpty-debugserver.exe
|-- winpty.exe
|-- xargs.exe
|-- xgettext.exe
|-- xxd.exe
|-- yat2m.exe
|-- yes.exe
|-- zipinfo.exe

There’s even this cute little df replacement called dfc I like to use in Linux for a more graphical representation of hard drive usage – it’s called duf in Windows (slightly truncated for formatting purposes):

Or htop which is called ntop in Windows:

See, now Windows isn’t so bad after all, is it?

The GRUB prompt: Demystified

Frustrated Computer User Cartoon - Free Transparent PNG Clipart Images  Download

OK, so practically everyone who uses Linux has come to this menacing prompt at least once or twice. Typically, unless you’re a seasoned sysadmin, it’s a harbinger of death of your ability to use the computer like you were hoping that day.

But if you know how to navigate the GRUB prompt, you can get back to work just like you were hoping.

If you’re scared of new prompts, and would rather just re-install GRUB, please see my sister post for restoring GRUB on Ubuntu: <coming soon>

These two skills are extremely useful to have in your arsenal of command-line fu, because if you can knowledgably tackle a GRUB prompt in a reasonable amount of time, it can save you hours of headaches and hassle.

So don’t be afraid, embrace the unknown and learn how to navigate GRUB!

First of all, what’s a GRUB prompt?

             GNU GRUB Version 2.04~beta2-36ubuntu3.15
Minimal BASH-like line editing is supported. For the first word, TAB lists possible for device or command completion.

grub>

It’s a black screen that has a prompt like this, instead of the list of OS you were hoping to boot.

What do you need to know to boot from a GRUB prompt?

You should have…

  1. A decent understanding of what disk-type devices you have in your computer
  2. A working memory of which partition is used for what purpose
  3. The ability to differentiate between which root GRUB is asking you for at which time

I’ll explain what #3 means more in a minute, but first let’s start with #1 – building a decent understanding of what disk-type devices you have in your computer:

Unix-like operating systems locate all system devices in a folder hierarchy, starting with /dev

Where * denotes a number or letter for ordering, typical disk-type endpoints in the /dev folder are /dev/sd** and /dev/nvme*n*p* in Linux, /dev/da* and /dev/ada* in FreeBSD, or /dev/dsk/c*t*d* and /dev/rdsk/c*t*d* in Solaris-like OS.

While not all these OS use GRUB by default, all of these OS are potential consumers of the GRUB bootloader, and all must have a bootloader of some kind, so understanding what to look for might become useful even if not specifically troubleshooting GRUB.

But, back to GRUB specifically, the only reason you need to know which /dev your disk is is so you can point GRUB to which partiton to ultimately boot from.

That’s because the GRUB prompt throws the standard heirarchy for disk devices and partitions out the window, and instead presents you with an ordering system that looks like this:

grub> ls
(hd0) (hd0,gpt1) (hd0,gpt2) (hd0, gpt3) (hd0,gpt4) (hd1) (hd1,gpt1) (hd1,gpt9)
grub>

This is an actual scenario of a computer with two hard drives, (hd0) and (hd1), the first drive is configured to boot using UEFI. (hd0) is a typical partition structure created by default using an Ubuntu installer. (hd1) looks like what you might see when looking at a volume formatted using ZFS (which is beyond the scope of this article).

Which brings me to topic #2: You need to be able to remember which partition is responsible for what function

Say (hd0,gpt1) is your installer-created EFI partition. That is very common, so it’s an easy guess that’s likely to be correct. But which partition holds your vmlinuz or initrd.img? Is it on the EFI partition, as required by systemd-boot? Or the second partition which is standard for many automated GRUB installations?

Which partition holds your root directory, is it (hd0,gpt3) or (hd0,gpt4)? Do you remember which one is swap? Because you can’t boot to that…

If you hadn’t noticed the correlation of the GRUB partition ordering scheme to a standard Linux /dev ordinal, here’s a chart on how it breaks down:

GRUB OrdinalsSATA/SAS OrdinalsSCSI OrdinalsNVME Ordinals
(hd0,gpt1)/dev/sda1/dev/sga1/dev/nvme0n1p1
(hd0,gpt2)/dev/sda2/dev/sga2/dev/nvme0n1p2
(hd0,gpt3)/dev/sda3/dev/sga3/dev/nvme0n1p3
(hd0,gpt4)/dev/sda4/dev/sga4/dev/nvme0n1p4
Note: This is an example of a typical Ubuntu installation, but not everyone’s partitions are ordered the same way, so learn what signs to look for that indicate which one is which

If you remember your root partition is /dev/sda4, and your boot partition is /dev/sda2, it will come in handy for this process. So look for the signs while your computer is working so you can remember how to get yourself out of the potential mess that is the inevitable, eventual greeting by the dreaded GRUB prompt!

Here’s a real world example of some partition structures using lsblk:

$ lsblk -pf
 NAME FSTYPE LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINT
 /dev/sda
 │
 ├─/dev/sda1
 │    vfat         D76E-7DEB                             807.3M    19% /boot/efi
 ├─/dev/sda2
 │    ext4         b1cfa7fa-cd24-469a-87fb-d28f0062fb65  692.7M    22% /boot
 ├─/dev/sda3
 │    xfs    root  31aad6f4-98bf-4ae1-a00c-cfa43be07840   12.2G    66% /
 └─/dev/sda4
      swap         d07bf51d-1ef9-4d07-bc86-450945e83a93                [SWAP]
 /dev/sdb
 │
 └─/dev/sdb1
 /dev/sdc
 │
 ├─/dev/sdc1
 │    zfs_me epool 11659485700310844622
 └─/dev/sdc9
 /dev/sdd
 │
 ├─/dev/sdd1
 │    zfs_me epool 11659485700310844622
 └─/dev/sdd9

You can see the first drive, /dev/sda , is the drive used to boot from. It has an EFI partition, a /boot partition, a / (root) partition, and a swap partition. Get to know these and remember which one’s what.

These would subsequently correspond to the following:

in GRUBin LinuxPurpose
(hd0,gpt1)/dev/sda1efi
(hd0,gpt2)/dev/sda2vmlinuz, initrd
(hd0,gpt3)/dev/sda3root
(hd0,gpt4)/dev/sda4swap
The breakdown of how these partition ordinals correspond to one another, depending on which interface you are interacting with. This is a good thing to remember!

Issue #3: Say you can remember these, you know what each of them do. Can you figure out what the GRUB prompt is asking you for?

GRUB prompt will ask you for root. This has two different meanings in the context of the GRUB prompt.

The first root is which partition you will be browsing, loading files from, etc. The second one will be the one that you will be booting from.

Try it – here’s how the first root works (the one that’s only relevant in GRUB):

grub> set root=(hd0,gpt3)
grub> ls /
 bin   etc   lib32   media  proc  sbin        srv  usr
 boot  home  lib64   mnt    root  selections  sys  var
 dev   lib   libx32  opt    run   snap        tmp

Structure look familiar? This is your root partiton.

grub> set root=(hd0,gpt2)
grub> ls /
config-5.10.0-1013-oem   lost+found
 config-5.4.0-26-generic  System.map-5.10.0-1013-oem
 config-5.4.97            System.map-5.4.0-26-generic
 config-5.4.98.zfs        System.map-5.4.97
 efi                      System.map-5.4.98.zfs
 grub                     vmlinuz
 initrd.img               vmlinuz-5.4.97
 initrd.img-5.4.97        vmlinuz-5.4.98.zfs
 initrd.img-5.4.98.zfs    vmlinuz.old
 initrd.img.old

Now GRUB’s root is set to your boot partition…

It’s important to know what the EFI partition looks like, too, so here is an example of an EFI partition with both GRUB and systemd-boot:

grub> set root=(hd0,gpt1)
grub> ls /
b0993a91342e4baea30901c5d7533f4d  EFI  loader  ubuntu
grub> ls /EFI
BOOT  Linux  systemd
grub> ls /EFI/BOOT
BOOTX64.EFI

That BOOTX64.EFI file is what you’re interfacing with right now – that’s the binary responsible for the GRUB prompt.

You can use this navigation feature in conjunction with TAB completion to try and figure out which partition is which – if you recognize what kind of files are located in the root of these partitions and what they are used for.

To boot, you need both a vmlinuz and an initrd.img file. On most machines installed with GRUB as the primary bootloader, these will be located on your second partition when configured with UEFI.

TL;DR

Now you’re going to set the GRUB root to the partition you want to boot from, then tell Linux which partition you want to be the root once it boots (!) (got that?)

Here’s the whole command sequence to initiate the boot process:

grub> set root=(hd0,gpt2)
grub> linux /vmlinuz-5.4.98.zfs root=/dev/sda3
grub> initrd /initrd.img-5.4.98.zfs
grub> boot

So, see, when setting the location of the Linux kernel executable, the root you’re supplying there is not the root for GRUB, but the root for Linux (once you’ve booted). It’s confusing, so I figured I’d repeat it.

And, this might be obvious, but I’ll mention it just to be thorough: Choose the corresponding vmlinuz and initrd.img files from the same initramfs compression process – don’t use vmlinuz from 5.10.0-1013-oem and initrd from 5.4.0-26-generic, for example.

Let’s break these aforementioned commands down into each part:

grub> set root=(hd0,gpt2)

Set the partition GRUB will be looking at to your boot partition (if it’s /dev/sda2, for example)

grub> linux /vmlinuz-5.4.98.zfs root=/dev/sda3

Set vmlinuz-5.4.98.zfs as your Linux kernel executable (don’t forget the / to signify it’s position located in the root you set in the first step). While setting the root Linux will be using once you’re all booted up (in this case, root=/dev/sda3) (can’t say that enough times)

grub> initrd /initrd.img-5.4.98.zfs

Set initrd.img-5.4.98.zfs as your initramfs archive (again, don’t forget the leading / )

grub> boot

Start the boot process using the two variables you just set in the last two steps

IF YOU GET STUCK: Try browsing the other partitions to see if you’re setting GRUB root properly, try a different vmlinuz and initrd.img (maybe the one you first tried was hosed?), you can get a list of commands using help at the prompt…

And if all else fails, boot to a live installer USB and rebuild GRUB from chroot

If you make it through this, I know you’ll be loving your computer again in no time…

hot…

Easing pain of migration from Google Hangouts to Google Voice (as much as humanly possible)

Parting Hangouts is not sweet sorrow…

Some of us have been using Hangouts for ages. Essentially since Google recommended we switch from texting with Google Voice way back May of 2013.

Well, now they’ve dropped the hammer again, and said we have to switch back to Google Voice, since for whatever reason they’ve decided to terminate Hangouts altogether.

What gives? I’d been enjoying Hangouts quite a bit, as it fits my workflow perfectly, and had adapted to it in every minute detail through years of experience in daily life.

And now you want to make that all go away?

Unlike many other things, for which I’m an eager participant for early adoption, I was determined that Hangouts would have to be depreciated out of my cold, dead fingers.

That day appears to have come today, when suddenly my Hangouts window ala Chrome Extension’s box for entering text just disappeared.

Sure, my phone had been bugging me that I should “check out Google Voice” for over a month now, so I knew this day was coming, but I didn’t anticipate it would be like this – while in the middle of a project for a time-sensitive client I suddenly couldn’t text back to (!).

So I set out to see how much I could make Google Voice’s window look like Hangouts. Here’s what I came up with:

Start with an empty Chrome window

Navigate to https://voice.google.com – if you don’t have an account, sign up for one and set up your phone preferences (For instance, I like how it can ring all my numbers, but would never opt to get even more email… perhaps you feel differently?)

Go to the 3 dots menu in the top right hand side of the Chrome window and select More Tools -> Create Shortcut

Give your shortcut a fancy name, like "Voice" (look, it’s even done for you)

Desktop shortcut for Google Voice

If you look on your desktop, you should have the shortcut now. Open it! Ooopen iiiitt…

Then go to the text message menu and scrunch it up until it starts to look like Hangouts! Looks similar enough… 🤷‍♀️

It’ll take some getting used to. One thing that really upsets me is I can’t directly copy + paste images straight into the text box like I could in Hangouts – I had just gotten good at finding pertinent GIFs in Google Image Search! 😥

The best you can do is drag an image you have already saved to your computer 😕

You can save images from this odd view it does inside the scrunched-up window. Unlike Hangouts, it takes an additional step to view the full-size image in another browser Window (gee, Google, all this extra work, I thought this was supposed to be better?)

But all in all, I suppose I’ll live now that I was able to eliminate that gawd-awful bar at the top of the Window.

Life continues apace