# linux

* [prompts](#prompts)
  * [settings](#settings)
    * [PS4](#ps4)
  * [colors](#colors)
  * [functions](#functions)
* [character](#character)
  * [metacharacter](#metacharacter)
* [process substitution](#process-substitution)
  * [example: run script without download](#example-run-script-without-download)
  * [example: merge lines of file](#example-merge-lines-of-file)
    * [nstalling tools via running random scripts from unknown sites](#nstalling-tools-via-running-random-scripts-from-unknown-sites)
* [basic commands](#basic-commands)
  * [`du`](#du)
  * [sort](#sort)
    * [sort result via human-readable format](#sort-result-via-human-readable-format)
  * [others](#others)
    * [`you have new mail`](#you-have-new-mail)
    * [crontab](#crontab)
* [tricky](#tricky)
  * [unicode](#unicode)
  * [useful functions](#useful-functions)
  * [search manual page](#search-manual-page)
  * [show services](#show-services)

{% hint style="info" %}

> reference
>
> * [The Bash Shell Startup Files](http://www.linuxfromscratch.org/blfs/view/svn/postlfs/profile.html)
> * [Advanced Bash-Scripting Guide](https://tldp.org/LDP/abs/html/index.html)
> * download pdf from [here](https://tldp.org/LDP/abs/abs-guide.pdf) or [here](http://www.linux-france.org/lug/ploug/doc/abs-guide.pdf)
> * [Perform tab-completion for aliases in Bash](https://brbsix.github.io/2015/11/23/perform-tab-completion-for-aliases-in-bash/)
> * [dot\_file: .bash\_aliases](https://github.com/agilesteel/.dotfiles/blob/master/stow/bash/.bash_aliases)
> * [killbutmakeitlooklikeanaccident.sh](https://gist.github.com/moyix/95ca9a7a26a639b2322c36c7411dc3be)
>   {% endhint %}

## prompts

{% hint style="info" %}

> reference:
>
> * [\* imarslo: color](https://github.com/marslo/ibook/blob/marslo/docs/cheatsheet/colors.html)
> * [\* Bash/Prompt customization](https://wiki.archlinux.org/title/Bash/Prompt_customization)
> * [\* Bash/Prompt customization](https://wiki.archlinux.org/index.php/Bash/Prompt_customization)
> * [Colors using tput](https://wiki.bash-hackers.org/scripting/terminalcodes#colors_using_tput)
> * [What color codes can I use in my PS1 prompt?](https://unix.stackexchange.com/a/124409/29178)
> * [joseluisq/terminal-git-branch-name.md](https://gist.github.com/joseluisq/1e96c54fa4e1e5647940)
> * [How to show git branch in terminal and change terminal colours](https://www.stijit.com/engineering/show-git-branch-colours-terminal-mac.html)
> * [8 Useful and Interesting Bash Prompts](https://www.maketecheasier.com/8-useful-and-interesting-bash-prompts/)
> * [\* 2.5. Bash Prompt Escape Sequences](https://tldp.org/HOWTO/Bash-Prompt-HOWTO/bash-prompt-escape-sequences.html)
> * [\* My Ultimate PowerShell prompt with Oh My Posh and the Windows Terminal](https://www.hanselman.com/blog/my-ultimate-powershell-prompt-with-oh-my-posh-and-the-windows-terminal)
>   {% endhint %}

![bash prompts with change-mode and cursorshape](https://4276369325-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpuTw6o3ALq0J3Uf7ELc7%2Fuploads%2Fgit-blob-f2853fcd500fb07a5eca198083205a7369326dc9%2Fbash-bind-mode-string-cursor-shape.gif?alt=media)

### settings

> \[!NOTE|label:inputrc]
>
> * [\* iMarlso: inputrc](https://github.com/marslo/ibook/blob/marslo/docs/cheatsheet/bash/builtin.html#inputrc)
> * [\* marslo/mylinux/inputrc](https://github.com/marslo/mylinux/blob/main/confs/home/.inputrc)

```bash
# https://marslo.github.io/ibook/screenshot/colors/ansi/color-formatting.png
fgc=$(RGBcolor 5 6 8)                             # 240;  fgc=$(RGBcolor 5 6 5)  # 237
COL_SD_GREEN='\[\033[32;2m\]'                     # COL_SD_GREEN='\[\033[2;32m\]'
COL_IF_SL_RED='\[\033[0\;31m\]'
COL_DEFAULT="\[\033[38;5;${fgc}m\]"               # "\[$(tput setaf ${fgc})\]"; $"\e[38;5;${fgc}m";
COL_IF_DEFAULT="\[\033[38\;5\;${fgc}m\]"          # COL_IF_DEFAULT="\[\033[1\;38\;5\;${fgc}m\]"  | COL_IF_DEFAULT="${COL_IF_SD_GREEN}"
COL_RESET='\[\033[1m\]'                           # COL_RESET="\[$(tput sgr0)\]" | COL_RESET='\[\033[1m\]'
COL_NONE='\[\033[0m\]'                            # COL_NONE='\[\033[38;5;3m\]'

PS1="\\n${COL_RESET}${COL_DEFAULT}╭╶ (\\u@\\h${COL_RESET} "
PS1+="${COL_SL_RED}\\w${COL_RESET}${COL_DEFAULT}) "
PS1+="\$(__git_ps1 \"- (${COL_SD_GREEN}%s${COL_NONE}${COL_DEFAULT}) \")${COL_RESET}"
PS1+="${COL_DEFAULT}\`if [ \$? = 0 ]; then echo ${COL_IF_DEFAULT}\⏵; else echo ${COL_IF_SL_RED}\⏵; fi\`${COL_RESET}"
PS1+="\\n${COL_DEFAULT} \$ ${COL_RESET}"
PS1+="${COL_NONE}"
PS2="${COL_DEFAULT}  -> ${COL_RESET}${COL_NONE}"
PS4=' ${BASH_SOURCE}:$FUNCNAME:$LINENO: '
```

```bash
PS1="\\n${COL_RESET}${COL_DEFAULT}╭╶ (\\u@\\h${COL_RESET} "
PS1+="${COL_SL_RED}\\w${COL_RESET}${COL_DEFAULT}) "
PS1+="\`__git_ps1 '- (%s) '\`"
PS1+="${COL_RESET}${COL_DEFAULT}->${COL_RESET}"
PS1+="\\n${COL_DEFAULT}╰╶ ${COL_RESET}"
PS1+="\`if [ \$? = 0 ]; then echo ${COL_IF_DEFAULT}\\$; else echo ${COL_IF_SL_RED}\\$; fi\` ${COL_RESET}"
PS1+="${COL_NONE}"
# PS2="${COL_DEFAULT} |-> ${COL_RESET}${COL_NONE}"
PS2="${COL_DEFAULT}  -> ${COL_RESET}${COL_NONE}"
PS4=' ${BASH_SOURCE}:$FUNCNAME:$LINENO: '

export PS1 PS2 PS4
```

```bash
UMARK='\[\033(0\]l\[\033(B\]'
DMARK='\[\033(0\]m\[\033(B\]'
LMARK='\[\033(0\]q\[\033(B\]'

COL_SL_GREEN='\[\033[32;0m\]'
COL_SD_GREEN='\[\033[32;2m\]'                     # COL_SD_GREEN='\[\033[2;32m\]'
COL_SD_YELLOW='\[\033[2;33m\]'
COL_SL_YELLOW='\[\033[0;33m\]'
COL_B_YELLOW='\[\033[2;33m\]'
COL_IF_SD_YELLOW='\[\033[2\;33m\]'

COL_D_BLACK='\[\033[30;1m\]'
COL_L_BLACK='\[\033[30;0m\]'
COL_SD_BLACK='\[\033[1;30m\]'
COL_SL_BLACK='\[\033[0;30m\]'
COL_SD_RED='\[\033[1;31m\]'
COL_SL_RED='\[\033[0;31m\]'
COL_SD_BLUE='\[\033[1;34m\]'
COL_SL_BLUE='\[\033[0;34m\]'
COL_L_RED='\[\033[31;0m\]'
COL_D_RED='\[\033[31;1m\]'

COL_IF_D_BLACK='\[\033[30\;1m\]'
COL_IF_L_BLACK='\[\033[30\;0m\]'
COL_IF_SD_BLACK='\[\033[1\;30m\]'
COL_IF_SL_BLACK='\[\033[0\;30m\]'
COL_IF_SL_YELLOW='\[\033[0\;33m\]'
COL_IF_D_RED='\[\033[31\;1m\]'
COL_IF_SD_RED='\[\033[1\;31m\]'
COL_IF_SL_RED='\[\033[0\;31m\]'
COL_IF_SL_GREEN='\[\033[0\;32m\]'
COL_IF_SD_GREEN='\[\033[2\;32m\]'
COL_IF_SL_BLUE='\[\033[0\;34m\]'
COL_IF_SD_BLUE='\[\033[1\;34m\]'
```

```bash
if [ -z "$DISPLAY" ]; then
  export PS1="\n${COL_D_BLACK}┌─ (\u@\h ${COL_RESET} ${COL_D_RED}\w${COL_RESET}${COL_D_BLACK}) ->${COL_RESET}\n${COL_D_BLACK}└─ ${COL_RESET}\`if [ \$? = 0 ]; then echo ${COL_SD_BLACK}\\$ ${COL_RESET}; else echo ${COL_SD_RED}\\$ ${COL_RESET}; fi\`${COL_NONE}"
  export PS2="${COL_D_BLACK} -> ${COL_RESET}${COL_NONE}"
else
  export PS1="\n${COL_D_BLACK}${UMARK}${LMARK} (\u@\h ${COL_RESET} ${COL_D_RED}\w${COL_RESET}${COL_D_BLACK}) ->${COL_RESET}\n${COL_D_BLACK}${DMARK}${LMARK} ${COL_RESET}\`if [ \$? = 0 ]; then echo ${COL_SD_BLACK}\\$ ${COL_RESET}; else echo ${COL_SD_RED}\\$ ${COL_RESET}; fi\`${COL_NONE}"
  export PS2="${COL_D_BLACK} ->${LMARK} ${COL_RESET}${COL_NONE}"
fi

# for mac os -> Solarized Dark
export PS1="\n${COL_DEFAULT}┌─ (\u@\h${COL_RESET} ${COL_SD_RED}\w${COL_RESET}${COL_DEFAULT}) ->${COL_RESET}\n${COL_DEFAULT}└─ ${COL_RESET}\`if [ \$? = 0 ]; then echo ${COL_IF_DEFAULT}\\$ ${COL_RESET}; else echo ${COL_IF_SL_RED}\\$ ${COL_RESET}; fi\`${COL_NONE}"
```

#### PS4

> \[!NOTE|label:references:]
>
> * [Setting $PS4 using `bash -c`](https://stackoverflow.com/a/50627260/2940319)
> * [Why does Bash reset PS4 value to its default value when starting a script?](https://stackoverflow.com/a/74028357/2940319)

* show timestamp

  ```bash
  $ bash -xc $'PS4=\'+ $(date "+%T %x ($LINENO) : ")\'; echo ABC; echo XYZ'
  + PS4='+ $(date "+%T %x ($LINENO) : ")'
  + 15:45:51 08/29/2024 (1) : echo ABC
  ABC
  + 15:45:51 08/29/2024 (1) : echo XYZ
  XYZ

  # or
  $ PS4='+ \D{%s} ($LINENO) ' bash -xc 'echo ABC; echo XYZ'
  + 1724971586 (1) echo ABC
  ABC
  + 1724971586 (1) echo XYZ
  XYZ

  # or
  $ cmd=$(cat <<'EOF'
  PS4='+ $(date "+%T %x ($LINENO) : ")'
  echo ABC
  echo XYZ
  EOF
  )

  bash -xc "$cmd"
  ```
* show process id

  ```bash
  $ env -i SHELLOPTS=xtrace PS4='$(id)' ./test
  ```

### colors

* [Bash tips: Colors and formatting (ANSI/VT100 Control sequences)](https://misc.flogisoft.com/bash/tip_colors_and_formatting)

  ```bash
  # https://misc.flogisoft.com/bash/tip_colors_and_formatting
  #  ----+---+---+----+---+----       --------+--------     ----+------+------
  # | ⌌・| ⠋ | ⌜ | ╭╶ | ┌ | ┌─ |    | 0\;xxm | Normal |    | \e | \033 | \x1B |
  # | ⌎・| ⠦ | ⌞ | ╰╶ | └ | └─ |    | 1\;xxm | Bright |     ----+------+------
  #  ----+---+---+----+---+----      --------+--------
  #
  #  ---+--------------++---------------------++----------------------+    +-----------------
  # | # |  color name  ||      foregrand      ||      background      |    |   attribute     |
  #  ---+--------------++---------------------++----------------------+    +---+-------------
  # | 9 | Default      ||      \e[0;39m       ||       e[0;49m        |    | 0 | Normal      |
  # | 0 | Black        || \e[0;30m |          || \e[0;40m |           |    | 1 | Bold        |
  # | 1 | Red          || \e[0;31m |          || \e[0;41m |           |    | 2 | Faint       |
  # | 2 | Green        || \e[0;32m |          || \e[0;42m |           |    | 3 | Italic      |
  # | 3 | Yellow       || \e[0;33m |          || \e[0;43m |           |    | 4 | Underline   |
  # | 4 | Blue         || \e[0;34m |          || \e[0;44m |           |    | 5 | Slow Blink  |
  # | 5 | Purple       || \e[0;35m |          || \e[0;45m |           |    | 6 | Rapid Blink |
  # | 6 | Cyan         || \e[0;36m |          || \e[0;46m |           |    | 7 | reverse     |
  # | 7 | Light Gray   || \e[0;37m |          || \e[0;47m |           |     ---+-------------
  # | 0 | Dark Gray    || \e[1;30m | \e[0;90m || \e[1;40m | \e[0;100m |     ---------------------
  # | 1 | Light Red    || \e[1;31m | \e[0;91m || \e[1;41m | \e[0;101m |    |       others        |
  # | 2 | Light Green  || \e[1;32m | \e[0;92m || \e[1;42m | \e[0;102m |     -------------+-------
  # | 3 | Light Yellow || \e[1;33m | \e[0;93m || \e[1;43m | \e[0;103m |    | color none  | \e[0m |
  # | 4 | Light Blue   || \e[1;34m | \e[0;94m || \e[1;44m | \e[0;104m |    | color reset | \e[1m |
  # | 5 | Light Purple || \e[1;35m | \e[0;95m || \e[1;45m | \e[0;105m |     -------------+-------
  # | 6 | Light Cyan   || \e[1;36m | \e[0;96m || \e[1;46m | \e[0;106m |     ----------------+---------------------------------
  # | 7 | White        ||      \e[0;97m       ||      \e[0;107m       |    | \[\e[xx;0m]\]  | system color                    |
  #  ---+--------------++---------------------++----------------------     | \[\e[xx\;0m]\] | system color in ``              |
  # |   |              ||  \e[38;5;{0..255}m# ||  \e[48;5;{0..255}m#  |    | \[\e[0;xxm]\]  | profile color (solarized)       |
  #  ---+--------------++---------------------++----------------------     | \[\e[0\;xxm]\] | profile color (solarized) in `` |
  #                                                                         ----------------+---------------------------------
  #  ------------+-------------------------------------------------------   ----------------+-------------------------------
  # |                   256 colors standard format                       | |                   comments                     |
  #  ------------+-------------------------------------------------------   ----------------+-------------------------------
  # | attributes | 0 1 2 3 4 5 6 7                                       | | COL_NONE       | no color                      |
  # | foregrand  | {0..255}                                              | | COL_RESET      | reset color                   |
  # | background | {30..37} {90..97} 39                                  | | COL_DEFAULT    | default color                 |
  #  ------------+-------------------------------------------------------  | COL_IF_DEFAULT | default color in if-statement |
  # | usage : \e[${attributes};{background};5;${foreground}m <str> \e[0m |  ----------------+-------------------------------
  #  ------------+-------------------------------------------------------
  #
  # Solarized color table from http://ethanschoonover.com/solarized.
  #
  # | SOLARIZED | HEX     | ANSI      | TERMCOL   | cmd.exe     | PowerShell  | ColorTable | DWORD    |
  # |-----------|---------|-----------|-----------|-------------|-------------|------------|----------|
  # | base03    | #002b36 | ESC[0;30m | brblack   | Black       | Black       | 00         | 00362b00 |
  # | base02    | #073642 | ESC[1;30m | black     | Gray        | DarkGray    | 08         | 00423607 |
  # | base01    | #586e75 | ESC[0;32m | brgreen   | Green       | DarkGreen   | 02         | 00756e58 |
  # | base00    | #657b83 | ESC[0;33m | bryellow  | Yellow      | DarkYellow  | 06         | 00837b65 |
  # | base0     | #839496 | ESC[0;34m | brblue    | Blue        | DarkBlue    | 01         | 00969483 |
  # | base1     | #93a1a1 | ESC[0;36m | brcyan    | Aqua        | DarkCyan    | 03         | 00a1a193 |
  # | base2     | #eee8d5 | ESC[0;37m | white     | White       | Gray        | 07         | 00d5e8ee |
  # | base3     | #fdf6e3 | ESC[1;37m | brwhite   | BrightWhite | White       | 15         | 00e3f6fd |
  # | yellow    | #b58900 | ESC[1;33m | yellow    | LightYellow | Yellow      | 14         | 000089b5 |
  # | orange    | #cb4b16 | ESC[0;31m | brred     | Red         | DarkRed     | 04         | 00164bcb |
  # | red       | #dc322f | ESC[1;31m | red       | LightRed    | Red         | 12         | 002f32dc |
  # | magenta   | #d33682 | ESC[1;35m | magenta   | LightPurple | Magenta     | 13         | 008236d3 |
  # | violet    | #6c71c4 | ESC[0;35m | brmagenta | Purple      | DarkMagenta | 05         | 00c4716c |
  # | blue      | #268bd2 | ESC[1;34m | blue      | LightBlue   | Blue        | 09         | 00d28b26 |
  # | cyan      | #2aa198 | ESC[1;36m | cyan      | LightAqua   | Cyan        | 11         | 0098a12a |
  # | green     | #859900 | ESC[1;32m | green     | LightGreen  | Green       | 10         | 00009985 |
  ```

  ```bash
  PS1="\[$(tput setaf 0) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 1) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 2) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 3) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 4) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 5) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 6) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 7) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 8) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 9) \]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 10)\]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 11)\]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 12)\]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 13)\]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 14)\]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 15)\]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 16)\]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 17)\]my prompt\[$(tput sgr0)\]> "
  PS1="\[$(tput setaf 18)\]my prompt\[$(tput sgr0)\]> "
  ```

  ![bash ps1](https://4276369325-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpuTw6o3ALq0J3Uf7ELc7%2Fuploads%2Fgit-blob-15dd81d3c2759d9df6d230a5d3607d35b2621678%2Fbash-ps1.png?alt=media)

  * or ps1 with conditions

    ```bash
    $ DEFAULT="\[$(tput setaf 3)\]"         # or '\[\033[1;38;5;3m\]'     or '\[\e[1;33m\]'
    $ ifDEFAULT='\[\e[1\;33m\]'             # or '\[\033[1\;38\;5\;3m\]'
    $ ifRED='\[\e[1\;31m\]'                 # or '\[\033[1\;38\;5\;1m\]'
    $ PS1="${DEFAULT}my prompt${RESET} \$( if [ \$? != 0 ]; then echo -e ${ifRED}\\$; else echo -e ${ifDEFAULT}\\$; fi) ${RESET}"
    ```

    ![bash ps1 in conditional](https://4276369325-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpuTw6o3ALq0J3Uf7ELc7%2Fuploads%2Fgit-blob-7d32e33eba9b840a19b50fec5306b5a363ec2747%2Fbash-ps1-conditions.png?alt=media)

### functions

```bash
function showKeyMap() { RET=$?; bind -v | awk '/keymap/ {print $NF}'; return "${RET}"; }
function rightPrompt() {
  if [ "$(bind -v | awk '/keymap/ {print $NF}')" == 'emacs' ]; then
    kmap=⌁
  else
    kmap=⚙︎
  fi
  printf "%*s" $COLUMNS "${kmap}"
}

PS1+="- [\$(showKeyMap)] "
PS1+="- [\$(tput sc; rightPrompt; tput rc)]"
```

* right prompt

  ```
  rightprompt() { printf "%*s" $COLUMNS "right prompt"; }
  PS1='\[$(tput sc; rightprompt; tput rc)\]left prompt > '
  ```

  ![bash ps1 right-prompt](https://4276369325-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpuTw6o3ALq0J3Uf7ELc7%2Fuploads%2Fgit-blob-c1f8253746b7be06639485caa14d7b3fc798fae4%2Fbash-ps1-right-prompt.png?alt=media)

## character

### [metacharacter](https://www.grymoire.com/Unix/Quote.html)

|     Character    | Where                | Meaning                                       |
| :--------------: | -------------------- | --------------------------------------------- |
|    `<RETURN>`    | csh, sh              | Execute command                               |
|        `#`       | csh, sh, ASCII files | Start a comment                               |
|     `<SPACE>`    | csh, sh              | Argument separator                            |
|      `` ` ``     | csh, sh              | Command substitution                          |
|        `"`       | csh, sh              | Weak Quotes                                   |
|        `'`       | csh, sh              | Strong Quotes                                 |
|        `\`       | csh, sh              | Single Character Quote                        |
|    `variable`    | sh, csh              | Variable                                      |
|    `variable`    | csh, sh              | Same as variable                              |
|        `\`       | csh, sh              | Pipe character                                |
|        `^`       | sh                   | Pipe Character                                |
|        `&`       | csh, sh              | Run program in background                     |
|        `?`       | csh, sh              | Match one character                           |
|        `*`       | csh, sh              | Match any number of characters                |
|        `;`       | csh, sh              | Command separator                             |
|       `;;`       | sh                   | End of Case statement                         |
|        `~`       | csh                  | Home Directory                                |
|      `~user`     | csh                  | User's Home Directory                         |
|        `!`       | csh                  | History of Commands                           |
|        `-`       | Programs             | Start of optional argument                    |
|       `$#`       | csh, sh              | Number of arguments to script                 |
|       `$*`       | csh, sh              | Arguments to script                           |
|       `$@`       | sh                   | Original arguments to script                  |
|       `$-`       | sh                   | Flags passed to shell                         |
|       `$?`       | sh                   | Status of previous command                    |
|       `$$`       | sh                   | Process identification number                 |
|       `$!`       | sh                   | PID of last background job                    |
|       `&&`       | sh                   | Short-circuit AND                             |
|      `\|\|`      | sh                   | Short-circuit OR                              |
|        `.`       | csh, sh              | Typ. filename extension                       |
|        `.`       | sh                   | Source a file and execute as command          |
|        `:`       | sh                   | Nothing command                               |
|        `:`       | sh                   | Separates Values in environment variables     |
|        `:`       | csh                  | Variable modifier                             |
|    `Character`   | Where                | Meaning                                       |
|       `[ ]`      | csh, sh              | Match range of characters                     |
|       `[ ]`      | sh                   | Test                                          |
|      `%job`      | csh                  | Identifies job Number                         |
|    `(cmd;cmd)`   | csh. sh              | Runs cmd;cmd as a sub-shell                   |
|       `{ }`      | csh                  | In-line expansions                            |
|   `{cmd;cmd }`   | sh                   | Like (cmd;cmd ) without a subshell            |
|     `>ofile`     | csh, sh              | Standard output                               |
|     `>>ofile`    | csh, sh              | Append to standard output                     |
|     `<ifile`     | csh, sh              | Standard Input                                |
|     `<<word`     | csh, sh              | Read until word, substitute variables         |
|     `<<\word`    | csh, sh              | Read until word, no substitution              |
|     `<<-word`    | sh                   | Read until word, ignoring TABS                |
|     `>>!file`    | csh                  | Append to file, ignore error if not there     |
|     `>!file`     | csh                  | Output to new file, ignore error if not there |
|     `>&file`     | csh                  | Send standard & error output to file          |
|     `<&digit`    | sh                   | Switch Standard Input to file                 |
|       `<&-`      | sh                   | Close Standard Input                          |
|     `>&digit`    | sh                   | Switch Standard Output to file                |
|       `>&-`      | sh                   | Close Standard Output                         |
| `digit1<&digit2` | sh                   | Connect digit2 to digit1                      |
|    `digit<&-`    | sh                   | Close file digit                              |
| `digit2>&digit1` | sh                   | Connect digit2 to digit1                      |
|    `digit>&-`    | sh                   | Close file digit                              |

## [process substitution](http://www.gnu.org/software/bash/manual/html_node/Process-Substitution.html#Process-Substitution)

> \[!TIP]\
> Process substitution is a form of redirection where the input or output of a process (some sequence of commands) appear as a temporary file.\
> reference:
>
> * [chapter 23. process substitution](https://tldp.org/LDP/abs/html/process-sub.html)\
>   Command list enclosed within parentheses
>
> ```bash
> >(command_list)
> <(command_list)
> ```
>
> Process substitution uses `/dev/fd/<n>` files to send the results of the process(es) within parentheses to another process. \[1]

```bash
$ while read branch; do
    git fetch --all --force;
  done < <(git rev-parse --abbrev-ref HEAD)
```

```bash
$ echo >(true)
/dev/fd/63
$ echo <(true)
/dev/fd/63

$ echo >(true) <(true)
/dev/fd/63 /dev/fd/62

$ echo <(date)
/dev/fd/63
$ cat <(date)
Tue Dec 15 22:32:08 CST 2020
```

[named pipe](https://tldp.org/LDP/abs/html/extmisc.html#NAMEDPIPEREF) similar

```bash
$ wc <(cat /usr/share/dict/words)
 235886  235886 2493109 /dev/fd/63
$ cat /usr/share/dict/words | wc
 235886  235886 249310

$ wc <(grep script /usr/share/dict/words)
    176     176    5414 /dev/fd/63
$ grep script /usr/share/dict/words | wc
    176     176    5414

# https://superuser.com/a/1059790/112396
$ cat file | while read line; do ((count++)); done
$ while read line; do ((count++)); done < <(cat file)
```

get diff in two folders

```bash
$ diff <(ls ibook) <(ls mbook)
1c1,2
< book.json
---
> _book
> book.json
3a5
> node_modules

$ diff <(sleep 4; date) <(sleep 5; date)
1c1
< Tue Dec 15 22:48:31 CST 2020
---
> Tue Dec 15 22:48:32 CST 2020
```

### [example: run script without download](https://askubuntu.com/a/1086668)

```bash
$ bash < <(wget -qO - https://raw.githubusercontent.com/ubports/unity8-desktop-install-tools/master/install.sh)
```

* via curl

  ```bash
  $ python < <(curl -s https://raw.githubusercontent.com/giampaolo/psutil/master/scripts/meminfo.py)
  ```

  * or

    ```bash
    $ curl -so - https://raw.githubusercontent.com/giampaolo/psutil/master/scripts/meminfo.py | python
    ```
* [via wget](http://alvinalexander.com/linux/unix-linux-crontab-every-minute-hour-day-syntax/)

  ```bash
  $ python < <(wget -O - -q -t 1 https://raw.githubusercontent.com/giampaolo/psutil/master/scripts/meminfo.py)
  ```

  * or

    ```bash
    $ wget -qO - https://raw.githubusercontent.com/giampaolo/psutil/master/scripts/meminfo.py | python
    ```
* [or](https://github.com/giampaolo/psutil/blob/master/scripts/meminfo.py)

  ```bash
  $ python < <(curl -s https://raw.githubusercontent.com/giampaolo/psutil/master/scripts/meminfo.py)
  MEMORY
  ------
  Total      :   16.0G
  Available  :    5.8G
  Percent    :    63.8
  Used       :    8.8G
  Free       :  204.5M
  Active     :    5.4G
  Inactive   :    5.6G
  Wired      :    3.4G

  SWAP
  ----
  Total      :    1.0G
  Used       :  269.2M
  Free       :  754.8M
  Percent    :    26.3
  Sin        :   38.3G
  Sout       :   63.9M
  ```
* or

  ```bash
  $ python < <(curl -s https://raw.githubusercontent.com/giampaolo/psutil/master/scripts/disk_usage.py)
  Device               Total     Used     Free  Use %      Type  Mount
  /dev/disk1s5        233.5G    10.6G    70.6G    13%      apfs  /
  /dev/disk1s1        233.5G   149.6G    70.6G    67%      apfs  /System/Volumes/Data
  /dev/disk1s4        233.5G     2.0G    70.6G     2%      apfs  /private/var/vm
  /Library/Input Methods/SogouInput.app   233.5G   149.1G    71.1G    67%    nullfs  /private/var/folders/s3/mg_f3cv54nn7y758j_t46zt40000gn/T/AppTranslocation/E29031DE-FE63-4ABC-BA3D-E99C743E57D2
  ```

### example: merge lines of file

> inspired by [here](https://apple.stackexchange.com/a/216657/254265) and [here](https://stackoverflow.com/q/31371672/2940319)

```bash
$ cat a
t1
t2
t3
t4
$ cat b
11
22
33
44

$ paste <(cat a) <(cat b)
t1  11
t2  22
t3  33
t4  44
```

* additional usage

  ```bash
  $ cat a | paste -d'\t' - - - -
  a b c d
  e f
  ```

  or

  ```bash
  $ cat a | paste -d, - -
  a,b
  c,d
  e,f
  ```
* `/dev/fd/63` is not a regular file

  ```bash
  $ more <( ls -l )
  /dev/fd/63 is not a regular file (use -f to see it)

  $ more -f <( ls -l )
  total 12
  -rw-r--r--  1 marslo staff 3457 Nov  2 15:53 README.md
  -rw-r--r--  1 marslo staff 4314 Nov  2 15:53 SUMMARY.md
  drwxr-xr-x  6 marslo staff  192 Oct 12 22:10 artifactory
  drwxr-xr-x  8 marslo staff  256 Sep 29 17:40 cheatsheet
  drwxr-xr-x 12 marslo staff  384 Oct 15 15:27 devops
  drwxr-xr-x  7 marslo staff  224 Sep 28 22:17 jenkins
  drwxr-xr-x 11 marslo staff  352 Sep 28 22:17 kubernetes
  drwxr-xr-x  8 marslo staff  256 Oct  9 19:15 linux
  drwxr-xr-x  8 marslo staff  256 Nov  2 15:51 osx
  drwxr-xr-x  6 marslo staff  192 Sep 28 22:17 programming
  drwxr-xr-x 45 marslo staff 1440 Nov  2 13:56 screenshot
  drwxr-xr-x 11 marslo staff  352 Oct 14 21:22 tools
  ```

#### [nstalling tools via running random scripts from unknown sites](https://stackoverflow.com/a/12748630/2940319)

```bash
$ ( wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
    fetch -o - http://pi.dk/3 ) > install.sh
```

## basic commands

### `du`

* top biggest directories under *\[path]*

  ```bash
  $ du -a [path] | sort -n -r | head -n 5
  ```
* display the largest files according to human-readable format

  ```bash
  $ du -hs * | sort -rh | head -5
  ```
* display the largest folders/files including the sub-directories

  ```bash
  $ du -Sh | sort -rh | head -5
  ```
* biggest file sizes

  ```bash
  $ find -type f -exec du -Sh {} + | sort -rh | head -n 5

  # or
  $ find [PATH] -type f -printf "%s %p\n" | sort -rn | head -n 5
  ```
* [du with colored bar graph](https://www.commandlinefu.com/commands/view/9797/du-with-colored-bar-graph)

  ```bash
  $ t=$(df|awk 'NR!=1{sum+=$2}END{print sum}'); sudo du / --max-depth=1 | sed '$d' | sort -rn -k1 | awk -v t=$t 'OFMT="%d" {M=64; for (a=0;a<$1;a++){if (a>c){c=a}}br=a/c;b=M*br;for(x=0;x<b;x++){printf "\033[1;31m" "|" "\033[0m"}print " "$2" "(a/t*100)"% total"}'
  ```

### sort

#### [sort result via human-readable format](https://www.redhat.com/sysadmin/sort-du-output)

```bash
$ sudo du -ahx --max-depth=1 <path> | sort -k1 -rh
```

* [or](https://unix.stackexchange.com/a/197821/29178)

  ```bash
  $ du -sk * | sort -g | awk '{

      numBytes = $1 * 1024;
      numUnits = split("B K M G T P", unit);
      num = numBytes;
      iUnit = 0;

      while(num >= 1024 && iUnit + 1 < numUnits) {
          num = num / 1024;
          iUnit++;
      }

      $1 = sprintf( ((num == 0) ? "%6d%s " : "%6.1f%s "), num, unit[iUnit + 1]);
      print $0;

  }'

  # or in one-line
  $ du -sk * | sort -g | awk '{ numBytes = $1 * 1024; numUnits = split("B K M G T P", unit); num = numBytes; iUnit = 0; while(num >= 1024 && iUnit + 1 < numUnits) { num = num / 1024; iUnit++; } $1 = sprintf( ((num == 0) ? "%6d%s " : "%6.1f%s "), num, unit[iUnit + 1]); print $0; }'
  ```
* [or](https://unix.stackexchange.com/a/4701/29178)

  ```bash
  #! /usr/bin/env bash
  ducks () {
      du -cks -x | sort -n | while read size fname; do
          for unit in k M G T P E Z Y; do
              if [ $size -lt 1024 ]; then
                  echo -e "${size}${unit}\t${fname}"
                  break
              fi
              size=$((size/1024))
          done
      done
  }
  ducks > .ducks && tail .ducks
  ```
* [or](https://unix.stackexchange.com/a/27102/29178)

  ```bash
  $ du -k ./* |
       sort -nr |
       awk '{ split("KB,MB,GB",size,","); }
            { x = 1;while ($1 >= 1024) {$1 = $1 / 1024;x = x + 1} $1 = sprintf("%-4.2f%s", $1, size[x]); print $0; }'
  ```

### others

#### `you have new mail`

* [remove](https://apple.stackexchange.com/a/28747/254265)

  ```bash
  $ mail
  ? delete *
  No applicable messages.
  ? q
  ```

  * or

    ```bash
    $ mail -N
    ? d *
    ? quit
    ```

#### crontab

> \[!NOTE|label:references:]
>
> * [Linux / UNIX Crontab File Location](https://www.cyberciti.biz/faq/where-is-the-crontab-file/)
> * [\* cron.help](https://cron.help/) | [\* cron analysis](https://crontab.guru/)
>   * [cron examples](https://crontab.guru/examples.html)
> * [Cron Jobs: The Complete Guide for 2023](https://cronitor.io/guides/cron-jobs?utm_source=crontabguru\&utm_campaign=cron_reference)

* format

  ```bash
  *    *    *    *    *   /home/user/bin/somecommand.sh
  |    |    |    |    |            |
  |    |    |    |    |    Command or Script to execute
  |    |    |    |    |
  |    |    |    | Day of week(0-6 | Sun-Sat)
  |    |    |    |
  |    |    |  Month(1-12)
  |    |    |
  |    |  Day of Month(1-31)
  |    |
  |   Hour(0-23)
  |
  Min(0-59)
  ```
* tips
  * every odd hours

    ```bash
    0 1-23/2 * * *
    ```
  * every even hours

    ```bash
    0 */2 * * *
    ```
* sample
  * delete *.DS\_*

    ```bash
    15 */2 * * 1-5 /usr/local/bin/fd --type f --hidden --follow --unrestricted --color=never --exclude .Trash --glob '*\.DS_*' $HOME | xargs -r rm
    # or
    30 */2 * * 1-5 /usr/local/bin/fd -Iu --glob '*\.DS_*' $HOME | xargs -r rm
    # or
    30 */2 * * 1-5 /usr/local/bin/rg --hidden --smart-case --color=never --files "$HOME" -g '*\.DS_*' | xargs -r rm
    ```
  * flush disk cache

    ```bash
    0 * * * * /usr/sbin/purge
    ```
  * flush DNS

    ```bash
    0 1-23/6 * * * /usr/bin/killall -HUP mDNSResponder
    ```
* localtion
  * macos

    ```bash
    $ sudo ls -Altrh /usr/lib/cron/tabs/<USERNAME>
    ```
  * freebsd/openbsd/netbsd

    ```bash
    $ sudo ls -Altrh /var/cron/tabs/<USERNAME>
    ```
  * centos/rhel/fedora/scientific/rocky/alma linux

    ```bash
    $ sudo ls -Altrh /var/spool/cron/<USERNAME>
    ```
  * debian/ubuntu/mint linux

    ```bash
    $ sudo ls -Altrh /var/spool/cron/crontabs/<USERNAME>
    ```
  * p-ux unix

    ```bash
    $ sudo ls -Altrh /var/spool/cron/crontabs/<USERNAME>
    ```
  * ibm aix unix

    ```bash
    $ sudo ls -Altrh /var/spool/cron/<USERNAME>
    ```

## tricky

{% hint style="info" %}

> references:
>
> * [Searching the manual pages](https://help.ubuntu.com/community/UsingTheTerminal#Searching_the_manual_pages)
> * [How To Readline](https://help.ubuntu.com/community/HowToReadline)
> * [Commandline Howto](https://help.ubuntu.com/community/CommandlineHowto)
> * [Advanced Commandline Howto](https://help.ubuntu.com/community/AdvancedCommandlineHowto)
>   {% endhint %}

### unicode

{% hint style="info" %}

> references:
>
> * [\* iMarslo: Unicode](https://imarslo.gitbook.io/ibook/good/text-processing/unicode) | [\* iMarslo: unicode in vim/nvim](https://imarslo.gitbook.io/ibook/vim/tricky#characters)
> * [How do you echo a 4-digit Unicode character in Bash?](https://stackoverflow.com/q/602912/2940319)
> * [centos locale utf-8](https://unix.stackexchange.com/a/25237/29178)
> * [How can I make iconv replace the input file with the converted output?](https://unix.stackexchange.com/q/10241/29178)
>
> Your description is vague. Either your terminal does not support Unicode, or you're editing a file that's in latin1 (= iso-8859-1).\
> On a bash or zsh shell, with `LC_CTYPE=en_US.UTF-8`, run `echo $'\xc3a9'`. If you see `é`, your terminal supports UTF-8. If you see `Ã©`, your terminal is showing latin1.
> {% endhint %}

> ```bash
> $ echo $'\xc3a9'
> a9
> ```

```bash
$ echo $'\xe2\x98\xa0'
☠
$ echo $'(U+2620) \U02620' | /usr/bin/xxd
00000000: 2855 2b32 3632 3029 20e2 98a0 0a         (U+2620) ....

# test
$ for (( i=0x2500; i<0x2600; i++ )); do
  UnicodePointToUtf8 $i
  [ "$(( i+1 & 0x1f ))" != 0 ] || echo ""
done
─━│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟
┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿
╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟
╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿
▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟
■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿
◀◁◂◃◄◅◆◇◈◉◊○◌◍◎●◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟
◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿

## test harness
$ for (( i=0x2500; i<0x2600; i++ )); do unichr $i; done
─━│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◆◇◈◉◊○◌◍◎●◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿

# https://stackoverflow.com/a/55639328/2940319
$ echo -e "\U1F304"
�
$ echo -e "�" | /usr/bin/hexdump -C
00000000  f0 9f 8c 84 0a                                    |.....|
00000005
```

* [unicode to utf8](https://stackoverflow.com/a/59040037/2940319)

  ```bash
  UnicodePointToUtf8() {
    local x="$1"                   # ok if '0x2620'
    x=${x/\\u/0x}                  # '\u2620' -> '0x2620'
    x=${x/U+/0x}; x=${x/u+/0x}     # 'U-2620' -> '0x2620'
    x=$((x)) # from hex to decimal
    local y=$x n=0
    [ $x -ge 0 ] || return 1
    while [ $y -gt 0 ]; do y=$((y>>1)); n=$((n+1)); done
    if [ $n -le 7 ]; then          # 7
        y=$x
    elif [ $n -le 11 ]; then       # 5+6
        y=" $(( ((x>> 6)&0x1F)+0xC0 )) \
            $(( (x&0x3F)+0x80 ))"
    elif [ $n -le 16 ]; then       # 4+6+6
        y=" $(( ((x>>12)&0x0F)+0xE0 )) \
            $(( ((x>> 6)&0x3F)+0x80 )) \
            $(( (x&0x3F)+0x80 ))"
    else                           # 3+6+6+6
        y=" $(( ((x>>18)&0x07)+0xF0 )) \
            $(( ((x>>12)&0x3F)+0x80 )) \
            $(( ((x>> 6)&0x3F)+0x80 )) \
            $(( (x&0x3F)+0x80 ))"
    fi
    printf -v y '\\x%x' $y
    echo -n -e $y
  }
  ```
* [unichr](https://stackoverflow.com/a/16509364/2940319)

  ```bash
  fast_chr() {
    local __octal
    local __char
    printf -v __octal '%03o' $1
    printf -v __char \\$__octal
    REPLY=$__char
  }

  function unichr {
    local c=$1  # Ordinal of char
    local l=0   # Byte ctr
    local o=63  # Ceiling
    local p=128 # Accum. bits
    local s=''  # Output string

    (( c < 0x80 )) && { fast_chr "$c"; echo -n "$REPLY"; return; }

    while (( c > o )); do
      fast_chr $(( t = 0x80 | c & 0x3f ))
      s="$REPLY$s"
      (( c >>= 6, l++, p += o+1, o>>=1 ))
    done

    fast_chr $(( t = p | c ))
    echo -n "$REPLY$s"
  }
  ```

### useful functions

* [universal extract](https://github.com/nemausus/dotfiles/blob/master/bashrc#L113)

  ```bash
  function extract () {
    case $1 in
      *.tar.bz2 ) tar xjf  "$1" ;;
      *.tar.gz  ) tar xzf  "$1" ;;
      *.tar.xz  ) tar Jxvf "$1" ;;
      *.tar.Z   ) tar xzf  "$1" ;;
      *.tar     ) tar xf   "$1" ;;
      *.taz     ) tar xzf  "$1" ;;
      *.tb2     ) tar xjf  "$1" ;;
      *.tbz     ) tar xjf  "$1" ;;
      *.tbz2    ) tar xjf  "$1" ;;
      *.tgz     ) tar xzf  "$1" ;;
      *.txz     ) tar Jxvf "$1" ;;
      *.zip     ) unzip    "$1" ;;
      *.gz      ) gunzip   "$1" ;;
      *         ) echo "'$1' cannot be extracted" ;;
    esac
  }
  ```
* [up to parent folder](https://www.commandlinefu.com/commands/view/10751/quickly-cd-out-of-directories-without-5-aliases)

  ```bash
  $ up() { local x=''; for i in $(seq ${1:-1}); do x="$x../"; done; cd $x; }

  # usage
  $ up
  $ up 3
  ```
* [generate cron time format](https://www.commandlinefu.com/commands/view/9294/print-a-cron-formatted-time-for-2-minutes-in-the-future-for-crontab-testing)

  ```bash
  # 2 minutes in the future
  $ echocron () { date '-d +2 minutes' +'%M %k %d %m *'; }
  ```

### search manual page

* `whatis -r <string>`
* `apropos -r <string>`

### [show services](https://bbs.archlinux.org/viewtopic.php?pid=1967721#p1967721)

```bash
$ systemctl list-unit-files -t service
```
