How to set environment variable in gdb

GDB inherits the environment variables from your shell. Some environment variables, like LD_LIBRARY_PATH, might not be inherited for safety reasons. This can cause errors like this when you try to debug:

$ gdb --args ./a.out
(gdb) r
/path/to/a.out: error while loading shared libraries: cannot open shared object file: No such file or directory

You can set the LD_LIBRARY_PATH environment variable at the gdb shell using the set env command like this:

(gdb) set env LD_LIBRARY_PATH /path/to/1:/path/to/2

However, if you use a shell like Fish, you will notice that this will silently not work and you still get the cannot open shared object file error.

This is because under the covers, gdb is reading the SHELL environment variable to understand what is the shell and doing what is right for that shell. It might not understand how to work with the Fish, which is a relatively new shell.

The solution that works for me, is to set the SHELL variable at the Fish shell to the Bash path:

$ set SHELL (which bash)

And then launch gdb and set the environment variable as shown above. It works after that.

Reference: Your program’s environment (GDB Manual)

How to get last argument of previous command in Fish

While working at the Bash shell prompt, you can access the very last argument of the preceding command using $_.

For example:

$ vim foobar.txt
$ vim $_

To get the effect of $_ in Fish, press Alt+Up. Fish will insert the last argument of the previous command for you right there at the shell prompt.

If you find this command is not working, please check if your terminal multiplexer (tmux or Byobu) or your GUI terminal or windowing environment has not already assigned that key for something else.

How to install Conda

Conda is a package and environment management system for Python. To install it on Ubuntu, I used these steps:

  • Download the bash shell script by clicking on the Download button here. For example, when I did this, I got a file.

  • Run the downloaded bash shell script through bash. For example, I did:

$ bash
  • The bash script asks you for a place to install Anaconda. Typically this is $HOME/anaconda3. But you can provide it any alternate location you wish. Conda will store the environments you create in an envs subdirectory inside this base directory.

  • The bash script asks if you want to add the bin subdirectory inside the base directory to your PATH environment variable. You can choose to do this on your own too. In either case, remember to make sure the Conda bin path is appended to PATH. If it is instead prepended to PATH, then Conda’s Python interpreter will be invoked as the default one at the shell. Typically, you do not want this behavior. You want Conda’s Python to be used only inside a Conda environment.

  • After the script is done, restart your shell, so that your PATH has the Anaconda bin subdirectory.

  • Run this command to check if everything is working:

$ conda info
  • I use the Fish shell, so I need to add this line to the to be able to use Conda’s environment activate and deactivate commands:
source (conda info --root)/etc/fish/conf.d/

I was able to create environments and use Conda after this.

Tried with: Ubuntu 16.04

Command history in Fish

Fish maintains a history of all commands you have executed.

  • To list the history in reverse chronological order:
$ history
  • To list the history along with the time at which each command was executed:
$ history --show-time

Note that this is a very useful feature to check when a particular command was executed. However, this feature was only added in Fish 2.4.0 and is not available in older versions.

  • To search for a substring foo in history:
$ history foo
  • To merge the history of all open sessions of Fish right now:
$ history --merge

Fish does this merge only when it is exited. This is because Fish does not want to update the common history file at the end of every command. This might be for performance and to avoid race conditions.

However, sometimes you execute a long command in one Fish session and might want to repeat that in another session. This is a quick way to merge all histories, so that that command is now available in history of the second session for easy autocompletion.

Tried with: Fish 2.4.0 and Ubuntu 14.04

fish_pwd error


I updated the Fish shell using the apt command:

$ sudo apt install fish

After the update, Fish threw up this error:

fish: __fish_pwd
in command substitution
    called on standard input

in command substitution
    called on standard input


This turned out to be because the /usr/share/fish/functions/ function file it was looking for could not be found! The apt update had screwed up and had deleted some essential configuration files of Fish.

I removed and reinstalled Fish shell:

$ sudo apt purge fish
$ sudo apt install fish

I noticed that the above function file was correctly installed and available now. Fish worked fine after this 🙂

Tried with: Fish 2.4.0 and Ubuntu 14.04

How to read in silent mode in Fish

Silent mode is an useful feature in shells to read sensitive information like passwords. The text typed by the user is not displayed on the displayed nor stored anywhere on file.

Sadly, the Fish shell does not have a true silent mode in its read command. Also, when used with default options, the password (or input) entered to the read command is stored in ~/.config/fish/fish_read_history.

The best we can do is to make the read command not store its history. This can be achieved by passing /dev/null as the history file for read:

read -m /dev/null var_to_store_password

Tried with: Fish 2.2.0 and Ubuntu 14.04

How to update environment variable of existing Tmux session


I use Byobu (which is a wrapper on Tmux) to maintain shell sessions on the many servers I login to. I connect, disconnect and reconnect to the same Tmux sessions on these servers. When I reconnect back to an existing Tmux session, a new value is assigned to the DISPLAY environment variable. If I create a new Tmux session, by opening a new split or tab, then Tmux sets the new DISPLAY value correctly for that session. However, existing Tmux sessions have their old DISPLAY value which gives the familiar cannot open display error. I can find out the new DISPLAY value and set it manually in the existing session, but that is cumbersome.


I found a simple solution to this problem. Whenever I SSH to a server, I save the new DISPLAY assigned to this server in a .display.txt file in the home directory. For example, this can be done in .bashrc:

echo $DISPLAY > ~/.display.txt

To pick up the new DISPLAY value from this file in existing sessions, create a shell alias or function that you can call when you realize that the environment variable is wrong.

For example, for Fish shell, I added a ~/.config/fish/functions/ file with these lines:

function set_display
    set --export DISPLAY (cat ~/.display.txt)

When I need to update DISPLAY, I just call set_display at the shell! 🙂

Tried with: Byobu 5.74, Tmux 1.8 and Fish 2.2.0

How to get autocomplete for command options in Fish

Fish has support to autocomplete the options of any command at the shell. (This is sometimes called tab completions.) For example, when I type ls - and TAB, Fish shows me the options available for the ls command. This works even when you’ve typed out part of an option. Fish generates this information by parsing all the man pages installed on your system.

If you find that Fish autocomplete is not working for the options of a command, that can be fixed easily by asking Fish to reindex from man pages. The Fish function that you need to run for this is: fish_update_completions.

I recently installed Git. Since Git is infamous for its myriad command-line options I missed having autocomplete at the shell for Git command options. After running fish_update_completions, I could get autocomplete for options of all Git commands! The icing on top was to discover that Fish could autocomplete options even for my Git aliases!

Tried with: Fish 2.2.0

Missing argument to exec


I run a find command at the Fish shell and get this error:

$ find . -type f -exec sed -i 's/foo/bar/g' {} +
find: missing argument to `-exec`


This command has nothing wrong with it, it works under Bash. Fish expands the curly braces by default. So, for this to work, just enclose the curly braces in single quotes, so that it is not expanded. More details here.

Tried with: Fish 2.2.0 and Ubuntu 14.04

How to redirect and pipe in Fish


  • To redirect to stdin is similar to Bash:
$ ./a.out > out.txt
  • To redirect stdout is similar to Bash:
$ ./a.out < in.txt
  • To redirect stderr:
$ ./a.out ^ out.txt
  • To redirect both stdout and stderr:
$ ./a.out > out.txt 2>&1

Note how the binding of stderr (2) to stdout (1) is placed after the filename.


  • To pipe stdout is similar to Bash:
$ ./a.out | less
  • To pipe stderr:
$ ./a.out ^| less
  • To pipe both stdout and stderr:
$ ./a.out 2>&1 | less

Tried with: Fish 2.7.1 and Ubuntu 16.04