# Modern Shell Tools

## Shell Tools

All these are quite nice if you're working with a bare shell, or an uncustomized shell. However, in this day and age, there's a lot of new commands and tools to enhance your terminal experiences.

{% embed url="<https://github.com/ibraheemdev/modern-unix>" %}

### Finding out how to use commands and installing them

Before we get started with tools, we need to know how to install them and also how to learn what they do. For commands, we can often pass in **flags** to tell the program how we want it to run. One of the universal flags is the `--help` flag.

<pre class="language-shell-session"><code class="lang-shell-session"><strong>chun@legion:~$ cat --help
</strong></code></pre>

To install a program, we often times use what is known as a **package manager.** This allows us to search and install packages without having to googling the tool and trying to find the correct downloadable file

If you're on Linux or WSL, you should have a package manager installed. If you're on Ubuntu/Debian-based distros, this should be `apt`. If you're on anything else, you should try and figure out what the package manager is based on your distro.

If you're on MacOS, you'll need to install brew:

{% embed url="<https://brew.sh>" %}

Now to install a program, you can just do:

{% tabs %}
{% tab title="WSL/Linux" %}
You will need to update the package lists before installing a package!

```shell-session
sudo apt-get update
sudo apt-get install <package-name>
```

{% endtab %}

{% tab title="MacOS" %}

```ruby
brew install <package-name>
```

{% endtab %}
{% endtabs %}

### Finding Files

{% embed url="<https://github.com/junegunn/fzf>" %}

{% tabs %}
{% tab title="WSL/Linux" %}

```bash
sudo apt-get install fzf
```

{% endtab %}

{% tab title="MacOS" %}

```shell-session
brew install fzf
```

{% endtab %}
{% endtabs %}

Once installed, do:

`fzf` stands for fuzzy finder. It allows you to find anything with a fuzzy search (you can make spelling errors). If you just run `fzf`, it will do a fuzzy find on your current directory

```bash
fzf
```

But we can do so much more than that! To do so, we need to add some keybindings by running this command:

```bash
eval "$(fzf --bash)"
```

Now try out these new keybindings:

* `CTRL-T` - Paste the selected files and directories onto the command-line
* `CTRL-R` - Paste the selected command from history onto the command-line
* `ALT-C` - cd into the selected directory

Now notice that if you quit the terminal or start a new terminal, these keybindings won't be available. To make the change permanent, we need to save it into a **config file.** For bash, this config file is is at `~/.bashrc`

```bash
nano ~/.bashrc

## Inside the editor, add this line
eval "$(fzf --bash)"
```

### Finding code or text

So we can find specific files and directories, but what about finding specific contents within a file? `ripgrep` is a program that aims to solve this.

{% embed url="<https://github.com/BurntSushi/ripgrep>" %}

{% tabs %}
{% tab title="WSL/Linux" %}

```bash
sudo apt-get install ripgrep
```

{% endtab %}

{% tab title="MacOS" %}

```bash
brew install ripgrep
```

{% endtab %}
{% endtabs %}

```bash
# Find all python files where I used the requests library
rg -t py 'import requests'
# Find all files (including hidden files) without a shebang line
rg -u --files-without-match "^#\!"
# Find all matches of foo and print the following 5 lines
rg foo -A 5
# Print statistics of matches (# of matched lines and files )
rg --stats PATTERN
```

### Fast directory navigation

It is quite troublesome so jump around directories, especially if you're copying something, or the path is really, really, really long. A good way around this is to have a program guess what directory you want to jump to based on keywords and frequency of which directory you jump to! That is exactly what zoxide does.

{% embed url="<https://github.com/ajeetdsouza/zoxide>" %}

{% tabs %}
{% tab title="WSL/Linux" %}

```bash
curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh
```

{% endtab %}

{% tab title="MacOS" %}

```bash
brew install zoxide
```

{% endtab %}
{% endtabs %}

You can use `z` to jump to directories, similar to how you use `cd`. For example, if you have a directory you frequently go to, like:

```
 /home/user/downloads/temp_dir/funny_project
```

You could do something like `z funny` to jump into it.

{% hint style="info" %}
If all you want to do is learn how to use the terminal, you can just stop here! The next section goes above an beyond and talks about how you can build your own scripts and commands which you can then run.
{% endhint %}
