Skip to content
JZLeetCode
Go back

Linux Cheatsheet, tips and Commands

Updated:

Table of contents

Open Table of contents

A

adb

# get device mac address mac_addr mac secret mac_sec
adb shell idme print
# start adb shell as root
adb shell su
# reboot
adb reboot
# get properties
adb shell get-dynconf-value <property_name>
# sendText
adb shell sendText <text>

alias

alias sshp
# how to set ssh to not use proxy command?
alias sshp='ssh -o ProxyCommand=none'

B

bg

# ctrl + z to suspend a foreground job
bg %1 # resume job 1 in background

C

chmod

chmod 777 -R <dir> # set read write executable for directory by user, group, others
chmod a+rwx -R <dir> # same as above
chmod +x <file> # make file executable by anyone, +x, a+x, same as ugo+x

chown

sudo chown -R <user1> ./folder # recursively change owner to user1 for folder

D

date

date +%F # today's date 2018-04-21
date # Sat Apr 21 16:43:16 PDT 2018
date -r <epoch seconds> # example 1547927682
> date +%s           # Current time seconds, mac
1544081888
> date -v -15M +%s   # 15 minutes ago in seconds, mac
1544081034
> date -r 1544081034 # seconds to readable, mac
Thu Dec  6 09:23:54 IST 2018
> date +%s                  # Current time seconds, linux
1544082214
> date -d "15 mins ago" +%s # 15 minutes ago in seconds, linux
1544081345
> date -d @1544081345       # seconds to readable, linux
Thu Dec  6 07:29:05 UTC 2018
today=$(date +%Y/%m/%d) # today's date in format 2020/02/22
today=$(date) # Sat Feb 22 06:15:12 UTC 2020
date -d $today +%Y/%m/%d # reformat date

df

How to check disk space on the command line?

% df -h
# mac result
Filesystem        Size    Used   Avail Capacity iused ifree %iused  Mounted on
/dev/disk3s1s1   460Gi    10Gi   343Gi     3%    412k  3.6G    0%   /
devfs            204Ki   204Ki     0Bi   100%     706     0  100%   /dev
/dev/disk3s6     460Gi    20Ki   343Gi     1%       0  3.6G    0%   /System/Volumes/VM
/dev/disk3s2     460Gi   6.4Gi   343Gi     2%    1.2k  3.6G    0%   /System/Volumes/Preboot
/dev/disk3s4     460Gi   3.0Mi   343Gi     1%      53  3.6G    0%   /System/Volumes/Update
/dev/disk1s2     500Mi   6.0Mi   483Mi     2%       1  4.9M    0%   /System/Volumes/xarts
/dev/disk1s1     500Mi   5.6Mi   483Mi     2%      32  4.9M    0%   /System/Volumes/iSCPreboot
/dev/disk1s3     500Mi   824Ki   483Mi     1%      74  4.9M    0%   /System/Volumes/Hardware
/dev/disk3s5     460Gi    99Gi   343Gi    23%    1.4M  3.6G    0%   /System/Volumes/Data
map auto_home      0Bi     0Bi     0Bi   100%       0     0     -   /System/Volumes/Data/home
/dev/disk3s3     460Gi   986Mi   343Gi     1%      41  3.6G    0%   /Volumes/Recovery
/dev/disk4s2     167Gi   2.7Gi   165Gi     2%    108k  4.3G    0%   /Volumes/code

du

How to check disk space usage on the command line?

du -b <file> | cut -f1 # get file size in bytes
# list file and folder sizes in current directory
sudo du -sh * | sort -h -r
du -ahx . | sort -rh | head -5
du -hd 1 . # mac

F

fg

fg %4 # bring job 4 to foreground

find

# search text in gz zipped log
find . -name "*.gz" -exec zgrep -nI "text to search" {} +

G

Git

How to check a github repo size?

See stackoverflow reference.

We can check with GET /repos/:user/:repo with GitHub API.

You can access https://api.github.com/repos/<user_or_organization_name>/<repo_name> with a browser such as google chrome.

or use curl

How to Check the Summary (Changed Files) of the Last Commit?

git log -1 --stat # show basic info and all changes
git show -1 --summary  # show basic info and created or removed files, does not include changed files

