Skip to content

Commit

Permalink
Added bash tricks
Browse files Browse the repository at this point in the history
  • Loading branch information
AnupJoseph committed Feb 2, 2024
1 parent 2ae1603 commit acf4278
Show file tree
Hide file tree
Showing 3 changed files with 359 additions and 1 deletion.
10 changes: 10 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This configuration file was automatically generated by Gitpod.
# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml)
# and commit this file to your remote git repository to share the goodness with others.

# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart

tasks:
- init: sudo apt install -y hugo


2 changes: 1 addition & 1 deletion assets/jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"baseUrl": ".",
"paths": {
"*": [
"..\\..\\..\\..\\..\\ANUPJO~1\\AppData\\Local\\Temp\\hugo_cache\\modules\\filecache\\modules\\pkg\\mod\\github.com\\!cai!jimmy\\hugo-theme-stack\\[email protected]\\assets\\*"
"../../../tmp/hugo_cache/modules/filecache/modules/pkg/mod/github.com/!cai!jimmy/hugo-theme-stack/[email protected]/assets/*"
]
}
}
Expand Down
348 changes: 348 additions & 0 deletions content/post/bash_tricks/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
---
title: tricks.sh
description: A collection of shell tricks I have found useful over the years
slug: tricks-sh
date: 28-07-2022 00:00:00+0000
categories:
- Shell
tags:
- sh
---


# Table of Contents

1. [Shell tricks](#org4f2342b)
1. [Switch to previous directory](#switch-to-previous-directory)
1. [git](#git)
2. [master](#org6b00f32)
1. [cd](#cd)
1. [Get global ip](#get-global-ip)
2. [Simple commands](#simple-commands)
3. [Loop](#loop)
4. [Loop with specified increment each iteration](#loop-with-specified-increment-each-iteration)
5. [Sequences of letters or numbers](#sequences-of-letters-or-numbers)
6. [Reuse arguments](#reuse-arguments)
7. [Reuse commands](#reuse-commands)
8. [Compare output of two commands](#compare-output-of-two-commands)
9. [Fix last command](#fix-last-command)
10. [Accept interactive commands](#accept-interactive-commands)
11. [Last exit code](#last-exit-code)
12. [Easy backup](#easy-backup)
13. [Print to stderr](#print-to-stderr)
14. [Debugging](#debugging)
15. [Useful `readline` tricks](#useful-readline-tricks)
16. [Repeat command](#repeat-command)
17. [Zipping and Unzip](#zipping-and-unzip)



<a id="org4f2342b"></a>

# Shell tricks

- [Switch to previous directory](#switch-to-previous-directory)
- [git](#git)
- [cd](#cd)
- [Get global ip](#get-global-ip)
- [Simple commands](#simple-commands)
- [Loop](#loop)
- [Loop with specified increment each iteration](#loop-with-specified-increment-each-iteration)
- [Sequences of letters or numbers](#sequences-of-letters-or-numbers)
- [Reuse arguments](#reuse-arguments)
- [Reuse commands](#reuse-commands)
- [Compare output of two commands](#compare-output-of-two-commands)
- [Fix last command](#fix-last-command)
- [Accept interactive commands](#accept-interactive-commands)
- [Last exit code](#last-exit-code)
- [Easy backup](#easy-backup)
- [Print to stderr](#print-to-stderr)
- [Debugging](#debugging)
- [Useful `readline` tricks](#useful-readline-tricks)
- [Repeat command](#repeat-command)
- [Zipping and Unzip](#zipping-and-unzip)


<a id="switch-to-previous-directory"></a>

## Switch to previous directory

Switch between the current and previous branch / directory.


<a id="git"></a>

### git

\#+begin<sub>src</sub> sh
$ git branch


<a id="org6b00f32"></a>

# master

development

$ git checkout development
Switched to branch &rsquo;development&rsquo;
$ git checkout - # Switch to previous
Switched to branch &rsquo;master&rsquo;
$ git checkout -
Switched to branch &rsquo;development&rsquo;
\#+end<sub>src</sub>


<a id="cd"></a>

### cd

$ pwd
/
$ cd /tmp
$ cd - # Switch to previous
/
$ cd -
/tmp


<a id="get-global-ip"></a>

## Get global ip

$ curl ifconfig.co # IPv4
50.110.14.21
$ curl -6 ifconfig.co # IPv6
2010:3f3f:113f:0:ea57:4497:7291:e422


<a id="simple-commands"></a>

## Simple commands

Create a script which calls functions by its\` first argument. This is
very useful to create simple scripts which could be a wrapper for other
commands.

#!/usr/bin/env bash

function do_this () { echo "call do_this function"; }

function do_sth() { echo "call do_sth function" }

case "$1" in
do_this|do_sth) "$1" ;;
esac

Execute it:

$ ./simple-commands.sh do_this
call do_this function


<a id="loop"></a>

## Loop

Write simple one liner loops if you need to do some batch tasks.

$ for i in {1..10}; do echo "$i"; done

# List disk usage by directories
$ for file in */ .*/ ; do du -sh $file; done


<a id="loop-with-specified-increment-each-iteration"></a>

## Loop with specified increment each iteration

for i in {1..100..2}; do echo $i; done
1
3
5
7
...


<a id="sequences-of-letters-or-numbers"></a>

## Sequences of letters or numbers

Brace expansion is great for lots of things.

$ touch file{a..c}
$ ls
$ command ls
filea fileb filec

$ touch file-{1..15}
$ ls
file-1 file-10 file-11 file-12 file-13 file-14 file-15 file-2 file-3 file-4 file-5 file-6 file-7 file-8 file-9
$ ls file-{9..12}
file-10 file-11 file-12 file-9

$ printf "%s\n" file-{a..c}{1..3}
file-a1
file-a2
file-a3
file-b1
file-b2
file-b3
file-c1
file-c2
file-c3

(If you give `printf` more arguments than it expects, it automatically
loops.)


<a id="reuse-arguments"></a>

## Reuse arguments

$ ls /tmp
some_file.txt some_archive.tar.gz
$ cd !$
/tmp


<a id="reuse-commands"></a>

## Reuse commands

$ echo "reuse me"
reuse me
$ !!
echo "reuse me"
reuse me


<a id="compare-output-of-two-commands"></a>

## Compare output of two commands

diff <(echo "1 2 4") <(echo "1 2 3 4")
1c1
< 1 2 4
---
> 1 2 3 4


<a id="fix-last-command"></a>

## Fix last command

$ ehco foo bar bar
bash: ehco: command not found
$ ^ehco^echo
foo bar baz


<a id="accept-interactive-commands"></a>

## Accept interactive commands

$ yes | ./interactive-command.sh
Are you sure (y/n)
Accepted
yes: standard output: Broken pipe

The error message is printed because `yes` gets killed by `SIGPIPE`
signal. This happens if the pipe to `./interactive-command.sh` gets
closed but `yes` still wants to write into it.

Ignore error message:

`$ yes 2>/dev/null | ./interactive-command.sh`


<a id="last-exit-code"></a>

## Last exit code

$ ls /tmp
some_file.txt
$ echo $?
0


<a id="easy-backup"></a>

## Easy backup

$ cp file.txt{,.bak}
$ ls -1
file.txt
file.txt.bak


<a id="print-to-stderr"></a>

## Print to stderr

$ >&2 echo hello
hello


<a id="debugging"></a>

## Debugging

Add `-xv` to your bash scripts, i.e.:

/usr/bin/env bash
set -xv

or `/bin/bash -xv script.sh`


<a id="useful-readline-tricks"></a>

## Useful `readline` tricks

If you use the standard `bash` `readline` bindings.

- `C-a` (aka `CTRL+A`) move cursor to beginning of line
- `C-e` (aka `CTRL+E`) move cursor to end of line
- `M-.` (aka `ALT+.`) insert last argument of previous command (like
`!$`, but you can edit it)


<a id="repeat-command"></a>

## Repeat command

Execute a command every two seconds and monitor its\` output. This is
especially useful for waiting until a deployment or infrastructure
provisioning is completed, i.e. on aws.

`watch -n2 echo hello` \` ## Substrings

$ a="apple orange"

$ echo ${a#* }
orange
$ echo ${a#*p}
ple orange
$ echo ${a##*p}
le orange

$ echo ${a% *}
apple
$ echo ${a%p*}
ap
$ echo ${a%%p*}
a

The # for finding first occurence from the start and % for the first
occurence from the end. \* for matching any pattern. For greedy matching
\## and %%.


<a id="zipping-and-unzip"></a>

## Zipping and Unzip

To zip a folder with certain file types excluded

zip -x {file_types} -r archive.zip {folder}

0 comments on commit acf4278

Please sign in to comment.