+++ title = "Intro to Linux and the Bash command line, pt II" date = 2018-12-31T09:20:00Z +++ So the year is coming to an end, and I didn't follow up on the first part of these mini tutorial/guide/introduction. Might as well end the year on a good note and write at least one post this last month. In this part I will be writing about some more aspects of Linux and Unix-like systems and tools that will come in handy when using the terminal. All or most of these tools are a standard part of Linux and Unix/Unix-like systems. ## File manipulation I didn't get into detail in the previous part of this guide on the file manipulation side of things. However it is a crucial part of any computer system, after all they wouldn't be as useful as they are if you couldn't create, edit and delete files. ### Create files Usually, the way you would go about creating and editing files is by using the corresponding programs. Like for example, vim to create and edit text files. However, there's also a utility to create blank files called touch. You can make a blank file by writing touch followed by the path of the file you wish to create, like this ```sh user@host:~$ touch example.txt ``` Now we have an empty file at "/home/user/example.txt". Although I kind of lied when I said that this command is for making blank files. In reality, what it does is check if such file exists, if it does, it modifies the date and time of access and modification, otherwise it makes a new empty file, like in our case. Most of the time you won't really need this command, since you would actually be creating files through programs or means, though it does come in handy sometimes. ### Create directories Now on to something more interesting, making directories. This one is quite simple, and the command for that is mkdir. For example ```sh user@host:~$ mkdir foo ``` In this case we have created a new folder called "foo" in "/home/user/". But remember that we are passing paths here, which can be relative or absolute (if you don't know or remember what this means, check the first part of this guide). In our case we were using a relative path, with just the name of the directory to create. If we were to indicate an absolute path like "/home/user/foo" we would need to make sure that directories "home" and "user" already exist. However, there's a useful argument we can pass to mkdir to make parent directories if needed, -p ```sh user@host:~$ mkdir -p /tmp/foo/bar ``` In this case, if directory "foo" doesn't exist, mkdir will make it for us along with "bar" inside it. ### Moving and renaming This one is pretty simple, and both actions are handled by the same command, mv, which is short for move. If you want to rename a file or directory, simply "move" it to the same destination directory with a new/different name, for example ```sh user@host:~$ mv untitled titled ``` If you want to move it to a different location, just indicate that path as the second argument. Remember that we are using paths here, and we use either absolute or relative paths ```sh user@host:~$ mv titled Documents/titled ``` ### Copying Copying files is similar to moving them, except that the command is different, cp ```sh user@host:~$ cp titled Documents/titled2 ``` However, copying directories is different. To copy directories you have to use a special flag, the -r flag. This flag means that the operation ought to be recursive, that is to copy every file and subdirectory in that directory along with the directory (and files in those subdirectories and files the subdirectories of the subdirectories and... yeah recursion, you get it) to the destination path. So we would do something like this ```sh user@host:~$ cp -r dir dir-copy ``` ### Removing Removing files is pretty simple, just use rm followed by the path of the file, for example ```sh user@host:~$ rm title ``` However, removing directories is a little bit trickier. One option would be to use the command rmdir, however, the directory has to be empty before you can remove it. The second option, is to use the same command as we used with files, but passing it the -r flag so that it removes files recursively, similar to what we did with the copy (cp) command. Do watch out, as it will remove the directory along with everything that is in it. So to remove a directory and everything in it, we input something like this ```sh user@host:~$ rm -r dir ``` This command also has another flag to forcefully remove files without prompting, the -f flag. This might be useful when you are removing files recursively and there might be some special files, like hidden files (the ones with a dot as the first character) and you don't want to be prompted for each and everyone of them. Thread REALLY carefully when using this command though, especially if you are issuing it as root. You don't wanna issue a "sudo rm -rf /" and end up with a borked system and lost files. Unless you are some kind of sadist or something. An example of when it might be useful, is when you need to delete a git repository from your computer, since it contains a lot of special hidden files which git uses to keep track of your commits and other stuff. So to remove it, we do ```sh user@host:~$ rm -rf somerepo ``` ### Permissions The Unix or Unix-like user and permissions systems, is a robust system for managing what particular users can do with certain files and directories. This allows to create a secure environment, especially when there are multiple users using one computer. Every file has three types of permissions which dictate what can be done with it. Each permission is represented by a single letter * r - read: the user can read/view the file. * w - write: the user can write/modify (this includes deleting) the file. * x - execute: the file can be run or executed by the user, if it is a program or script. There are as well three different sets of people the permissions and ownership might apply to. These are * u - user/owner: the one user that owns the file. Usually it is the user that created the file, but ownership can be modified. * g - group: every file has a group it belongs to. The group can be a one user group (every user has their own one-user group), or a common group with multiple users. * o - others: everybody else who is not either in the group or the owner. If you read the first part of this guide you might remember that I mentioned using the command "ls -l" to list the contents of the directory with details about the files, including permissions ```sh user@host:~/Documents$ ls -l drwxr-xr-x 2 user user 4.0K Jul 18 04:20 Books -rwxr-xr-- 1 user group 350 Jul 18 04:20 run.py -rw-r--r-- 1 user user 1.2M Jul 18 04:20 picture.png ``` As mentioned in the first part, the first ten characters of a row of the output is what tells us about the permissions of the given file in that row. The first character in that sequence tells us if it is a normal file, or a directory. If it has a d, it is a directory (duh), if it has a dash, it is a normal file. It can be another letter, like an l for a symbolic link (a topic for another day). The next 9 characters are divided in subsequences of three letters, each for a set of people. The first three characters after the file type one are the permissions for the owner, the next three are for the group, and the last three for others. In each of this subset of three characters, the permissions are in the order of read, write, and execute. So a letter means that that said set of users have said permission, and its absence means the lack of that permission. Let's take for example the "run.py" file. By the information there we can see that it is a normal file (no d (that's what she said)), its owner (user) can read, write and even execute it; the group users (in group group) can read and execute it, but not write to it; and the others can just take a look at its contents. You might have noticed that directories tend to have the "x" part of the permissions, however, this means something a little bit different on directories than on files. It doesn't mean that you can execute but rather that you can "search it", or in other words, access files inside of it. Because having the "read" permission on a directory only means that you can take a look at what files are inside of it, and write that you can put files inside the directory. ### Changing permissions There is a really useful command that allows us to change permissions on files, chmod. It is short for change file mode bits. To change the permissions on the file you input chmod followed by the permissions and the path of the file. There are two ways of setting the permissions, the easy and long one using letters, and the short but not as easy way with octal "permission bits". We'll take a look at the easy one first. The easier way is made up of three parts * Who - user/owner, group, others or all (u, g, o, or a) * Revoke or grant, "+" to grant, "-" to revoke * The permission we are setting - read, write or execute (r, w, or x) So let's suppose we have a script we want to set the execute permission for so that any user in the computer can execute it. ```shh user@host:~/Documents/stuff$ ls -l -rw-r--r-- 1 user group 420 April 20 6:59 script.sh user@host:~/Documents/stuff$ chmod a+x script.sh -rwxr-xr-x 1 user group 420 April 20 6:59 script.sh ``` As we can see, after executing the command, every user on the computer now has execute permission on the script. Now let's say that we want to revoke read permissions for everybody except for the owner (user), we could execute o-r and then g-r, but we can also combine them, like so ```sh user@host:~/Documents/stuff$ chmod go-r script.sh -rwx--x--x 1 user group 420 April 20 6:59 script.sh ``` Now onto the short way. This one's a bit harder to remember as you have to have some understanding of binary. Basically the way it works is that you set the permissions by passing three octal numbers (i.e., 0-7) that each represent the permission bits for each set of people (user/owner, group, others). As it is we have three possible permissions (read, write and execute) and 2^3 just so happens to be 8 (possible combinations), that's why it is in octal. Here's a table to help you out
Octal | Binary |
0 | 001 |
1 | 001 |
2 | 010 |
3 | 011 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |