Spool Five

Shell Commands

Aug 8, 2021

This is a note on some of the commands I have found useful and want to remember.

Setting the default shell

List all available shells, then set the default shell with chsh

cat /etc/shells

# Example output:
# /bin/bash
# /bin/csh
# /bin/dash
# /bin/ksh
# /bin/sh
# /bin/tcsh
# /bin/zsh

chsh -s /bin/zsh

popd and pushd

  • can use to create a directory ‘stack’
  • pushd pushes the new directory to the stack, e.g., pushd ~/directory/another/andanother/ and moves into that directory
  • then popd takes you back to the previous directory in the stack.
  • popd +0 prints the stack (current directory first)
  • popd +1 takes you to second directory in stack.

Exclamation mark !

A very useful command! I mainly just use the first two points below a lot.

  • double exclamation !!: re-run previous command
  • exclamation plus number !500 run the ‘500th’ command from history
  • exclamation plus a few characters !pa runs the recent command matching that pacman -Sy or whatever
  • any of the above followed by colon ‘p’ !!:p prints the command instead of running it.
  • exclamation with dollar sign !$ use argument of previous command.
    • E.g., say you create a file touch filename then, if you run vim !$ it will open that file in vim. Useful for very long filenames/arguments.
    • The $ represents the last argument of previous command. For example: ping google.com -c 4
      • echo !$ will print 4
      • echo !^ will print the first argument instead (google.com)
      • echo !* will print all the arguments (google.com -c 4)
    • to get a specific number argument, you first ‘select’ the command, then use colon+number. E.g.:
      • ping google.com -c 4
      • echo !!:2 returns -c if it was the previously run command. Alternatively, use !pi, !389 (the history number), etc.
      • Also, you can use ranges: echo !!:2-4
    • Also, you can ‘find and replace’ text in a command using ^ e.g.,
      • Say you run ping googl.com -c 4
      • You can correct the error in ‘googl’ with ^googl^google this automatically re-runs the command.

tail

Useful for long log files, etc.

# Show last 8 lines in file:
    tail -n 8 path/to/file

# Print a file from a specific line number:
    tail -n +8 path/to/file

# Show last `count` lines in a file and refresh every =seconds" seconds:
    tail -n count -s seconds -f path/to/file

Find & Replace across multiple files

grep -rl "target_string" . | xargs sed -i 's/target_string/new_string/g'

What is happening:

grep -rl: search recursively, and only print the files that contain “old_string” xargs: take the output of the grep command and make it the input of the next command (ie, the sed command) sed -i ‘s/old_string/new_string/g’: search and replace, within each file, old_string by new_string

Alternative: I used this to replace all the footer email links in my blog directory. Seemed to work perfectly. The section included with find makes sure to skip the git directory.

find . \( -type d -name .git -prune \) -o -type f -print0 | \
    xargs -0 sed -i 's/target_string/new_string/g'

less - Exclude Lines from View

Once your file is open in less (or journalctl) press the following keys:

  • &
  • !
  • “your-exclude-keyword”

Ampersand opens the pattern matching mode, exclamation mark tells less to exclude the following part, and then you enter your search term.

shuf

Shuffle lines

shuf /path/file

shuf --input-range=1-100

# Random number between 1 and 100
shuf --input-range=1-100 | head -1

sort

sorts alphabetically, use -n flag for numeric sorting.

  • -r for reverse order
  • -f ignore case
  • -t to designate field separator
  • -u unique sorting - only sort unique lines.
  • -o output (to file, for example)
  • -R random sorting, but groups identical keys

For example:

sort /path/file

# Sort using only unique lines
sort -u /path/file

# Sort a file in place (overwrite)
sort -o /path/file /path/file

uniq

Print unique lines.

  • -u only return unique lines
  • -d only return duplicated lines
  • -c provide ‘count’ for how many times lines occur

Processes

Some of my most used commands

  • kill (process id)
  • pgrep (search term) find process by search term
  • killall (search term) kill processes by search term
  • pstree
  • setsid - spawn a detached child process

Disk Usage

  • df -h: filesystem disk usage (in human readable format)
  • du -h /path/dir/: usage for file/directory

Process substitution

Using < and > to treat steps in a process as a ‘file’ as opposed to stdin/out. The file is created in the proc / dev directory. See this video

For example, run a program and (a) outputs logs to less and (b) writes error messages to a file, at the same time.

program.sh > >(less) 2> >(tee errors.txt)

Or, send a directory archive to two different locations at once (without creating intermediate archive file):

tar cf - directory | tee >(ssh server1 tar xf -) (ssh server2 tar xf -) > /dev/null

Or, (a comment from the YouTube video): If you ever need to get lsusb info but have too many devices, doing diff <(lsusb) <(sleep 3; lsusb) will show you the device, you just need to plug it in in the span of 3 seconds after hitting enter.