other commands

# rename branch
git branch -m <new_branch_name>

# view branch detailed info
git branch -vv

# set upstream
git branch -u <remote>/<branch_name>

# cherry pick remote commit
git fetch origin
git cherry-pick <commit hash>

# stash change for later
git stash save <useful message>
git stash show -p stash@{1}

git push <remote-name> <local-branch-name>:<remote-branch-name>  # add -u to track remote branch with local branch, i.e. set as upstream
# delete remote branch
git push -d <remote_name> <branch_name>
git push origin --delete <branch_name>

# show last three tags
git tag -l | tail -3

# github ssh setup
https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
git log --all  --oneline --graph
# --decorate only applies to the head, --decorate=full example: commit 6b51db131e32e8fcaaa075e7d1134dbf9f7359ee (HEAD -> refs/heads/main, refs/remotes/origin/main)
# --oneline shows the commit hash and commit message
# --graph add a * (star symbol) and try to draw a graph, each commit may take more than one line
# oneline graph for blame
git log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all
# two line graph for blame
git log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'

How view and config git at system/global/local(repo) levels?

# to show config
% git config --list --system
# on mac
fatal: unable to read config file '/etc/gitconfig': No such file or directory
# global config file for unix based OS (linux, macOS) is at ~/.gitconfig, for windows c:\\Users\<username>\.gitconfig
% git config --list --global
user.name=<your_name>
user.email=<your_email>
# local config file location: <repo_path>/.git/config
% git config --list --local
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.precomposeunicode=true
user.name=<your_name>
user.email=<your_email>
remote.origin.url=git@github.com:<org_or_username>/<repo_name>.git # for ssh connected
# remote.origin.url=https://github.com/<org_or_unsername>/<repo_name>.git # for https connected
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.main.remote=origin
branch.main.merge=refs/heads/main
  1. git configuration doc
  2. where is global config data betterstack
  3. git config file locations theserverside

grep

$ grep -c # count of the number of lines
% echo "line 1\nline 2\nline 3"
line 1
line 2
line 3
% echo "line 1\nline 2\nline 3" | grep -c line
3

I

id

% id  # mac
uid=501(<username>) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),701(com.apple.sharepoint.group.1),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),400(com.apple.access_remote_ae)
(base) root@43a8fed75479:/# id  # linux
uid=0(root) gid=0(root) groups=0(root)

IO redirection

<command> > /dev/null # redirect standard output to be discarded
<command> > /dev/null 2>&1 # reroute stdout and stderr to be drscarded
nohup myscript.sh >myscript.log 2>&1 </dev/null &
#\__/             \___________/ \__/ \________/ ^
# |                    |          |      |      |
# |                    |          |      |  run in background
# |                    |          |      |
# |                    |          |   don't expect input
# |                    |          |
# |                    |        redirect stderr to stdout
# |                    |
# |                    redirect stdout to myscript.log
# |
# keep the command running
# no matter whether the connection is lost or you logout
  1. The Linux Document Project (TLDP) doc
  2. stackoverflow question about < /dev/null

J

jobs

$ jobs # list jobs
[1]  + suspended (tty output)  vim

L

lsb

# check ubuntu version
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.2 LTS
Release: 24.04
Codename: noble

S

shell

$ echo $SHELL
/bin/zsh  # mac os 15 default
/bin/bash  # linux default
# Ctrl+R  reverse incremental search (readline/bash/zsh): recall matching history lines
# press Ctrl+R again (and again) to cycle through all matches for your search string

Shell ! and $ quick reference

History (!^, !$, !!, …)

sudo !!  # !! repeat last command (e.g. add forgotten sudo)
vim !$  # !$ last argument of previous command
cd !^  # !^ first argument of previous command
echo !*  # !* all arguments of previous command
echo !:0  # !:0 command name from previous line
echo !:2  # !:n nth word of previous line (example: second word)
!-2  # !-n nth command back (example: two commands ago)
!git  # !string last command starting with string
!?foo  # !?string last command containing substring
cp ~/Downloads/report.pdf /tmp/  # previous command (meant mv not cp)
^cp^mv^  # ^old^new on previous line → mv ~/Downloads/report.pdf /tmp/
!42  # !n history event by number (see `history` for numbers)

