# Shell | ![img \|150](https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Linux_command-line._Bash._GNOME_Terminal._screenshot.png/320px-Linux_command-line._Bash._GNOME_Terminal._screenshot.png) | A **Command-line interface** (CLI) is a means of interacting with a computer program by inputting lines of text called command-lines. Command-line interfaces emerged in the mid-1960s, on computer terminals, as a user-friendly alternative to punched cards. | | ---- | ---- | | | wikipedia:: [Command-line interface](https://en.wikipedia.org/wiki/Command-line_interface) | | ![img \|150](https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/X-Window-System.png/320px-X-Window-System.png) | In computing, a shell is a computer program that exposes an operating system's services to a human user or other programs. In general, operating system shells use either a command-line interface (CLI) or graphical user interface (GUI), depending on a computer's role and particular operation. It is named a shell because it is the outermost layer around the operating system. | | | wikipedia:: [Shell (computing)](https://en.wikipedia.org/wiki/Shell_(computing)) | ## Meta shell ### Help - man - Search all the man pages for a keyword - man -k searchTerm - e.g. - man -k directory - views all of the man pages related to the command directory such as mkdir, ls, etc. - man man - man intro - good intro guide to the command line - man bash - From Inside the man page - /searchTerm - searches inside that man page - n - goes to the next found term - --help? - help - apropos - searches for man pages related to that command - whatis - description of what the command does - info - compgen -c - Lists all available commads ### Terminal multiplexers - [[tmux]] - screen ### [[Shell on macOS]] ### [[Shell Scripting]] ### [[Cron]] ### [[Shell `at`, `batch`, `atq`, and `atrm` commands for scheduling]] ### Comments - `# comment` ## Environment - Each time we launch the terminal application, it creates a new session. The session immediately loads settings and preferences that make up the command line environment. - We can configure the environment to support the commands and programs we create. This enables us to customize greetings and command aliases, and create variables to share across commands and programs. - The environment refers to the preferences and settings of the current user. ### Sessions ### [[Shell Environment Variables]] ### Path/Directory - PWD - which - shows the path to that command - where the actual binary is located as determined by $PATH environment variable - which python3 - which ls ### General syntax of commands - Broadly, there is a command and then maybe various arguments. The arguments can then be further broken down into options/switches/flags, parameters, and targets. - | - | | - &lt;&gt; are often used in Syntax guides to indicate that the &lt;&gt; surround a place for a command rather than an actual command. | is used to denote OR or Optional so in the line above we read that a Command can be used on its own but may be followed by Switches (single letters, preceded by a hyphen that adjust what the command does), Parameters (Things that the command needs to know in order to work) and a Target (The thing that the command will be applied to). - switches aka options aka flags - often work either shorthand with one dash -U or with a full name -user - Evaluate to Boolean - Shorthand -a - Longhand --all - e.g. ls -l /home/brian - means List in Long Format (the -l switch) the directory (target) /home/brian ### Exit - exits terminal ### Keyboard commands - Tab - Autocomplete partially typed commands, files, etc. - If there are multiple possibilities, tab won’t complete, but if you double tap tab you’ll get a list of the possibilities - Good for finding the names of options and switches - Good for finding all the apps that start with a set of letters with apt-get install for example - Up arrow - Cycles through previous inputs - Ctrl - C - Halts the current command, cancel the current operation and/or start with a fresh new line - sends a sigint - q - quits a terminal mode, like in less, e.g. - Ctrl-c doesn’t work in less. I think it might be in vi or something - Ctrl - Z - Stops the current command, resume with fg in the foreground or bg in the background - Ctrl - R - Recent commands - Can search them as well? - Ctrl - L - Clears the screen leaving your typing there - Equivalent to the clear BASH command - Ctrl-D - Exits the shell - Ctr-alt-del - REISUB - Ctrl-A - Cursor to start of line - Ctrl-E - Cursor to end of line - Ctrl-U - Cut/Delete left of cursor - Ctrl-K - Cut/Delete right of cursor - Ctrl-W - Cut/Delete word to left of cursor - Ctrl-Y - Paste what you cut via Ctrl-U or K or W ### $ - Dollar prompt ### \# - Shown at prompt when root ### !! - Repeats last command - E.g. If you forget sudo you could just type "sudo !!" ### !$ - Repeats just the last argument - E.g. - Mkdir \~/docs/Evan - Cd !$ ### & - after last command to tell terminal to run it in the background, thus freeing up the currnet terminal for further use - e.g. - sudo apt-get upgrade & - ping google.com & ping apple.com & - runs both commands in background - It will output a process id number which you can check later with ps or kill with kill - You can keep doing this indeifintely with multiple commands to be sent as a background process ### History - Up Arrow - cycles through previous terminal commands - history - command to list your terminal history - !num - !53 - executes specific numbered command - !num:p - To edit a command from history - This prints the comnand instead of executing it so that you can then arrow up to edit it - history with datestamps - $ HISTTIMEFORMAT="%F %T " $ history - This is only valid for the current session, but you can also add this to your bash profile if you want that to be permanent - sudo !! trick to repeat last command with sudo prepended - omnioutliner:///open?row=dOpCUN901UY ### Recursion - -r or -R - changes attributes of all files inside a folder instead of just the folder itself ### -y - automatically answers yes to following confirmations ### Clear - Clears everything on the screen - equivalent to the ctrl-L keyboard shortcut ### Pause output per screen - less - usually per line? - a pun on more - q to quit - I think it runs in vi - more - usually per page? - you have to pipe the commands output to less or more ### Shells #### Change shells - chsh -s /bin/zsh #### Display current shell - echo $0 - echo $SHELL #### [[Bash]] #### [[Zsh]] #### [[fish]] #### [[dash]] #### Sh - https://en.wikipedia.org/wiki/Bourne\_shell #### Ash - https://en.wikipedia.org/wiki/Almquist\_shell - Almquist shell ## Functions - Example - function hello { echo Hello! } $ hello ## Reference ### Variables - Variables in functions are global by default unless declared local with local variablename=value - A variable in bash can contain a number, a character, a string of characters. You have no need to declare a variable, just assigning a value to its reference will create it. - Variables need to be preceded by $ when referencing them, but not when assigning them. - Variable names are case-sensitive - Variables are global by default, even in functions. local var=value declared it as local - Example - STR="Hello World!" echo $STR - Delete Variable - unset variable\_name - $1 takes the value of the first argument after the script automatically ### [[Shell Environment Variables]] ## Data types No actual data types ### Strings #### "" Vs '' - " " allows referencing other variables and command outputs whereas '' just sets whatever characters are in the quotes - "" - '' #### End of file thing: `<< EOF` - [linux - How does "cat << EOF" work in bash? - Stack Overflow](https://stackoverflow.com/questions/2500436/how-does-cat-eof-work-in-bash) - Assign multi-line string to a shell variable ```bash $ sql=$(cat <<EOF SELECT foo, bar FROM db WHERE foo='baz' EOF ) ``` - The $sql variable now holds the new-line characters too. You can verify with echo -e "$sql". - Pass multi-line string to a file in Bash ```bash $ cat <<EOF > print.sh #!/bin/bash echo \$PWD echo $PWD EOF ``` - The print.sh file now contains: ```bash #!/bin/bash echo $PWD echo /home/user ``` - Assign multi-line string to a shell variable ```bash $ sql=$(cat <<EOF SELECT foo, bar FROM db WHERE foo='baz' EOF ) ``` - The `$sql` variable now holds the new-line characters too. You can verify with `echo -e "$sql"`._ - Pass multi-line string to a file in Bash ```bash $ cat <<EOF > print.sh #!/bin/bash echo \$PWD echo $PWD EOF ``` The `print.sh` file now contains: ```bash #!/bin/bash echo $PWD echo /home/user ``` ## Data structures ### [[Shell Text Processing]] #### [[Shell Wildcards]] #### [[Regular Expressions|RegEx]] ### Arrays - ARRAYNAME=(value1 value2 .... valueN) - ARRAYNAME\[INDEXNR\]=value - \* or @ means all elements of the array - echo ${ARRAYNAME\[\*\]} or echo ${ARRAYNAME\[@\]} ## Control flow ### [[Shell Standard In, Standard Out, Standard Error]] ### [[Nix Services, Processes, & init System]] ### Piping - | - e.g. - cat bands.txt | wc - cat bands.txt | sort | grep The\* - Ignore error for a given command [linux - Bash ignoring error for a particular command - Stack Overflow](https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command) `a_command | true` - xargs - "The xargs command in UNIX is a command line utility for building an execution pipeline from standard input. Whilst tools like grep can accept standard input as a parameter, many other tools cannot. Using xargs allows tools like echo and rm and mkdir to accept standard input as arguments." - execute arguments - echo 'one two three' | xargs mkdir ls one two three - "By default xargs reads items from standard input as separated by blanks and executes a command once for each argument. In the following example standard input is piped to xargs and the mkdir command is run for each argument, creating three folders." ### Redirection - > - Instead of output going to screen it goes to a file - e.g. - ls -l Documents > documents.txt - sort < bands.txt - sort < bands.txt > bands_sorted.txt - >> makes the output appended to the file instead of overwriting - < - goes the other way - redirects stdin instead of stdout? - e.g. - cat gymnastics.txt is the same as cat < gymnastics.txt - cat volcanoes.txt | wc | cat > islands.txt ### Multiple commands - Order matters - commands are interpreted in order - Multiple Commands with Operators - && - run second command only if first command completes successfully - Ie, && is boolean so it requires both to be ‘true’ - e.g. sudo apt-get update -y && sudo apt-get upgrade -y || echo “Something went wrong” - || - run second command only if first command doesn’t complete successfully - Ie, boolean logic - you can try using || to echo something to report if the previous sequence ran successfully - like { command && command } || echo something went wrong - ; - run second command regardless of if first command completes successfully - ie, just a simple sequence, in order - {} Brace Expansion #remember - to group commands together like parentheses in logic - e.g. - command && echo command ran correctly || { echo command did not run correctly; commandtodointhatcase; } - need a space between the curly brackets - need ; at end of last command to return to shell correctly - Better example: - `cp {main.js,manifest.json} $obsidianVault/.obsidian/plugins/obsidian-wikipedia-data/"` - instead of having 2 separate cp commands, this will effectively do 2 cp commands - 1 for each item in the braces. - Multiple Commands with Conditionals - if - then - else - fi - e.g. - if ls \*.txt ; then echo We’ve found text files ; else echo No files found ; fi - Chain Commands with ; - touch file; sleep 10; rm file &lt;-- 10 seconds ### [[Shell Conditionals]] ### Iteration #### Loops - For Loops - Collection Traversal - seq method is outdated - for i in \`seq 1 10\`; do echo $i done - for i in $( ls ); do echo item: $i done - for i in {1...3} do echo $i done - While Loops - Example - count=0 while \[ $count -lt 100 \]; do echo $count let count=count+1 done - Until Loops - Like while loop but in reverse, basically. But I think you can just use boolean ! to get the same thing? - Example - COUNTER=20 until \[ $COUNTER -lt 10 \]; do echo COUNTER $COUNTER let COUNTER-=1 done - Syntax - C, C++, Java like syntax \#issue - start=4 - end=12 - jump=4 - for (( i = $start ; i &lt;= $end ; i += $jump )) - do - echo $i - done ### Exception/Error Handling #### [[Nix Services, Processes, & init System]] #### Interrupts [How Linux Signals Work: SIGINT, SIGTERM, and SIGKILL](https://www.howtogeek.com/devops/linux-signals-hacks-definition-and-more/) Software interrupts on Linux and Unix systems are made via signals. one can pass a signal to a running program or service to interact with it. - Shell Signals - HUP - INT - QUIT - ILL - TRAP - ABRT - EMT - FPE - KILL - BUS - SEGV - SYS - PIPE - ALRM - TERM - URG - STOP - TSTP - CONT - CHLD - TTIN - TTOU - IO - XCPU - XFSZ - VTALRM - PROF - WINCH - INFO - USR1 - USR2 - The basic Linux signals all have a number (1-30+) - A number of signals can be captured and redirected by the process, whereas others cannot - e.g. 9/kill - SIGTERM - 15 - may be ignored - SIGKILL - 9 - forces termination - only use if needed - if hanging - SIGINT ### Program termination - [[kill (command)]] - [[exit (command)]] ### Pause execution - [[sleep (command)]] ### Commands - [[pkill (command)]] - [[caffeinate (command)]] - [[Timeout (command)]] - [[watch (command)]] ## Quantitative ### Operators - && - || - -gt - -lt - -ge - -le - -eq - -ne - = - != - ! - e.g. - rm -r !(\*.txt) - delete all files except for txt files - `$(aCommand)` shell operator - The `$(...)` shell operator executes the command within parentheses and substitutes its output into the command line. - e.g.: - `docker rm -vf $(docker ps -a -q)` ### Math & science - bc - calculator ### Date & time ## Io ### [[Shell Standard In, Standard Out, Standard Error]] ### Input ### Output #### Echo - [How to use Echo Command in Linux (With Examples)](https://phoenixnap.com/kb/echo-command-linux) - echo string to print - Normally quotes are unnecessary - echo -E to echo the interpretation of escape chars. E.g. if you want actual \n instead of a new line. - echo “Hello world!” - Prints what is in quotes - -e - Allows you to use special characters - e.g. - echo “First line/nSecond Line/nThird Line” #### Printf #### Cat - cat file1 - text files: displaying them, combining copies of them and creating new ones. - cat &lt;-&gt; \#issue - good for exploring files since its non-destructive - e.g. - cat file1 file2 &gt; file3 - concatenates file1 and file2 together in file3 - cat file1 | less - displays contents of file1 on screen and pauses before each screen advance - cat file1 file2 file 3 | sort &gt; file 4 - concatenates file1, file2, and file3, pipes it to the sort filter which alphabetizes each line before it is written to file4 #### Tac - cat in reverse - last line first, through to the first line. #### Head - displays top of text file - defaults to 10 lines - head -3 3 lines, etc. #### Tail - displays bottom of text file - defaults to 10 lines - tail -5 5 lines, etc. #### Less - sort of more sophisticated version of cat #### More #### Fold - Wraps text - fold -w5 myfile.txt &gt; newfile.txt - Wraps the lines of myfile.txt to a width of 5 characters, and writes the output to newfile.txt. #### Colors and text effects - echo -e "\\033\[31m Hello World" - I think needs a Bash upgrade on macOS - \[31m controls the text color - 30-37 sets foreground color - 40-47 sets background color - -e allows escaped characters ### Ui - [[ncurses]] - Zenity ### Graphics - scrot screenshot tool - works in terminal ### Multimedia - speaker-test - tests the default audio device by playing tones - aplay \#issue - plays a sound file - espeak - text to speech? - mplayer \#issue - omxplayer - imagemagick - Can make gifs e.g. - Find / -name \*.wav -exec aplay {} \\; \#issue - (Plays all wav files it can find) ### Files ## Tools - [[Homebrew]] - [[Windows Subsystem for Linux]] - [[Git Bash]] - [[PowerShell]] - [[NirCmd]] - [[Zsh]] - [[Midnight Commander]] ## Sources ## Inbox - -e name - Does a file named name exist in the working directory - -d name - is the fike named name a directory? - [[Shellcheck (script SCA checker)]] - [12 Factor CLI Apps. CLIs are a fantastic way to build… | by Jeff Dickey | Medium](https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46) - [ralish/bash-script-template: A best practices Bash script template with several useful functions](https://github.com/ralish/bash-script-template)