# Linux ###### tags: `Developer Basics` > My notes on Linux > These notes are compiled from various sources and cover some basic and useful shell programming concepts. Auto-generated Table of Content [ToC] ## SSH ### Overview SSH stands for Secure Shell and provides a safe and secure way of executing commands, making changes, and configuring services remotely. When you connect through SSH, you log in using an account that exists on the remote server. For the duration of your SSH session, any commands that you type into your local terminal are sent through an encrypted SSH tunnel and executed on your server.The SSH connection is implemented using a client-server model. This means that for an SSH connection to be established, the remote machine must be running a piece of software called an SSH daemon. This software listens for connections on a specific network port, authenticates connection requests, and spawns the appropriate environment if the user provides the correct credentials. ### Login Using SSH Keys SSH keys are a matching set of cryptographic keys which can be used for authentication. Each set contains a public and a private key. The public key can be shared freely without concern, while the private key must be vigilantly guarded and never exposed to anyone. To authenticate using SSH keys, a user must have an SSH key pair on their local computer. On the remote server, the public key must be copied to a file within the user’s home directory at ~/.ssh/authorized_keys. This file contains a list of public keys, one-per-line, that are authorized to log into this account. ::: success When a client connects to the host, wishing to use SSH key authentication, it will inform the server of this intent and will tell the server which public key to use. The server then checks its authorized_keys file for the public key, generates a random string, and encrypts it using the public key. This encrypted message can only be decrypted with the associated private key. The server will send this encrypted message to the client to test whether they actually have the associated private key. Upon receipt of this message, the client will decrypt it using the private key and combine the random string that is revealed with a previously negotiated session ID. It then generates an MD5 hash of this value and transmits it back to the server. The server already had the original message and the session ID, so it can compare an MD5 hash generated by those values and determine that the client must have the private key. ::: ### Switching user using sudo #### Sudo - Switching User Do It allows us to run programs with sudo priviledges of another user. If no username is specified then it assumes the root user. - One of the advantages of using sudo over the su command is that you don't need to know the password of the other user. This could eliminate some issues that arise from using shared passwords in generic accounts. When you execute the sudo command, you are prompted for your password. If the sudo configuration permits access, that command is executed. #### Su Command One way to start a session as another user on the system is to use the su command. su [username] If no arguments are supplied, it assumes that you are trying to become the superuser or root account. Executing su without any options is the same thing as su root. Your current environment is passed to the new shell unless you specify a hyphen or dash (-). In that case, su creates an environment like the user logged in directly. ## Running Shell in a Environment ### Shell Variables We don't need to worry about the data types here. ::: success VAR=value ::: There should not be any space between "=" sign for declaring a variable. :::info #!/bin/sh MY_MESSAGE="Hello World" echo $MY_MESSAGE ::: #### Scope of Variables Variables in the Bourne shell do not have to be declared, as they do in languages like C. But if you try to read an undeclared variable, the result is the empty string. You get no warnings or errors. This can cause some subtle bugs. :::success #!/bin/sh echo "MYVAR is: $MYVAR" MYVAR="hi there" echo "MYVAR is: $MYVAR" ::: The output for this script: :::info $ ./myvar2.sh MYVAR is: MYVAR is: hi there ::: There is a command called **export** which has a fundamental effect on the scope of variables. Let's see it with an example, :::success #!/bin/sh echo "MYVAR is: $MYVAR" MYVAR="hi there" echo "MYVAR is: $MYVAR" ::: When you run it generally, the output is: :::info $ ./myvar2.sh MYVAR is: (**Because MYVAR was declared later, it prints an empty output**) MYVAR is: hi there ::: But now let's do one thing, :::info $ MYVAR="Harsh" $ ./myvar2.sh MYVAR is: (**It is empty again, why ?**) MYVAR is: hi there ::: When you call myvar2.sh from your interactive shell, a new shell is spawned to run the script. This is partly because of the #!/bin/sh line at the start of the script. We need to export the variable for it to be inherited by another program - including a shell script. :::info $ export MYVAR $ ./myvar2.sh MYVAR is: hello MYVAR is: hi there ::: Line 3 of the script is changing the value of MYVAR. But there is no way that this will be passed back to your interactive shell. Try reading the value of MYVAR :::success $echo MYVAR hello ::: Once the shell script exits, its environment is destroyed. But MYVAR keeps its value of hello within your interactive shell. In order to receive environment changes back from the script, we must source the script - this effectively runs the script within our own interactive shell, instead of spawning another shell to run it. We can source a script via the "." (dot) command: :::info $ MYVAR=hello $ echo $MYVAR hello $ . ./myvar2.sh MYVAR is: hello MYVAR is: hi there $ echo $MYVAR hi there ::: The change has now made it out into our shell again! This is how your ".profile" or ".bash_profile" file works, for example.We don't need to export MYVAR. :rocket: ## Editing a Bunch of Files (Stream Editor) SED is a text stream editor. Can do insertion, deletion, search and replace(substitution). :::success sed OPTIONS... [SCRIPT] [INPUTFILE...] ::: For example, :::info $ sed 's/unix/linux/' lpicentral.txt ::: **s** stands for substitution, "/" are delimiters. This command will replace linux by unix in the given files. By default, the sed command replaces the first occurrence of the pattern in each line and it won’t replace the second, third…occurrence in the line. To do that, we'll have to add "g" to the command :::info $ sed 's/unix/linux/g' lpicentral.txt ::: There are lot of options like that. ### Adding License information Can't we just do cat license.txt >> $name ? ## SSH and Pipe ### Automate Login Through SSH Usually ssh-keys are best way to automate such process, but just in case you really need to use password. The best is to either use **sshpass** or use **expect** script. An example for such script will be, :::success #!/usr/bin/expect spawn ssh MyUserName@ip expect "password" send "MyPassword\r" interact ::: ## Different Commands ### Diff Diff is a command-line utility that allows you to compare two files line by line. It can also compare the contents of directories :::info diff file1 file2 ::: For comparing two directories :::info diff -r dir1 dir2 ::: **r** stands for recursive flag, which allows us to check for subdirectories as well. ### cmp Used for comparing files byte-by-byte. ### md5 Sums The md5sum is designed to verify data integrity using MD5 (Message Digest Algorithm 5). MD5 is 128-bit cryptographic hash and if used properly it can be used to verify file authenticity and integrity.If two files have the same MD5 checksum value, then there is a high probability that the two files are the same. ### cut command Cut is a command-line utility that allows you to cut parts of lines from specified files or piped data and print the result to standard output. It can be used to cut parts of a line by delimiter, byte position, and character. :::info cut OPTION... [FILE]... -f (--fields=LIST) - Select by specifying a field, a set of fields, or a range of fields. This is the most commonly used option. -b (--bytes=LIST) - Select by specifying a byte, a set of bytes, or a range of bytes. -c (--characters=LIST) - Select by specifying a character, a set of characters, or a range of characters -d (--delimiter) - Specify a delimiter that will be used instead of the default “TAB” delimiter. ::: ## File Permissions There are basically three perimission groups: - Owner - Groups - Other ### Permission Set Each set consists of read, write, and execute permissions.Each file or directory has three permission sets for the three types of permission groups.The first permission set represents the owner permissions, the second set represents the group permissions, and the last set represents the other permissions.The read, write, and execute permissions are represented by the characters r, w, and x, respectively.The presence of any of these characters, such as r, indicates that the particular permission is granted.A dash (–) symbol in place of a character in a permission set indicates that a particular permission is denied.Linux assigns initial permissions automatically when a new file or directory is created. ![](https://i.imgur.com/aBscB85.png) Every file is owned by a specific user (or UID) and a specific group (or GID). The chown command can be used to change just the user, or the user and group of a file. ### Sticky Bit Let' say we create a Linux directory that can be used by all the users of the Linux system for creating files. Users can create, delete or rename files according to their convenience in this directory. For all those who think that why would such a directory be created? There exists, for example, /tmp directory in the Linux system that can be used by different Linux users to create temporary files. Now, what if an user accidentally or deliberately deletes (or rename) a file created by some other user in this directory? Well, to avoid these kind of issues, the concept of sticky bit is used. **A Sticky bit is a permission bit that is set on a file or a directory that lets only the owner of the file/directory or the root user to delete or rename the file. No other user is given privileges to delete the file created by some other user.** ## Soft Links and Hard Links A symbolic or soft link is an actual link to the original file, whereas a hard link is a mirror copy of the original file. If you delete the original file, the soft link has no value, because it points to a non-existent file. But in the case of hard link, it is entirely opposite. Even if you delete the original file, the hard link will still has the data of the original file. Because hard link acts as a mirror copy of the original file. In a nutshell, a soft link - can cross the file system, - allows you to link between directories, - has different inode number and file permissions than original file, - permissions will not be updated, - has only the path of the original file, not the contents. A hard Link - can't cross the file system boundaries (i.e. A hardlink can only work on the same filesystem), [Why?] - can't link directories, - has the same inode number and permissions of original file, - permissions will be updated if we change the permissions of source file, - has the actual contents of original file, so that you still can view the contents, even if the original file moved or removed. ## Stderr, Stdout and StdIn In Bash and other Linux shells, when a program is executed, it uses three standard I/O streams. Each stream is represented by a numeric file descriptor: - 0 - stdin, the standard input stream. - 1 - stdout, the standard output stream. - 2 - stderr, the standard error stream. ### Redirecting Output Streams can be redirected using the n> operator, where n is the file descriptor number.When n is omitted, it defaults to 1, the standard output stream. To redirect the standard error (stderr) use the 2> operator: :::info program 2> file ::: :::success Redirecting stderr to stdout command > file 2>&1 ::: ## Cron Job The Cron daemon is a built-in Linux utility that runs processes on your system at a scheduled time. Cron reads the crontab (cron tables) for predefined commands and scripts. General structure of the command looks like, :::success a b c d e /directory/command output ::: The parts of a cron command are: - The first five fields a b c d e specify the time/date and recurrence of the job. - In the second section, the /directory/command specifies the location and script you want to run. - The final segment output is optional. It defines how the system notifies the user of the job completion. ![](https://i.imgur.com/bC7SWwB.png)