# CS202 Review Session 02 ## The Shell and IDEs Notes from Sam Frank, TA Spring 2024 Edited by Andrew Hua, TA Spring 2025 Inspiration from [MIT Missing Semester](https://missing.csail.mit.edu/2020/) and [Fireship VSCode Tips](https://www.youtube.com/watch?v=ifTF3ags0XI) _Try viewing this in markdown!_ 1. Introduction 2. Motivation 3. The Shell 4. IDEs 5. Lab 2 overview ------------------------------------------------- 1. Introduction 2. Motivation - Learning these tools will help *immensely* in class and outside it - You will program faster - You will understand your machine better - You will get closer to the OS 3. The Shell What is it? - def: a textual interface to the kernel (OS) - in practice: a program that takes keyboard inputs, and tells the OS to do something How to Use? - Open a terminal app - Enter commands into the prompt ("Command Line Interface") Basic Commands: - `date` --> prints date - `echo [arg]` -> prints [arg] - `ls` - you will implement in lab 2 - "commands" are really just programs! - how does shell know where to find programs? - `echo $PATH` - $PATH contains list of places for shell to look for programs - `which ls` - prints absolute pth to `ls` executable - or specify path when command isn't in $PATH - e.g. ./cs202-run-docker - `pwd`: print working directory(useful if you're ever lost) - `cd`: change directory(use `..` to go back a directory e.g. `cd ../.. goes back 2 levels) Flags and Pipe Building: - `ls -l`, `ls -a`, `ls -al` - what are these flags? -> `man ls` - pipes (`|`) are one of the most important features of the shell! - this is where you really unlock the full powers of the shell - `ls -al` -> `ls -al | head -n3` -> `ls -al | head -n3 | tail -n2` More Redirection: - Redirect to a file with `>` - or take input from file with `<` - ex: `echo hello > hello.txt` - `cat hello.txt` - more fun ex: `curl --silent -L www.google.com > google.html` Productivity Tips! - autocomplete !!!!! (tab) - ex: when you are running `./cs202-run-docker`, press tab after typing the first few characters - rerun last command: !! (especially helpful with sudo) - can also toggle through previous commands with up/down arrow When to Use the Shell: - All the time! (okay, maybe not ALL the time) - It is most helpful when you are running programs or browsing files - Can also edit/interact w/ text files (quick plug for Vim) - If you ever have a question about a command: `man [COMMAND]` - demo `man ls` 4. IDEs (VSCode) What is an IDE? - IDE = Integrated Development Environment - All the things you need for development processs in one place - text editor - compiler(s) - debugger - syntax highlighting - etc. - Ex: Eclipse, JetBrains (IntelliJ, PyCharm, etc.), Visual Studio Code Why VSCode? - fairly minimal => not too complicated, easy to learn - many productivity enhancements - flexible, supports a variety of languages(though we will just be using C and C++ here) - I use it (so I can teach it) - I also recommend it Open VSCode normally, or through terminal (`code [directory]`) Use keyboard to do things! - faster than mouse - learning shortcuts is an investment: take the time to learn a few you use right now, and you will save HOURS in this course alone - [mac](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf) - [windows](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf) - [linux](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf) Cmd + P to open Command Palette - start typing a file name to open that file (much easier than file explorer!) - search for a function with `@` - ... or go to a specific line with `:` (can also use Ctrl + G outside of cmd palette) - Run a command with `>` - ex: `> Shell Command: install 'code' in PATH` - this is how I can open VSCode from my shell! Other Productivity Tips: - No autosave => use Cmd + S - Open up a terminal in VSCode with Ctrl + Shift + ` - Comment out a block of code by highlighting it and typing Cmd + / - Use Cmd+C, Cmd+X, and Cmd+V without highlighting to copy, cut, paste entire lines - Cmd+enter to insert newline below, Cmd+shift+enter to insert above - Splitscreen and switch between the two pages with Cmd+1 and Cmd+2 - hover over function with your mouse to see definition, documentation (if it exists) Version Control: - You should definitely familiarize yourself with git cli - [Missing Semester Explainer](https://missing.csail.mit.edu/2020/version-control/) - BUT: VSCode can be nice too - Source control panel will display: - status of remote (i.e. are there changes you need to fetch?) - any modified/staged/untracked files (not included in .gitignore) - click on one to display a side-by-side comparison of your commited version and your working copy(super useful in lieu of `git diff`) - You can easily stage or unstage files - Or undo unstaged changes (this is clutch, and much easier than working with the cli) - You can even commit with a message and push, although I recommend doing this from the cli - Anything more advanced will probably have to be through the cli A simple setup (for these labs): - VSCode - With terminal open - two tabs(or [tmux](https://hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/) to avoid frequent tabbing): 1. Docker (to make, run, test, and grade my code) 2. normal shell (to `git add`, `commit`, `push`) Give this a shot, but find what works best for you! (personally I used only terminal and split my view with tmux) 5. Lab 2 overview 5.1. Motivation - You will implement ls, which is a command, in lab 2. - It will help you practice reading man pages, working with system calls, toying with the APIs, and design as well as re-design/refactor your code. 5.2. File definition - Normal files can be: "test.txt", "main.c", ... - Normal directories can be: "foo/", "bar/", "foo/bar/", ... - Some files and directories start with ".". If you are curious, you can inspect ".git" in your repository. This is where git stores your information and commit history. These are usually hidden from the users when they invoke `ls`. Specifically, to see them, you would need `ls -a` - In addition, "." also means current directory. ".." means parent directory. "~" means home directory. Every directory you create will have these 2 "pseudo-directories". - With that, there are also relative and absolute path: + Relative is a path from the current directory. Usually, it prefixes with "." and "..". For instance: `./my/relative/path/to/file`. +Absolute path is a path from the fullpath you are providing. For instance: `~/my/absolute/path`. Example (is a path a normal directory?): if(is_dir(pathandname) && (strcmp(name,".")!=0 && strcmp(name,"..")!=0)) 5.3. File permissions - Lab 2 will have you print the permission of a file, which has the form: -rwxr-xr–-. There are 10 chars, but we are concerned with the last 9. - First character (-): Indicates the type of file. - is regular file, d is directory. - Next three characters (rwx): Permissions for the owner (read, write, execute). - Next three characters (r-x): Permissions for the group (read, no write, execute). - Last three characters (r--): Permissions for others (read, no write, no execute). - Numeric representation - chmod 777? Each number corresponds to 3 characters in the string representation. Example: 700 -> 7,0,0 -> 111,000,000 -> rwx------ 5.4. Flags - ` ./ls -alR foo/ bar/` | program | flags | args - Flags refer to -a, -l, -R. You will need to support combination of them as well. - To make it more clear, let's look at getopt() (learn more `man 3 getopt`). int getopt(int argc, char* const argv[], const char *optstring) - argc: number of arguments supplied (from main) - argv: array of arguments supplied (from main) - optstring: the flag we want to parse - optind: a global variable specifying the index in argv to parse the next time - around, initialized to 1. If getopt() finds another option character, from the optstring you provided, in the arguments supplied, it returns that character, updating the variable optind so the next call to getopt() can resume the scan. It returns -1 otherwise. Example: // Example from man 3 getopt #include #include #include int main(int argc, char *argv[]) { int flags, opt; int nsecs, tfnd; nsecs = 0; tfnd = 0; flags = 0; while ((opt = getopt(argc, argv, "nt:")) != -1) { switch (opt) { case 'n': flags = 1; break; case 't': nsecs = atoi(optarg); tfnd = 1; break; default: /* '?' */ fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n", argv[0]); exit(EXIT_FAILURE); } } printf("flags=%d; tfnd=%d; nsecs=%d; optind=%d\n", flags, tfnd, nsecs, optind); if (optind >= argc) { fprintf(stderr, "Expected argument after options\n"); exit(EXIT_FAILURE); } printf("name argument = %s\n", argv[optind]); /* Other code omitted */ exit(EXIT_SUCCESS); } - Will parse -n and -t. - Expect at least 1 argument after the flag - Try compile, run and observe the output: `./a.out -n`, `./a.out -t`, `./a.out -nt`, `./a.out -n foo bar` - getopt_long is quite similar. The exception is that getopt_long allows us to parse flags in long format, which prefixes with `--` instead of `-` - Read about getopt_long: `man 3 getopt_long` 5.5. Functions: - The main building blocks of your program are: opendir, readdir and closedir. - Read through their man pages carefully. - Don't forget to call closedir when you finish with your function. We don't want resources to be leaked. 5.6. Helper functions: - We provide lots of handy helper functions and macros such as: - PRINT_PERM_CHAR: print out the corresponding permission character - uname_for_uid: convert to human-readable user id - group_for_uid: convert to human-readable group id - date_string: convert to formatted date string - ftype_to_string: print out the file type - Please read through them carefully(they can be found at the top of `main.c`). Lots of students try to reinvent their own way of doing this, which is more painful than necessary. 5.7 Using stat(): - The stat() function is a system call in Unix-like operating systems that retrieves information about a file or directory. It provides detailed metadata, such as file size, permissions, timestamps, and more. - Important Fields in struct stat: st_mode: File mode (permissions). st_size: Size of the file in bytes. st_mtime: Time of last modification. st_uid: User ID of the file's owner. st_gid: Group ID of the file's owner. Example: bool is_dir(char* pathandname) { struct stat res; stat(pathandname,&res); return S_ISDIR(res.st_mode); } 5.8. Test output: - Part of the lab is figuring out what it is testing. Don't be intimidated if your test output is really big and strange. - We run diff between your output (./ls) and system output (ls). - diff command: `diff your_output.txt system_output.txt` Example: 1,3c1,2 < Hi, my name is Andrew Hua < I make an error below: < 2 + 2 = 5 --- > Hey, my name is Andrew > 2 + 2 = 4 5,7d3 < a < b < c 8a5,7 > 1 > 2 > 3 - In the example above, 3 diffs are described by lines of the form: - `1,3c1,2`: Lines 1-3 in your output need to change to lines 1-2 in the system's output. Everything above the `---` is your output, and everything after is the system's. - `5,7d3`: denotes lines 5-7 in your output were not in the system's output. - `8a5,7`: means the system's output has added lines 5-7 compared to your output. - Lines removed from your output are prefixed with '<' - Those added to your output are prefixed with '>'. - `2,3c1,3`: Your file, line 2-3 needs to be changed to system output file, line 1-3. - c: change - a: add - d: delete