Parameters ($@, $1, $?, …)

echo "$0"  # $0 script name (or shell name if interactive)
echo "$1" "$2"  # $1 $2 first and second positional arguments
echo "${10}"  # ${n} braces required for positional args past $9
echo "$#"  # $# number of positional arguments
set -- 'my file.txt' 'second' 'third'  # three positional args; first contains a space
printf '%s\n' "$@"  # $@: each arg separate → three lines from printf
# my file.txt
# second
# third
printf '%s\n' "$*"  # $*: one joined string (first IFS char between args) → one line
# my file.txt second third
echo "$?"  # $? exit status of last foreground command
echo "$$"  # $$ PID of current shell
echo "$!"  # $! PID of last background job
echo "$_"  # $_ last argument of previous command

$_ vs !$

Often the same string after a one-line command; they can differ with pipelines, complex quoting, or when “last word on the history line” is not the same as “last argument” of the executed command.

touch a b c
echo "$_"  # $_ → c (last argument)
# ls /tmp/foo
# vim !$    # !$ → /tmp/foo (last word); expands before run, like other ! history

T

tmux

tmux is a terminal multiplexer: one terminal hosts multiple sessions, each with multiple windows (tabs) and panes (splits). Sessions persist after you disconnect, so you can detach and attach later (great over SSH).

Key concept: prefix key is Ctrl+b by default. Press prefix, release, then the next key. Below C-b means Ctrl+b.

Sessions vs windows vs panes

When to use which:

Rule of thumb: if you’d want them side-by-side on a second monitor, use panes; if you’d put them on separate desktops/spaces, use windows.

# --- session management (from outside tmux) ---
tmux ls                       # list sessions (alias of `tmux list-sessions`)
tmux new -s work              # create a new session named "work"
tmux a                        # attach to the most recent session (alias of `attach`)
tmux a -t work                # attach to session named "work"
tmux kill-session -t work     # kill session "work"
tmux kill-server              # kill all sessions
# --- inside tmux: sessions ---
C-b d        # detach from current session (leaves it running in background)
C-b s        # interactive list of sessions to switch to
C-b $        # rename current session
C-b (  / )   # previous / next session
# --- windows (tabs) ---
C-b c        # create a new window
C-b ,        # rename current window
C-b w        # preview/list all windows (interactive picker with preview)
C-b n / p    # next / previous window
C-b 0..9     # jump to window by number
C-b &        # kill current window (asks for confirmation)
C-b f        # find window by name
# --- panes (splits) ---
C-b %        # split current pane vertically (left | right) — DEFAULT
C-b "        # split current pane horizontally (top / bottom) — DEFAULT
# my ~/.tmux.conf rebinds the splits to more intuitive keys:
#   unbind % ; unbind '"'
#   bind | split-window -h    # C-b |  vertical split (| looks like the divider)
#   bind - split-window -v    # C-b -  horizontal split
# so on my machine % and " do nothing — use | and - instead.
C-b o        # cycle to next pane
C-b ; / arrows  # last pane / move by direction
C-b z        # zoom (toggle) current pane to fullscreen
C-b x        # kill current pane (asks `kill-pane? (y/n)` in status bar — press y)
C-b {  / }   # swap pane with previous / next
C-b space    # cycle through preset pane layouts
# --- copy mode (scrollback / select text) ---
C-b [        # enter copy mode; use arrows / PgUp / PgDn / `/` to search
# in copy mode (default emacs keys): space=start selection, enter=copy, q=quit
C-b ]        # paste most recent buffer
# --- misc ---
C-b ?        # show all key bindings
C-b :        # command prompt (e.g. `:new-window -n logs`)
tmux source-file ~/.tmux.conf # reload config without restarting

Plugins: tpm + resurrect + continuum

I manage plugins with tpm (Tmux Plugin Manager) and use two plugins to survive machine restarts:

Install tpm once:

git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

Relevant lines in ~/.tmux.conf:

set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'

# autosave snapshot every N minutes (0 = off)
set -g @continuum-save-interval '15'
# 'on' = restore last saved session when tmux starts
set -g @continuum-restore 'off'

