What is the best Linux terminal emulator?

(Or: Why doesn't Lubuntu PCManFM-Qt's "Execute in Terminal" work?"

Gnome-terminal is the best.

Admittedly, the only other ones I've tried are Sakura, QTerminal, and XTerm.

But hear me out.

Gnome-terminal is the only one that handles executing command arguments with spaces properly, like XTerm does.

I only say Gnome-terminal is better than XTerm because XTerm is a little too old school for me.

The problem with QTerminal

If you run:

qterminal -e sh "/path/to/Folder Name With Spaces/do stuff.sh"

QTerminal will screw up on the first space, splitting the string into multiple arguments.

This is a known problem from 2017, so I'm not holding my breath for it to be fixed.  I don't know why, but QTerminal has other white space problems too.

The problem with Sakura

Sakura has the exact same problem.  If you run:

sakura -e sh "/path/to/Folder Name With Spaces/do stuff.sh"

Sakura will screw up, splitting the string into multiple arguments due to the spaces.

Sakura is better than QTerminal in that it will work if you escape the double-quotes:

sakura -e sh \"/path/to/Folder Name With Spaces/do stuff.sh\"

Unfortunately, file managers like PCManFM-Qt does not escape the quotes when it opens a script for you in your terminal.

XTerm and Gnome-terminal does it right

Well, the -e option still doesn't work for Gnome-terminal but I guess it does for XTerm.  However, Gnome-terminal has the -- option which does work properly!

This works!

gnome-terminal -- sh "/path/to/Folder Name With Spaces/do stuff.sh"

And file managers like PCManFM-Qt does work with it to properly open a script in gnome-terminal, even if the path to the script contains spaces.

Now go check out how to change the default terminal in Lubuntu.


Changing the default terminal in Lubuntu 20.04

This is terrifically over-complicated.

I used to just remove lxterminal and symlink gnome-terminal over.

I'm testing out the "proper" way nowadays.  Here's 3 steps to do it:

1. PCManFM-Qt

Go to preferences > Advanced > change the Terminal emulator

2. Change the global shortcut Ctrl-Alt-T

The GUI way to do it (using LXQt Settings > Shortcut Keys) does NOT work.

You have to change the ~/.config/openbox/lxqt-rc.xml config file (or lxde-rc.xml for older Lubuntu), replacing the default qterminal with gnome-terminal.

3. Update-alternatives

Also in terminal, select gnome-terminal as prompted after running:

sudo update-alternatives --config x-terminal-emulator
sudo update-alternatives --set x-terminal-emulator /usr/bin/gnome-terminal.wrapper

Doing the above three things is the correct way* to do what's suggested here but which has documented the GUI global shortcut change method which doesn't work in Lubuntu 20.04 (and maybe even earlier versions).


What did you not do? Finding motivation

Leonardo da Vinci - Adorazione dei Magi - Google Art Project
The adoration of the magi (unfinished), Leonardo Da Vinci.

Yeah, Leo had trouble finishing things too.

It's tough working from home. Independently. Socially distantly.

But you have unique advantages too.

You have youthful energy, ideas and goals.

You have a great excuse in case of entrepreneurial failure: it's the 2020 economy!

You've got the internet, the greatest global information distribution and marketing network in history, for free! You can learn anything, for free!

But motivation is tough.

Here's some productivity and motivation DO's and DON'Ts:

1. DO: Just start!

It's better to start creating something instead of just thinking about starting.

Write some code, even if it's wrong. You can always fix it later. But if you don't code, there'd be nothing to fix.

Creative ideas are just conversations you have with yourself. Productive creative action is something you do in reality. There's no way to account for reality without just starting.

What is there to account for in reality? Reality might involve getting a computer screen tan; a need for great code to be wrapped by terrible code just to get it to work; hunger, tiredness; loneliness, boredom; a desire for better; impostor syndrome and self-doubt; not having everything "figured out"; a need to make dinner.

Real success doesn't bypass reality; it goes right through it.

2. DON'T: "I just need a better place to work!"

Your energy spent on finding/creating a fantasy work space is better spent creating something of value.

"If only I found the perfect work music... a better laptop... the weather wasn't so nice / terrible..."

Let's hear from Stephen King (On Writing: A Memoir of the Craft):

"For years I dreamed of having the sort of massive oak slab that would dominate a room --- no more child’s desk in a trailer laundry-closet... In 1981 I got the one I wanted and placed it in the middle of a spacious, skylighted study... For six years I sat behind that desk either drunk or wrecked out of my mind, like a ship’s captain in charge of a voyage to nowhere.

"A year or two after I sobered up, I got rid of that monstrosity... got another desk... half the size of the T. rex desk. I put it at the far west end of the office, in a corner... I'm sitting under it now, a fifty-three-year-old man with bad eyes, a gimp leg, and no hangover...

"It starts with this: put your desk in the corner, and every time you sit down there to write, remind yourself why it isn't in the middle of the room. Life isn't a support-system for art. It's the other way around."

3. DO: Reduce distraction, and totally annihilate interruption

Having Netflix on in the background might be distracting, but that's still better than being interrupted every minute by messages on messenger, FB, Discord, or ..., demanding you to reply, post, tell your powerful story in 280 character tweets, or express yourself in 60 second videos. Sometimes, you even interrupt yourself by checking Twitter, IG, whatever...

A whole generation of computing scientists and software development engineers have gone into making web sites and apps ever more "engaging" (née addictive).

Hundreds of millions of consumers post photos and videos on IG, youTube, etc. Guess who profited $18.5 billion USD in 2019? Facebook, owner of Instagram. BTW, Alphabet, owner of Google and YouTube, made $34.3 billion USD in 2019 profits.

IG or profit aren't bad (e.g. if you own stock). And we're told we should seek "balance", and learn to "manage" the distractions/interruptions, but just remember: stopping you from productive action by interrupting you with engaging apps is literally driven by their ~50 billion dollar profit motive.

It's "a strange game. The only winning move is not to play."

Productive creation requires concentration and focus; Interruptions block it.

And if you're very good at creating software, you too can join FB and GOOG.

4. DO: You have to *decide* to finish things

Finishing things can be scary.

Not finishing means your options are still open, anything can still happen, you don't have to worry about having it assessed and judged.

Remember that you are responsible for what you do. You are not responsible, and actually you have no control, over other's perception of it. So go ahead and just decide to start and finish things.

Yes, you have to *decide* that it's finished and done. If you don't decide to finish, creative work can go on forever and unfinished. The work won't tell you it's finished either; *you* have to make the decision that it's done.

Big projects can be tough to start, and even tougher to decide to finish. So break it down into small weekly/daily pieces with deliverable weekly/daily end-products that must exist in reality.

That way you can *feel* the progress being made. And when you get a chain of everyday progress, then just "Don't break the chain" (Jerry Seinfeld).

5. DON'T: "I just need to figure out what I want to do first / today / this week / with my life"

Stop trying to "figure out" what you want to do, and just start doing something. If you don't understand this, see point 1.

The inspiration for this was written by someone who wanted to remain anonymous: their literary posts is amazing.  Un/Fortunately, this post must stand alone.


Bash Brace Expansion and tricks to type less on the CLI

Brace Expansion is an awesome Bash feature whose GNU documentation doesn't hype up enough.

So let's summarize a few fun things I learned while reading it being hyped up:

Braces expand like a Cartesian product:

$ echo {A,B}

$ echo {A,B}{C,D}

$ echo {A,B}{C,D}{E,F}

But they also expand into number sequences:

$ echo {0..20}
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

You can even control the width of the numbers:

$ echo {00..20}
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20

$ echo {000..20}
000 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020

And even expand into alphabetical sequences:

$ echo {A..Z}

Combine brace expansion sequences into Cartesian products:

$ echo {A..B}{A..C}{1..2}

Brace Expansions can be used with other commands:

$ mv foo-bar.txt foo-baz.txt

can be rewritten as:

$ mv foo-{bar,baz}.txt

It just expands the braces into two arguments for the mv command.  So you could imagine using it for all kinds of other commands like tar, cp, etc.

Echo to Preview your brace expansion command:

$ echo mv foo-{bar,baz}.txt
mv foo-bar.txt foo-baz.txt

Empty Brace Expansions to add a word:

$ mv foo-bar.txt foo-bar-baz.txt

can be rewritten as:

$ mv foo-bar{,-baz}.txt

You can preview it:

$ echo mv foo-bar{,-baz}.txt
mv foo-bar.txt foo-bar-baz.txt

Want to interactively change a given file name but don't want to retype it twice?

$ mv oldname

Don't hit enter yet.  Delete (and add it to the kill ring) the last word using CTRL-W, then paste it back using CTRL-Y CTRL-Y twice to get:

$ mv oldname oldname

Now edit the second oldname until you're happy.

Of course this is useful for making copies with cp or whatever else.

Bang-hash to use an argument twice without retyping:

$ mv oldname !#:1.old

Not sure what it does?  Use the echo preview trick (but delete mv):

$ echo oldname !#:1.old
echo oldname oldname.old
oldname oldname.old

Now you see why mv needed to be deleted.  !#:1 is replaced with the first argument.

By the way, I say "bang-hash" because of calling #! "hash-bang".

Bang-hash with regex modifications
Check this out:

$ echo oldname !#:1:s/old/new
echo oldname newname
oldname newname

So instead of:

$ mv oldname newname

You can just:

$ mv oldname !#:1:s/old/new

Obviously more useful if the "oldname" was longer, or if you were doing this programatically in a bigger script.

Force glob expansion to see what * expands to:
Do your stuff:

$ mv Down*

Don't hit enter yet. Hit CTRL-x * to expand the glob:

$ mv Downloads

and carry on.


profile bash_profile bashrc on Ubuntu Linux, Macs, and Windows

I'm trying to get the same script to run and also set the $PATH for the login and non-login terminal shell on all 3 OSs: Windows, Mac, and Linux.

There's 3 parts to making it work:

Does the shell start in login or non-login mode?

  1. Mac's Terminal.app by default starts bash as a login shell.
  2. Ubuntu graphically logs in as a GUI shell (i.e. your desktop environment, gnome-session, etc.), so it's just not bash at all.  But if you then open a terminal in the desktop environment, your manually opened bash shell on Ubuntu may well start as a non-login (i.e. interactive) shell.
  3. Debian LXDE graphically logs in with bash and runs as a login shell by default.
  4. Windows Git Bash (MINGW64) seems to start as a login shell by default as well.

Which script runs on shell startup: .profile, .bash_profile, .bashrc?

  1. Gnome-session or whatever is your desktop environment (DE) is not bash, but the script that starts your DE is supposed to source ~/.profile but NOT ~/.bash_profile.  However, it's possible with Debian LXDE that it'll prefer ~/.bash_profile if it exists over the fallback that is ~/.profile.
  2. Bash as a login mode shell sources ~/.bash_profile and if that's missing then ~/.profile as a fallback.
  3. Bash as a non-login (interactive) shell sources ~/.bashrc and NOT those other two.

Where should scripts go to run on shell startup?

  1. So scripts that run only when your desktop environment or graphical shell starts goes into ~/.profile.
  2. Scripts that run only when you start bash in login mode --- e.g. started with bash -l, via the text console mode in Debian or Ubuntu e.g. via Ctrl + Alt + F2, when Mac's Terminal.app opens, or when Git's MINGW Bash opens on Windows --- goes into ~/.bash_profile.
  3. Scripts that run only when you start bash interactively (non-login mode) --- e.g. started by clicking the terminal icon having graphically logged in to Ubuntu's DE --- goes into ~/.bashrc.  This assumes you didn't configure your terminal emulator to run as a login shell!

Want the script to always run however shell starts up?

Suppose you want a bit of code to run when your shell starts.  It doesn't matter if it's a login, non-login (i.e. interactively started), graphical login from your desktop environment, on Macs, on Windows MINGW, etc.

In principle, I think ~/.bash_profile and ~/.profile both should source in ~/.bashrc as well, so scripts in ~/.bashrc should run whichever way you get your hands into a terminal UI in Ubuntu.  But Macs and Windows Git Bash doesn't have a proper .bash_profile to start.

Thus for Macs and Windows, favor ~/.bash_profile.

For Ubuntu Linux, favor ~/.bashrc.

A single method that works on all 3 platforms would be to put the code in ~/.bashrc, then make sure ~/.bash_profile sources in bashrc.


Why ~/.bash_profile is not getting sourced when opening a terminal?