https://sciware.flatironinstitute.org/23_CommandLine
https://github.com/flatironinstitute/learn-sciware-dev/tree/main/23_CommandLine
Activities where participants all actively work to foster an environment which encourages participation across experience levels, coding language fluency, technology choices*, and scientific disciplines.
*though sometimes we try to expand your options
(These will always be a work in progress and will be updated, clarified, or expanded as needed.)
You may hear people use these terms to mean the same thing:
But there are some subtle differences. Let’s do a quick review.
We mention this mainly to explain the…
The shell interface surrounds the kernel just as a nutshell surrounds a nut 🥜.
ssh
)ipython
)
A shell is a program that uses a terminal to offer a command line interface, through which a user can direct the operating system to run other programs.
Here’s a typical shell command, with three parts:
--
) and short (-
) forms-l -a
= -la
)Shells are:
bash
: Bourne Again SHell (1989)
sh
)zsh
(1990)
bash
scripts & offers more features than bash in interactive modefish
, ksh
, tcsh
, …zsh
, bash
); runs a new shell as a child of your old onechsh
modules
, source
) need extra config in zsh
echo $SHELL
to find outexit
) or hurt performanceIn practice, you probably just want to use .bashrc
(if you run bash) or .zshrc
(if you run zsh)
shell | login (ssh) | interactive | neither |
---|---|---|---|
bash | .bash_profile | .bash_login | .profile | .bashrc | - |
.bash_logout | - | - | |
zsh | .zshenv | ||
.zprofile | - | - | |
.zshrc | - | ||
.zlogin , .zlogout | - | - |
Emacs
keybindings, though there are vim
bindings as well^A
as shorthand for Control a
togetherAlt-X
keybindings might not work without proper terminal configuration, especially on macs
Terminal.app->Preferences->Profiles->Use Option as Meta key
Iterm.app->Preferences->Profiles->Keys->Left option key: Esc+
Alt-X
keybindings can be simulated by hitting Esc
and then the character after releasingpwd
[Print working directory – where you are currently]cd DIR
[Change directory to DIR, where DIR is relative (projects/codes
) or absolute (/mnt/home/rblackwell/projects/codes
)]
cd
[Change to home directory]cd -
[Change to last directory]mkdir DIRNAME
[Create DIRNAME directory]rmdir DIRNAME
[Remove DIRNAME if empty]rm -r DIRNAME
[Remove DIRNAME recursively (all subdirectories and files). USE WITH CARE: -rf
‘force’ to ignore prompts. ]Left
(^B
), Right
(^F
) [Move back and forward a character]^Left
(Alt-B
), ^Right
(Alt-F
) [Move back and forward a word]Home
(^A
) [Jump to beginning of line]End
(^E
) [Jump to end of line]^L
(clear
) [Clear terminal]Shells have a builtin clipboard ‘kill ring’ where ‘cuts’ add new entries to the ring.
^K
[Cut “kill” to end of line from cursor]^U
[Cut line from beginning to end(zsh
)/cursor(bash
)]^W
(Alt-BS
) [Cut previous word - repeating adds to the last cut]^Y
[Paste whatever was last cut, Alt-Y
after to cycle through the kill ring]^/
[Undo (repeatable)]Up
(^N
), Down
(^P
) [Go to previous/next command in history of commands]history 10
[Print last 10 commands you entered on bash
, zsh
different]^R
[Search history. After matching, pressing ^R
repeatedly will go to previous matches]^C
[Send ‘interrupt’ signal to current process, usually stopping it]^D
EOF [Kills most interactive sessions, if line is empty (your current shell, python repl, etc)]%<id>
: Identifier for job, where <id>
is some number
^Z
[Pause current running process and background it]jobs
[List currently backgrounded jobs]kill %1
[Kill last backgrounded process]bg
[Unpause last backgrounded job, keeping in background]fg
[Unpause last backgrounded job, bringing back to foreground]mylongcommand with args here &
[Background job and start it]wait
[Wait until background jobs finish before doing more stuff]disown
[Detach last job from terminal/jobs - will continue running even if you disconnect]tmux
and screen
are sometimes better utilities for persistent jobsHow does the shell decide what to do when you enter a command?
which
[Show which command actually gets run when you typed a command]PATH
(echo $PATH
): Environment variable that has a list of directories to search for executablesalias
[List aliases – usually shortcuts to run commands with basic arguments you like]
alias rm="rm -i"
[Defines alias have rm
always prompt for deletions]PATH
, HOME
, …
Env. Variable | Description |
---|---|
PATH |
List of directories searched or executables |
USER |
The current username |
HOME |
Home directory of the current user |
PWD |
Path to the current working directory |
VISUAL |
Text editor |
FOO="Hello there" # Define a shell variable
echo $FOO # Use $ to obtain the value
# Shell variables are not seen by child process
bash -c 'echo $FOO'
# Convert into an environment variable using export
export FOO
# Environment variables are seen by child processes
bash -c 'echo $FOO'
# Variable expansion
echo "$FOO fellow coders"
# Delete existing variables
unset FOO
# Definition and export in one line
export BAR="Hello again"
# Inspect your environment
env
env | grep BAR
# PATH is a colon separated list of directories searched for programs
echo $PATH
# Create directory ~/bin for personal programs
mkdir ~/bin
# Create empty file ~/bin/prog
touch ~/bin/prog
# Make it executable
chmod u+x ~/bin/prog
# See if prog is found
which prog
# Prepending ~/bin to the PATH
export PATH=~/bin:$PATH
# Check that now we can find prog
which prog
~/.bashrc
or ~/.zshrc
# -- ~/.bashrc
...
# Make sure programs in ~/bin are found
export PATH=~/bin:$PATH
# Set my Editor
export VISUAL=nano
source
# -- myenv.sh
export PATH=~/bin:$PATH
export VISUAL=nano
...
✅ Execute script in current shell ➜ Script variables will persist
source myenv.sh
⛔ Run script as child process ➜ Script variables will not persist
bash myenv.sh
FI Cluster: Use the module
command to find and load software
$ module load git/2.35.1
$ which git
/mnt/sw/nix/store/wix1v2lrfbwrh4mar9ry07zzvsix82i5-git-2.35.1/bin/git
$ module show git/2.35.1
...
prepend_path("PATH","/mnt/sw/nix/store/wix1v2lrfbwrh4mar9ry07zzvsix82i5-git-2.35.1/bin")
Instructions in our FI Wiki!
Control the number of threads for parallel programs.
Env. Variable | Description |
---|---|
OMP_NUM_THREADS |
Number of OpenMP threads to use |
MKL_NUM_THREADS |
Number of OpenMP threads to use for Intel MKL |
OPENBLAS_NUM_THREADS |
Number of OpenMP threads to use for OpenBlas |
Env. Variable | Description |
---|---|
PYTHONPATH |
Searched for Python modules |
CC , CXX |
C/C++ compiler |
CFLAGS ,CXXFLAGS |
Compiler flags for C/C++ |
LDFLAGS |
Flags for the linker |
LIBRARY_PATH |
Searched for libraries at linktime |
LD_LIBRARY_PATH |
Searched for dyn. libraries at runtime |
CPATH |
Searched for C/C++ header files |
pwd
)PS1='\u@\h:\w\$'
dylan@rusty:~$
PS1='%n@%m:%~$'
dylan@rusty:~$
%F{colorcode}
, default: %f
%B{colorcode}
, default: %b
PS1=' %n @ %m : %~ $ '
PS1='%F{213}%n%F{177}@%F{141}%m%F{147}:%F{111}%~%F{75}$%f'
The simplest way to include extra information in your prompt
git branch --show-current
main
PS1='\u@\h:\w [$(git branch --show-current 2> /dev/null || echo NONE)]$'
setopt prompt_subst
PS1='%F{green}%c $(git branch --show-current 2> /dev/null) %F{blue} // %F{red} ♥ %f'
PS1='%n@%m:%~%1(j. [%j].)$'
user@host:~ [1]$
case $HOST in
rusty*) color=blue ;;
cc?lin*) color=green ;;
laptop) color=red ;;
esac
PS1="%F{$color}..."
RPS1='%F{blue}%T%f'
setopt autocd # type directory names without cd
setopt autolist # show options on single tab
setopt nobeep # stop making noise on every tab
Set the colors you see in ls
output
dircolors -p > .dircolors
edit .dircolors
dircolors .dircolors >> ~/.bashrc
.dircolors
specifies how file types and extensions map to colors (same color codes as bash)dircolors
(LS_COLORS=
) to your bashrc/zshrcMost commands presented here take from 0 to N arguments. The command is usually just repeated on the N arguments
man command
/
, and navigate with the keyboardman fprintf
$ man ls
LS(1) User Commands LS(1)
NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
Mandatory arguments to long options are mandatory for short options too.
-a, --all
The local directory is assumed when no argument is provided
ls
will show you all the files in a given directorymkdir
mv filename new_filename_or_location
rename or move a filerm
, rm -r
: remove files, and (recursively) directoriescat
prints the file(s) content, concatenatedless
shows the file content, scrolling by line or pageecho
prints text, including environment variables>
, >>
> file
will create a new file>> file
will append to the file>
redirects only stdout2>
redirects only stderr&>
redirects both togethermy_program > program.out 2> program.err
Note: this will overwrite!|
in a left to right execution
command1 | command2 | command3 | ...
<
`
are used when you want to store a result$ KERNEL_VERSION=`uname -r`
$ echo $KERNEL_VERSION
4.18.0-372.13.1.el8_6.x86_64
for do done
is used to create a loopfor nprocs in 1 2 4 8 16 32
do
mpirun -np $nprocs ./program
done
*
, **
) are used to iterate over files/directories/subdirectoriesshopt -s globstar # Enable globs on bash
for f in **/*.md
do # Iterate over the .md files in the directory and its subdirectories
echo $f
done
if elif else then fi
are used for conditional operationsif [[ $i -eq 0 ]]
then
echo "Null value"
elif [[ $i -lt 5 ]]
then
echo "Small value"
else
echo "Large value"
fi
Create complete scripts to perform common operations
#!/bin/bash
# The line above is the shebang, to tell Linux what interpreter to use
# Comments start with hash/pound
today=`date +%Y%m%d`
backup_folder=/tmp/save$today
list_files=`ls $HOME/ceph/data/`
mkdir $backup_folder
for file in $list_files
do
mv $file $backup_folder
done
tar czvf $backup_folder.tar.gz $backup_folder
https://bit.ly/sciware-shells-2022
fi
, esac
), C ({}
)dash
).inputrc
git diff <tab>
, rsync host:<tab>
, gcc -<tab>
most modern shells copied, adopted similar, popular features
opinions?
.bash_profile
(careful!)if [[ $- == *i* && -x /bin/zsh ]] ; then
SHELL=/bin/zsh exec /bin/zsh -l
fi
${file##*.}
-> csv
${file%%.*}
-> mydata
${file/#*./data.}
-> data.csv
${file/%.*/.bin}
-> mydata.bin
{1..10..2}
-> 1 3 5 7 9
$file
, $dir
, $x
, etc.)set
command (depending on shell/mode, will print environment variables as well)unset
command
$ fi="the best"
$ echo "flatiron is... $fi"
flatiron is... the best
$ sh
sh-4.2$ echo "flatiron is... $fi"
flatiron is...
#!/bin/bash
and doing chmod +x myscript.sh
) and run ./myscript.sh
module avail
to see all available modules
module avail -t | grep <pattern>
module load <modulename>
to load modulemodule unload <modulename>
to unload modulemodule purge
to unload all modulesmodule show <modulename>
to show what loading the module does conda create -n myenvname # places inside conda
conda activate myenvname
conda install numpy
conda deactivate
shadowing
python3 -m venv myenvname # places in cwd
source myenvname/bin/activate
pip install numpy
deactivate
$ cat setenv.sh
module purge
module load gcc python3 intel/compiler/2020 --force
module load pvfmm/1e4bef5 home/stkfmm/59951f4 openmpi2/2.1.6-intel-hfi intel/mkl/2020
source $HOME/projects/codes/fiber-private/env/bin/activate
$ source setenv.sh
PATH
)help
command at your prompt (for zsh man zshbuiltins
)export
, source
and .
(see above)alias
and command
bg
, fg
, jobs
, kill
, and ^Csuspend
and ^Zcd
, pwd
, pushd
, popd
, and dirs
help
history
and fc
echo
alias
: create or display a shortcut
alias
displays a list of all aliasesNAME=VALUE
, creates or updates the alias named NAME with the value of VALUEcommand
: use the actual command or builtin, even if there is an alias making it something else
\
has a similar effectbg
fg
jobs
-p
flag also gives the PID for the relevant processkill
: terminates the process specified by either a PID or a job number
-HUP
: “Good afternoon process, please consider stopping or maybe re-reading your configuration file”-TERM
(default): “hey process, just die.”-KILL
: “DIE DIE DIE STUPID PROCESS!!!”-INT
: “please stop”kill -TSTP
)suspend
cd
cd -
puts you into the last directory you were incd
with no arguments puts you back to your home directorycd A B
substitutes A for B in your path (zsh only)pwd
$PWD
)pushd
popd
dirs
pushd
echo
help
history
fc
"
vs '
"
does variable expansion'
does not\
>
and >>
>
writes output from a process to the file named after the greater than symbol. if the file already exists, it is overwritten.>>
appends output from a process to the file name after the double greater than. if the file does not exist, it is created.set -o noclobber
keeps you from overwriting files with >
0
) is a stream of information you send to a process1
) is usually the expected output of a process2
) is either related to something going wrong or sort of control/status information depending on the process2>&1
|
<( CMD )
(and >( CMD )
)
\`CMD\`
or $( CMD )
Globs match things (but are less awesome than regular expressions)
*
: 0 or more any characters?
: precisely any one character[somelistofcharspickone]
precisely one character from the list in the brackets (case matters)ls
man
man -k
/ apropos
is a keyword search of man pages (this is life changing)man
on a builtin, you might get a generic or bash man page.sed
, awk
, cut
sed
is used to selectively edit streams of text (usually replacement or transformation of one or more characters)awk
is used to carve up text based around some field separatorscut
selects single columnsnano
rename
rename foo foo00 foo?
sleep
less
(is more
)
cat
PS1
: default interactive prompt.PROMPT_COMMAND
: executed just before PS1, often used for timestamps.bash
prompt special characters, colors, and prompt variables: https://ss64.com/bash/syntax-prompt.html__git_ps1
predefined to display the branch. function parse_git_branch {
git symbolic-ref --short HEAD 2> /dev/null
}
# Define the prompt character
char="♥"
# Define some local colors
red="\[\e[0;31m\]"
blue="\[\e[0;34m\]"
green="\[\e[0;32m\]"
gray_text_blue_background="\[\e[37;44;1m\]"
# Define a variable to reset the text color
reset="\[\e[0m\]"
# Export PS1: default interactive prompt
PS1="\[\e]2;\u@\h\a[$gray_text_blue_background\t$reset]$red\$(parse_git_branch) $green\W\n$blue//$red $char $reset"
PROMPT
: default is %m%#
RPROMPT
: right side prompt variable. RPROMPT='%t'
autoload -Uz vcs_info
precmd() {vcs_info}
zstyle ':vcs_info:git:*' formats '%F{yellow}%B% (%b)'
vcs_info
function and call it in a pre-command.zstyle
: builtin command is used to define and lookup styles stored as pairs of names and values.PROMPT_SUBST
: expands the parameters usable in the prompt.%F{green}%B%
: Named colors must be surrounded by the escape characters.%F{black}%B%
sets the color for the setopt PROMPT_SUBST
PROMPT='%F{green}%B% %c ${vcs_info_msg_0_} %F{blue}%B% // %F{red}%B% ♥ %F{black}%B%'