# must be the LAST line — initializes tpm
run '~/.tmux/plugins/tpm/tpm'

After editing .tmux.conf, reload it (C-b r if you bound it, otherwise tmux source-file ~/.tmux.conf), then:

C-b I   # capital I — install plugins listed in .tmux.conf
C-b U   # capital U — update plugins
C-b alt+u  # uninstall plugins removed from config

Resurrect manual save/restore (continuum just runs save automatically):

C-b C-s   # save current tmux environment to disk
C-b C-r   # restore last saved environment
# snapshots live at ~/.local/share/tmux/resurrect/ (or ~/.tmux/resurrect/ on older setups)

Tip: keep @continuum-restore 'off' initially so tmux doesn’t surprise you with old sessions on startup; flip to 'on' once you trust it.

U

ulimit

(base) root@43a8fed75479:/# ulimit -a  # docker container from image condaforge/miniforge-pypy3
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31325
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1048576
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
(base) root@43a8fed75479:/# cat /proc/sys/fs/file-max
801566
(base) root@43a8fed75479:/# cat /proc/sys/fs/file-nr
352	0	801566

% ulimit -a  # mac os single admin user
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8176
-c: core file size (blocks)         0
-v: address space (kbytes)          unlimited
-l: locked-in-memory size (kbytes)  unlimited
-u: processes                       4000
-n: file descriptors                256
% ulimit -Hn
unlimited
% ulimit -Sn
256

File Descriptor (wiki) limit references:

  1. limits on the number of file descriptors unix stack exchange question
  2. linux kernel file-max and file-nr doc
  3. limits on the number of linux file descriptors Baeldung
  4. increase max for file descriptors cyberciti

uname

uname -s # os name,e.g., GNU/Linux, Darwin(mac)

(base) root@43a8fed75479:/# uname -r  # linux
6.10.14-linuxkit
% uname -r  # mac
24.2.0

(base) root@43a8fed75479:/# uname -v  # linux
#1 SMP Thu Oct 24 19:28:55 UTC 2024
% uname -v  # mac
Darwin Kernel Version 24.2.0: Fri Dec  6 18:51:28 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T8112

uname -m # platform x86_64, arm64

MacOS Darwin name references:

  1. https://apple.stackexchange.com/questions/401832/why-is-macos-often-referred-to-as-darwin
  2. https://en.wikipedia.org/wiki/Darwin_(operating_system)
  3. https://www.howtogeek.com/295067/why-is-macos-software-sometimes-labeled-darwin/

W

which

How to find the file location/path of the executable/command?

Sometimes you may have different versions of the executable from different sources installed. Once I encountered a unique bug caused by the jq installed with conda shadowing the other jq installed with homebrew.

$ which whoami
/usr/bin/whoami

X

xclip

# copy current dir to xclip
pwd | xclip
# copy to clipboard, can be pasted in gui, e.g., in firefox
pwd | xclip -sel clip
# paste from xclip
xclip -o

xrdp

sudo yum update
sudo yum install xrdp x11rdp xorgxrdp
sudo /etc/init.d/xrdp status
# result should be
xrdp is stopped
xrdp-sesman is stopped

update cert when cert auto-renew

MY_CERT_MS=com.<domain>.certificates.<username>.aka.corp.<domain>.com-STANDARD_SSL_SERVER_INTERNAL_ENDPOINT-RSA
# retrieve the certificate the private key
<command1> -t Certificate $MY_CERT_MS | openssl x509 -inform DER | sudo tee /etc/xrdp/cert.pem > /dev/null
<command1> -t PrivateKey $MY_CERT_MS | openssl pkcs8 -nocrypt -inform DER -outform PEM | sudo tee /etc/xrdp/key.pem > /dev/null
sudo chmod 400 /etc/xrdp/key.pem /etc/xrdp/cert.pem
sudo /etc/init.d/xrdp restart
sudo /etc/init.d/xrdp status

References

  1. multi-lingual manpages.org
  2. Michael Kerrisk man-pages
Share this post on:

Previous Post
LeetCode 378 LintCode 1272 Kth Smallest Element in a Sorted Matrix
Next Post
LeetCode 3653 XOR After Range Multiplication Queries I