└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Linux Essentials 2 | 3 | Table of contents:
4 | - [Linux Essentials](#linux-essentials) 5 | - [General](#general) 6 | - [Help](#help) 7 | - [Audio/Video](#audiovideo) 8 | - [Working with Files](#working-with-files) 9 | - [Compression](#compression) 10 | - [Search for Information / Information Extraction from Files](#search-for-information--information-extraction-from-files) 11 | - [REGEX](#regex) 12 | - [Pipe](#pipe) 13 | - [Bash](#bash) 14 | - [Main Directories in Linux](#main-directories-in-linux) 15 | - [Processes](#processes) 16 | - [Networking](#networking) 17 | - [How to configure static ip address](#how-to-configure-static-ip-address) 18 | - [Users](#users) 19 | - [Permissions](#permissions) 20 | - [SYMBOLIC LINKS (EQUIVALENT OF SHORTCUTS IN WINDOWS)](#symbolic-links-equivalent-of-shortcuts-in-windows) 21 | - [Sticky Bit](#sticky-bit) 22 | - [AWS](#aws) 23 | - [Anaconda](#anaconda) 24 | - [GPU](#gpu) 25 | - [How to Install CUDA](#how-to-install-cuda) 26 | - [Screen (Do Something while I'm gone)](#screen-do-something-while-im-gone) 27 | - [Server](#server) 28 | - [Docker](#docker) 29 | - [Common Problems](#common-problems) 30 | ## General 31 | [Back to top](#) 32 | | | | 33 | |-|-| 34 | |__command__|__what it does__| 35 | | clear | clear the terminal | 36 | | history | list all of the commands we executed | 37 | | du -hs /path/to/a/directory/ | see the volume of a directory | 38 | | df -h | see the disk space left for all of the disks | 39 | | nvtop | see the status of the NVIDIA GPU | 40 | | htop | see the status of the CPUs and RAM | 41 | | pwd | show the current directory that the commands are being executed in | 42 | | rm -rf ~/.local/share/Trash/* | Empty the trash | 43 | | lsof / \| grep deleted | List the files that should have been deleted, but are not deleted until now! | 44 | | lsof\|grep deleted\|awk '{print $2}'\|xargs kill -9 | Get rid of the deleted files for which a job/process is still open, preventing the file from being deleted | 45 | | pip cache purge | clear the cache for pip | 46 | ## Help 47 | [Back to top](#) 48 | | | | 49 | |-|-| 50 | | ls --help | documentation of the "ls" command | 51 | | man echo | manual of the "echo" command | 52 | | info echo | more information about the "echo" command (Note: More complete than "man" and "help" commands) | 53 | | whatis ls | what is "ls"? (a very short answer to this) | 54 | ## Audio/Video 55 | [Back to top](#) 56 | | | | 57 | |-|-| 58 | | ffmpeg -i whatever.webm -c copy -strict experimental whatever.mp4 | convert webm file to mp4 (Note: "-strict experimental" was added due to the outdated ffmpeg package) | 59 | | ffmpeg -fflags -genpts -i whatever.webm -r 24 whatever.mp4 | convert webm file to mp4 (Another method) | 60 | | ffmpeg -i input.mp3 -acodec pcm_s16le -ac 1 -ar 16000 out.wav | convert 'input.mp3' to a wav file named 'out.wav' (16000 and mono) | 61 | ## Working with Files 62 | [Back to top](#) 63 | | | | 64 | |-|-| 65 | | sudo du -aBm / 2>/dev/null \| sort -nr \| head -n 10 | list the biggest files/directories in terms of volume (top 10) | 66 | | du -hsx * \| sort -rh \| head -10 | list the biggest files/directories in terms of volume (top 10) | 67 | | find . -type f -printf '%s %p\n'\| sort -nr \| head -10 \| numfmt --field=1 --to=iec | list the largest files in terms of volume (top 10) | 68 | |cd /the/path/of/a/folder/ | change directory | 69 | | cd ~ | change directory to the home dir | 70 | | cd / | change directory to the root dir | 71 | | ls | list the files in the current directory | 72 | |ls -a | list the files in the current directory (including the hidden files) (-a means all) - the files having . at the beginning of their names are hidden | 73 | | ls -l | list the files in the directory with more information (including their read/write access, owner, volume, date&time of creation) | 74 | | ls -la | list ALL of the files in the directory with more information (including their read/write access, owner, volume, date&time of creation) | 75 | | ls /path/to/some/directory/ | list the files in a given directory | 76 | | ls mypattern* | list the files in the current directory with names starting with "mypattern" | 77 | | ls *mypattern | list the files in the current directory with names ending with "mypattern" | 78 | |rm -rf /directory/ | remove everything inside a directory ("r" is for recursive deletion, "f" removes read-only files without asking | 79 | | mkdir directory_name | make a new directory (folder) | 80 | | touch test.txt | make a new file named "test.txt" in the current directory | 81 | | nano test.txt | edit the "test.txt" file in terminal | 82 | | cat test.txt | print the content of "test.txt" in the terminal | 83 | | rm test.txt | remove the file "test.txt" | 84 | | rm porteqal.mp4 sound.mp3 linux.png | remove the three files "porteqal.mp4", "sound.mp3", and "linux.png" | 85 | | rmdir /mydirectory/ | remove the directory "mydirectory" (NOTE: works if it's empty) | 86 | | sudo chmod +x myscript.sh | make the script "myscript.sh" executable | 87 | | x=2 | define the variable "x" to be 2 | 88 | | echo $x | print the content of the variable "x" | 89 | | echo "salam" | print the word "salam" | 90 | | echo $a $b | print the content of the variable "a", then a space, and then the content of the variable "b" | 91 | | scp -r speaker* arman@120.233.50.2:~/wavfiles | Copy the folders whose name start with "speaker" from here to the server 120.233.50.2, while logging into that server with the username "arman" | 92 | | scp -r /Users/armanmalekzadeh/Documents/BERT-NEW/ user01@123.22.456.22:~/arman/BERT-Refactor/codes/training/bert-checkpoints/ | Copy the folders and files inside the "BERT-NEW" directory on my own laptop to the "bert-checkpoints" directory on a remote server | 93 | | cp test.txt /path/to/a/directory | copy the file "test.txt" to a directory | 94 | | cp -r * /path/to/a/directory/ | copy everything inside the current directory (including the folders) to another directory | 95 | | cp -r /first/dir/ /second/dir/ | copy the first directory into the second directory | 96 | | cp -a /source/. /dest/ | copy everything from the "source" to the "dest" folder | 97 | | rsync -vau --remove-source-files source/ dst/ | Move all files from the "source/" directory to the "dst/" directory (Note: It's sometimes faster than the "cp"/"mv" command) | 98 | | mv test.txt /path/to/a/directory/ | move the file "test.txt" to another directory | 99 | | mv *.txt /path/to/a/directory/ | move all of the files whose name end with ".txt" to another directory | 100 | | mv a.txt b.txt | rename "a.txt" to "b.txt" | 101 | | whereis ls | show the directory in which the "ls" library exists | 102 | | less a.txt | read the contents of a text file one page(one screen) at a time. | 103 | ## Compression 104 | [Back to top](#) 105 | | | | 106 | |-|-| 107 | | zip media.zip porteqal.mp4 sound.mp3 linux.png | make a zip file containing the tree files "porteqal.mp4", "sound.mp3", and "linux.png". Name the file "media.zip" | 108 | | unzip media.zip | decompress the file "media.zip", and move its contents to the current directory | 109 | | zip linux.zip /path/to/a/directory/ | make a compressed file containing a directory itself (without the files it contains!!!) | 110 | | zip -r tutorial.zip /path/to/a/directory/ | make a compressed file containing a directory and its contents | 111 | | unzip media.zip -d /path/to/a/directory/ | decompress the file "media.zip", and move its contents to a desired directory | 112 | | tar -cf myfile.tar porteqal.mp4 sound.mp3 linux.png | "create" a tar "file" (a compressed file with no volume decreasion), given a list of files | 113 | | tar -xf myfile.tar | decompress (extract) a tar file | 114 | | tar -vxf myfile.tar | decompress (extract) a tar file while printing out the things inside it | 115 | | gzip myfile.tar | compress the given "tar" file (which is not volume-efficient) to a .tar.gz compressed file (more compressed than the tar file) | 116 | | gunzip myfile.tar.gz | decompress the .gz file into the .tar file | 117 | | bzip2 myfile.tar | compress the given "tar" file into a .tar.bz2 compressed file (more compressed than "tar") | 118 | | bunzip2 myfile.tar.bz2 | decompress the .bz2 file into the .tar file | 119 | | tar -cvzf media.tgz sound.mp3 porteqal.mp4 | compress some files directly to a tar gzip file (instead of first compressing as "tar", and then "gzip") - Note: "v" stands for "verbose mode" | 120 | | tar -cvjf media.bz2 sound.mp3 porteqal.mp4 | compress some files directly to a tar bzip file (instead of first compressing as "tar", and then "bzip") | 121 | | tar -xvzf media.tgz | Decompress the .tgz file directly into the original files | 122 | | tar -xvjf media.bz2 | Decompress the .bz2 file directly into the original files | 123 | ## Search for Information / Information Extraction from Files 124 | [Back to top](#) 125 | | | | 126 | |-|-| 127 | | less myfile.txt | displays the content of a file "page by page" with scrolling option | 128 | | head myfile.txt | Displays the first 10 lines of a file | 129 | | tail myfile.txt | Displays the last 10 lines of a file | 130 | | head -n 15 myfile.txt | Displays the first 15 lines of a file | 131 | | tail -n 15 myfile.txt | Displays the last 15 lines of a file | 132 | | sudo find / | Search in the whole files and directories recognized by the OS for files, and list them | 133 | | find Downloads/ -type f | Search for files (not folders) in the "Downloads" folder (and list them!) | 134 | | sudo find / -name "python" | Search for files and directories named "python", and list them | 135 | | sudo find / -name "python*" | Search for files and directories whose name starts with "python" | 136 | | grep arman myfile.txt | Search for the expression "arman" inside the file "myfile.txt", and if it exists, print the token containing it (e.g., print "arman.ir") - Note: If the expression doesn't exist, the output of this command will be empty! | 137 | | grep arman * | Search for the expression "arman" inside all of the files inside the current directory, and show the results (as a list) | 138 | | grep "arman malekzadeh" * | Search for the long expression "arman malekzadeh" inside all of the files inside the current directory, and show the results (as a list) | 139 | | sort myfile.txt | Display the content of the file "myfile.txt" (with lines sorted alphabetically!) - Note: Each line is considered as a separate string | 140 | | sort -n myfile.txt | Display the content of the file "myfile.txt" (with lines sorted based on numbers) - Note: Each line is considered as a separate string | 141 | | sort -r myfile.txt | Display the content of the file "myfile.txt" sorted in the reverse order | 142 | | sort -R myfile.txt | Display the content of the file "myfile.txt" sorted randomly! | 143 | | cut -c3-6 myfile.txt | Display the content of the file "myfile.txt", but only columns 3 to 6 for each line | 144 | | cut -c3,6 myfile.txt | Display the content of the file "myfile.txt", but only the third and sixth character for each line | 145 | | cut -c3- myfile.txt | Display the content of the file "myfile.txt", but only the third character and everything after it, for each line | 146 | | cut -d" " -f4 myfile.txt | Split the contents of a file using the space character, consider each part as a "field", and display the content of the fourth field - Note: this is useful for reading "csv" files | 147 | | cut -d" " -f4- myfile.txt | Split the contents of a file using the space character, consider each part as a "field", and display the content of the fourth field, and every field after it | 148 | | cut -d" " -f4-6 myfile.txt | Split the contents of a file using the space character, consider each part as a "field", and display the content of the fourth field up to the sixth field | 149 | | cut -d" " -f4,6 myfile.txt | Split the contents of a file using the space character, consider each part as a "field", and display the content of the fourth field and the sixth field | 150 | | cut -d" " -f3-6 myfile.txt > output.txt | Split the contents of a file using the space character, consider each part as a "field", and display the content of the third field up to the sixth field. Finally, write the output into the file "output.txt" | 151 | | cut -d" " -f3-6 myfile.txt >> output.txt | Split the contents of a file using the space character, consider each part as a "field", and display the content of the third field up to the sixth field. Finally, append the output to the content of the file "output.txt" | 152 | | wc myfile.txt | Display the number of lines that the file contains, then the number of words (tokens separated by space), and the number of characters | 153 | ## REGEX 154 | [Back to top](#) 155 | | | | 156 | |-|-| 157 | | grep ^arman myfile.txt | Search for the lines starting with "arman" inside "myfile.txt", and show the results (as a list) | 158 | | grep arman$ myfile.txt | Search for the lines ending with "arman" inside "myfile.txt", and show the results (as a list) | 159 | | grep a.m myfile.txt | Search for the lines starting with "a", having "m" as their third character, (don't care about the second character) inside "myfile.txt", and show the results (as a list) | 160 | | grep a..m myfile.txt | Search for the lines starting with "a", having "m" as their fourth character, (don't care about the second and third characters) inside "myfile.txt", and show the results (as a list) | 161 | | grep ^....$ myfile.txt | Search for the lines having only 4 characters inside "myfile.txt", and show the results (as a list) | 162 | ## Pipe 163 | [Back to top](#) 164 | | | | 165 | |-|-| 166 | | command1 \| command2 | run the first command, and take its output to the second command as its input | 167 | | ls \| grep ^D |/ list the files of the current directory, but only show the results starting with the "D" character | 168 | | ls \| grep s$ | list the files of the current directory, but only show the results ending with the "s" character | 169 | | find . type f \| grep python | find the files in the system named "python" | 170 | | cut -d" " -f3 myfile.txt \| cut -c2 |display the second character of the third token from each row | 171 | ## Bash 172 | [Back to top](#) 173 | | | | 174 | |-|-| 175 | | ls sh | get the path to the interpreter of the bash language | 176 | | #!/bin/bash
your bash code goes here | how to write a shell script with bash | 177 | | #! /etc/bash
echo "please write your name"
if [[ "$1" == "arman" ]];
then
    echo "yes"
else
     echo "no"
fi | a demo bash script using the conditional statement "if" | 178 | | sudo chmod 777 myscript.sh | Give the full permission to everyone to do everything with the file "myscript.sh" (including the permission to run it) | 179 | | bash ./myscript.sh | run my shell script named "myscript.sh" | 180 | | bash ./myscript.sh arman | run my shell script named "myscript.sh" taking "arman" as input | 181 | | #! /etc/bash
for i in {1..10}
do
    echo $i
done | print the numbers 1 to 10 | 182 | | #! /etc/bash
for (( i=1 ; i <= 50 ; i++ ))
do
     echo "number : $i$"
done
echo "done" | write the numbers from 1 to 50 with a "number : " string on the left side of them | 183 | ## Main Directories in Linux 184 | [Back to top](#) 185 | | | | 186 | |-|-| 187 | | etc | all of the linux tools are here, including bluetooth, apache, python, and everything you can install on it. So, if you wanna configure sth, here is the place to look for the .conf file | 188 | | bin | contains the code for all of the commands such as "ls" | 189 | | lib | contains the libraries | 190 | | /var/log | the logs in linux are here | 191 | | dmsg | show the logs in a beautiful way (for instance, if you connect a usb, this will show sth) | 192 | ## Processes 193 | [Back to top](#) 194 | | | | 195 | |-|-| 196 | | ps | list the processes that are running | 197 | | ps -aux | show the list of the processes being run by any user, along with the process IDs (PIDs) (Note: aux stands for all user execute) | 198 | | kill 5577 | kill the process with ID 5577 | 199 | | top | show the processes that are being run (live!) | 200 | | free | show the ram (memory), how much of it is used, how much is free, and the same things for the swap (which is used to accelerate the speed of the system) | 201 | | free -tb | show the ram (memory), how much (how many bytes) of it is used, how much is free, and the same things for the swap (which is used to accelerate the speed of the system) | 202 | | free -tm | show the ram (memory), how much (how many megabytes) of it is used, how much is free, and the same things for the swap (which is used to accelerate the speed of the system) | 203 | | `sudo kill -9 $(sudo lsof -t -i :8010)` | kill the process which is using the port `8010` | 204 | | `for port in {8010..8019} {8030..8034}; do pid=$(lsof -ti:$port); [ ! -z "$pid" ] && kill -9 $pid && echo "Killed process $pid on port $port"; done` | kill all processes using ports 8010 to 8019 or 8030 to 8034 | 205 | 206 | ## Networking 207 | [Back to top](#) 208 | | | | 209 | |-|-| 210 | | /etc/resolv.conf | the file containing the configure of the DNS
It may contain sth like this:
`nameserver 127.0.0.25`
`options edns0`
`search localdomain`
To add another DNS (like the DNS server of the google which is 8.8.8.8), append the following line:
nameserver 8.8.8.8 | 211 | | ifconfig | shows some information about the conifiguration of the network (such as the MAC address), the networking cards, ... (Note: "if" stands for "interface") | 212 | | ifconfig -a | show the network cards including the disabled ones | 213 | | sudo ifconfig eth0 192.168.245.120 | change the ip address of the network card "eth0" to 192.168.245.120 | 214 | | sudo ifconfig eth0 down | disable the network card "eth0" | 215 | | sudo ifconfig eth0 up | enable the network card "eth0" | 216 | | dig arman.ir | reveal some information about the website "arman.ir" including the IP addresses it has - Actually, this command sends a request to the nameservers of the website | 217 | | ping 192.168.200.567 | send requests to the given ip address to see if we can have a connection with the device (pc) having that ip address - Note: in the result of this command, you will see "TTL". If the value of "ttl" is more than 100, the pc has a windows installed on it. Otherwise, the OS is linux. - Note2: You are not required to write an ip address. Instead, you can write a domain, such as `ping arman.ir` - Note3: This command is used to see if the connection between two clients or a client and a server has been established | 218 | 219 | ### The best way to configure DNS 220 | 221 | 1. Run `sudo nano /etc/netplan/00-installer-config.yaml` to edit this file. The file contains something like this: 222 | 223 | ``` 224 | nameservers: 225 | addresses: [8.8.8.8] 226 | ``` 227 | Add your preferred DNS in the addresses variable. It will become something like this: 228 | 229 | ``` 230 | nameservers: 231 | addresses: [123.123.123.123, 234.234.234.234] 232 | ``` 233 | 2. Save the file and get back to the terminal. Then run `sudo netplan apply`. 234 | 235 | ### How to configure static ip address 236 | 1. Identify the name of the ethernet interface using `ip link` (or `ip a`, `ip addr`). The output will be something like this: 237 | ``` 238 | 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 239 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 240 | 2: eno1: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 241 | link/ether 0c:c4:7a:cc:59:70 brd ff:ff:ff:ff:ff:ff 242 | 3: eno2: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 243 | link/ether 0c:c4:7a:cc:59:71 brd ff:ff:ff:ff:ff:ff 244 | ``` 245 | Here the name is `eno1`. It can be `ens1`, `eth0` or sth like that in other cases. 246 | 247 | 2. Go to the `/etc/netplan/` directory. There are some files with the `.yaml` postfix. Edit those files and make them like this: 248 | ``` 249 | network: 250 | version: 2 251 | renderer: networkd 252 | ethernets: 253 | eth0: 254 | dhcp4: no 255 | addresses: 256 | - 192.168.121.199/24 257 | gateway4: 192.168.121.1 258 | nameservers: 259 | addresses: [8.8.8.8, 1.1.1.1] 260 | ``` 261 | In the above lines, `eth0` is the name of your interface, `192.168.121.199/24‍‍‍` is the static ip address. If you want multiple addresses, type another line for the other address. 262 | 263 | 3. Test the connection to the network (if you want to) using `sudo netplan try`. 264 | 265 | 4. Apply the new network plan by running `sudo netplan apply`. 266 | 267 | 5. Verify the changes by running `ip addr show dev eno1`. Remember that `eno1` was the name of our interface. The output will be something like this: 268 | ``` 269 | 3: eno1: mtu 1500 qdisc mq state UP group default qlen 1000 270 | link/ether 56:00:00:60:20:0a brd ff:ff:ff:ff:ff:ff 271 | inet 192.168.121.199/24 brd 192.168.121.255 scope global dynamic eno1 272 | valid_lft 3575sec preferred_lft 3575sec 273 | inet6 fe80::5054:ff:feb0:f500/64 scope link 274 | valid_lft forever preferred_lft forever 275 | ``` 276 | 277 | --- 278 | 279 | Note: For older Ubuntu versions (e.g., 16), there might be no `/etc/netplan/` directory. In this case, check for the `/etc/network/interfaces` file. It should look like this: 280 | ``` 281 | # interfaces(5) file used by ifup(8) and ifdown(8) 282 | auto eno1 283 | iface eno1 inet static 284 | address 213.220.120.2 (ip address of the server) 285 | netmask 255.255.255.0 (always the same) 286 | gateway 213.220.180.1 (ask this from the server admin) 287 | dns-nameservers 4.4.4.4 8.8.8.8 (always the same) 288 | ``` 289 | 290 | After doing this, restart the network service by running `sudo /etc/init.d/networking restart`. 291 | ## Users 292 | [Back to top](#) 293 | | | | 294 | |-|-| 295 | | who | shows the current user, with a little bit of extra info | 296 | | w | shows which users are logged in, the time of their login, and what they are doing | 297 | | whoami | shows the current user's name | 298 | | id | shows the unique id of the current user, the groups he/she belongs to - Note: From 0 to 499, is for system users, and 500 to 6000 is for standard users | 299 | | id anotheruser | shows the unique id of the given user named "anotheruser", the groups he/she belongs to | 300 | | cat /etc/passwd | the file `/etc/passwd` contains information about all of the users, including the uid of them and the id the group they belong to, and the home directory (a.k.a profile) (for the standard users) | 301 | | cat /etc/group | the file `/etc/group` contains information about all of the groups, including the id of each group and the users belonging to each group | 302 | | sudo cat /etc/shadow | the file `/etc/shadow` contains the hashed passwords for all users | 303 | | sudo command | execute the command using the permission level of the `root` user | 304 | | su arman | change the user to `arman` in order to execute commands on his/her behalf (this will ask for the password of the user `arman`) | 305 | | sudo su - arman | change the user to `arman` in order to execute commands on his/her behalf (without asking for their permission). This only works if you are a sudoer. | 306 | | sudo adduser arman | create a new user named `arman` - Note: this will ask for a password for the new user, and some other info (such as phone number!) | 307 | | sudo addgroup mynewgroup | create a new group named `mynewgroup` | 308 | | sudo passwd | change the password of the current user | 309 | | sudo passwd arman | change the password of the user named `arman` | 310 | | last | shows the last logins in the system | 311 | | sudo usermod -a -G mygroup arman| Add the user `arman` to the group `mygroup` ("a" stands for "add", "G" for "group") | 312 | | sudo usermod -a -G root arman | Add the user `arman` to the `root` group | 313 | | sudo userdel arman | delete the user `arman`, but keep his/her profile - Note: the path `/home/arman/` will remain. | 314 | | sudo userdel -r arman | delete the user `arman` and his/her profile (files) | 315 | | sudo groupdel mygroup | delete a group named `mygroup` | 316 | | sudo adduser arman sudo | add user `arman` to the sudo group | 317 | | usermod -aG sudo arman | add user `arman` to the sudo group | 318 | | sudo deluser arman sudo | revoke sudo access from `arman` | 319 | | `grep -Po '^sudo.+:\K.*$' /etc/group` | get the list of sudoers | 320 | 321 | ### Passwordless Login using SSH Keys 322 | 323 | Everytime you try logging into your server? Are you tired of it? If yes, do the following steps: 324 | 325 | 1. Run `ssh-keygen -t rsa -b 4096 -C "your_email@gmail.com"` in the terminal. This will create a ssh key-pair. You will be prompted with something like this: 326 | ``` 327 | Generating public/private rsa key pair. 328 | Enter file in which to save the key (/Users/armanmalekzadeh/.ssh/id_rsa): 329 | ``` 330 | Consider a new path for the key. For instance, type `/Users/armanmalekzadeh/.ssh/id_rsa_new` and hit enter. You will be asked for a passphrase. Choose something appropriate if you want. Finally, you will be shown something like this: 331 | ``` 332 | Your identification has been saved in /Users/armanmalekzadeh/.ssh/id_rsa_new 333 | Your public key has been saved in /Users/armanmalekzadeh/.ssh/id_rsa_new.pub 334 | The key fingerprint is: 335 | SHA256:blahblahblah your_email@gmail.com 336 | The key's randomart image is: 337 | +---[RSA 4096]----+ 338 | | blah blah blah | 339 | +----[SHA256]-----+ 340 | ``` 341 | 342 | 2. Run `ssh-copy-id -i .ssh/id_rsa_test.pub your_user_name@your_server` in the terminal. This will make a copy of the public key on your remote server. If for any reason this command doesn't work, you'll have to copy the content of the `.pub` file manually into a new line inside the file `~/.ssh/authorized_keys` on your remote server. 343 | 3. Run `nano ~/.ssh/config` to edit `~/.ssh/config`. Add something like this at the end of the file: 344 | ``` 345 | Host 123.123.123.123 (replace with your_servers_ip) 346 | HostName 123.123.123.123 (replace with your_servers_ip) 347 | User your_user_name 348 | IdentityFile ~/.ssh/id_rsa_new 349 | ``` 350 | 351 | ## Permissions 352 | [Back to top](#) 353 | | | | 354 | |-|-| 355 | | ls -l | The first character: "d" means directory, and "-" means file
The three characters after that: "r" = read, "w" = write, "x" = execute. If instead of any of them, a "-" is written, means that we cannot "read", "write" or "execute" that file.
The first three characters correspond to the permissions of the owner of the file
The second three characters correspond to the group members of the owner
The last three characters correspond to other users (any kind of user)
The "execute" permission for directories means changing directory to those dirs (using the `cd` command) | 356 | | About the numbers of the characters mentioned above | "r" (read) = 4, "w" (write) = 2, "x" (execute) = 1 - Note that the sum of them is 7.
So, 777 means that anyone can do anything with that file/directory | 357 | | sudo chmod u | give the permission of ... to the user named `` | 358 | | sudo chmod o | give the permission of ... to the other users named `` | 359 | | sudo chmod g+w myfile.txt | give the permission to write ("w") to the file "myfile.txt" to the group members of the owner of the file | 360 | | sudo chmod uog+w myfile.txt | give the permission to write ("w") to the file "myfile.txt" to everyone | 361 | | sudo chmod g+rw myfile.txt | give the permission to read and write ("rw") to the file "myfile.txt" to the group members of the owner of the file | 362 | | sudo chmod g+rxw myfile.txt | give the permission to read, execute and write ("rxw") to the file "myfile.txt" to the group members of the owner of the file | 363 | | sudo chmod g+rxw myfile.txt | give the permission to read, execute and write ("rxw") to the file "myfile.txt" to the group members of the owner of the file | 364 | | sudo chmod gou-wx myfile.txt | take away the permissions to write to and execute the file "myfile.txt" from every user | 365 | | sudo chmod ug+w myfile.txt | give the permission to write to the file "myfile.txt" to the owner and the group it belongs to | 366 | | sudo chmod 700 myfile.txt | give the permission to do anything to the owner of the file "myfile.txt", and do nothing to others | 367 | | sudo chmod +x myfile.txt | give the permission to write to the file "myfile.txt" to everyone! | 368 | | sudo chown arman myfile.txt | change the owner of the file "myfile.txt" to the user "arman" | 369 | | sudo chgrp mygroup myfile.txt | change the group of the file "myfile.txt" to the group "mygroup" | 370 | | sudo chown arman myfolder -R | change the owner of the directory named "myfolder" to the user "arman", along with all of its subfolders and files inside it | 371 | | sudo chmod -R 777 /path/to/your/directory | give every user the permission to do everything with the `/path/to/your/directory` and all its contents (including files and folders) | 372 | ## SYMBOLIC LINKS (EQUIVALENT OF SHORTCUTS IN WINDOWS) 373 | [Back to top](#) 374 | | | | 375 | |-|-| 376 | | ln -s /path/to/the/original/file.txt myshortcut.txt | create a shortcut of the file which is located at `/path/to/the/original/file.txt` in the current directory, and name it as `myshortcut.txt` | 377 | ## Sticky Bit 378 | [Back to top](#) 379 | | | | 380 | |-|-| 381 | | sudo chmod o+t myfolder/ | every user can only change the files that he/she owns | 382 | | sudo chmod 777 myfolder | remove the sticky bit mode | 383 | ## AWS 384 | [Back to top](#) 385 | | | | 386 | |-|-| 387 | | aws s3 cp /path/to/a/file.txt s3://[bucket-name]/path/to/file.txt --endpoint-url https://[bucket-name].parspack.net | copy a file to a bucket | 388 | | aws s3 cp /path/to/a/folder s3://[bucket-name]/ --recursive --endpoint-url https://[bucket-name].parspack.net | copy a folder to a bucket | 389 | | aws s3 ls s3://[bucket-name]/path/to/a/folder/ -endpoint-url https://[bucket-name].parspack.net | list the contents of a folder | 390 | ## Anaconda 391 | [Back to top](#) 392 | | | | 393 | |-|-| 394 | | source ~/anaconda3/bin/activate | activate the Anaconda's environment | 395 | | conda create --name your_desired_name python=3.8 | make a new environment which uses a specific Python version | 396 | | conda env list | list all environments built inside anaconda | 397 | | conda env remove --name ENVIRONMENT_NAME | remove the conda environment named "ENVIRONMENT_NAME" | 398 | | jupyter notebook --no-browser --port=8080 | Run a jupyter notebook on the server without using the browser on the port 8080 | 399 | | jupyter notebook password | Define a new password for the jupyter notebook (instead of the token, you will give this password to anyone who will use the jupyter) | 400 | | jupyter notebook --no-browser --port=8080 --notebook-dir=/home/user01/ | Run a jupyter notebook on the server (at path `/home/user01/` without using the browser on the port 8080 | 401 | | jupyter server list | Get the list of all jupyter servers (the log also contains the token for each notebook) | 402 | | tensorboard --logdir /path/to/save/the/logs --port 8895 | Run Tensorboard on port 8895 and save its logs to the specified directory (logdir) | 403 | | ssh -L 8080:localhost:8888 @ | Use a jupyter which is running on port `8888` (on a remote server) on your local port `8080` (by connecting to the `@` using SSH) - This is called "port forwarding" | 404 | 405 | ### To install Anaconda for all linux users, do the following steps: 406 | 407 | 1. Download Anaconda .sh installation file from its website. 408 | 2. Run `sudo -i` to be the root user. 409 | 3. Run `sudo apt-get update` 410 | 4. Execute `bash Anaconda[...].sh` to run the installation file. 411 | 5. Accept the license (type yes) 412 | 6. For the install location, choose `/opt/anaconda3` 413 | 7. It asks "Do you wish the installer to initialize blah blah blah"? Say "yes". (The installation is finished). 414 | 8. Run `exit` to again be a normal user. 415 | 9. Now your user does not recognize conda (For instance if you type `conda -V`, it will say `command not found`). 416 | 10. Run `sudo nano /etc/environment`. 417 | 11. At the beginning of the `PATH` variable, after the `"` character, add `/opt/anaconda3/bin:`, and save the file using `CTRL+O`. 418 | 12. Log out from your own user and do the SSH again. Now if you run `conda -V`, the user will recognize it. 419 | 420 | ### Add Users to JupyterHub 421 | 1. First, locate the file named `jupyterhub_config.py` using this command: 422 | ``` 423 | ps aux | grep jupyterhub 424 | ``` 425 | The result will contain something like this: 426 | ``` 427 | root 1215751 0.4 0.0 262044 98504 ? Ssl 10:30 0:01 /opt/py-venvs/py3.11/bin/python3 /opt/py-venvs/py3.11/bin/jupyterhub -f /opt/py-venvs/py3.11/etc/jupyterhub/jupyterhub_config.py 428 | ``` 429 | Obviously, the path to `jupyterhub_config.py` is there. 430 | 2. Inside that `jupyterhub.config.py` file, there is a line similar to the following: 431 | ``` 432 | c.Authenticator.allowed_users = {'arman', 'another_user', 'blah_blah_user'} 433 | ``` 434 | Note that the file is very long. So, be patient (or search inside it). Add the desired user to the `allowed_users` variable. 435 | 3. Finally, you should restart JupyterHub using this command: 436 | ``` 437 | sudo systemctl restart jupyterhub 438 | ``` 439 | 440 | ## GPU 441 | [Back to top](#) 442 | | | | 443 | |-|-| 444 | | Installing CUDA 11.2 and cuDNN 8.1 | [Unofficial Link](https://medium.com/analytics-vidhya/install-cuda-11-2-cudnn-8-1-0-and-python-3-9-on-rtx3090-for-deep-learning-fcf96c95f7a1) - [NVIDIA Link for cuDNN Installation](https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html) - [How to verify cuDNN Installation](https://stackoverflow.com/questions/31326015/how-to-verify-cudnn-installation/36978616) | 445 | | lsmod \| grep nvidia | Check the GPU Model | 446 | | pgrep nvidia-smi | Get all `nvidia-smi` processes by ID | 447 | | sudo /usr/local/cuda-11.4/bin/cuda-uninstaller | Uninstall CUDA using its own uninstallation script | 448 | | sudo /usr/bin/nvidia-uninstall | Uninstall NVIDIA using its own uninstallation script | 449 | | ubuntu-drivers devices | Get the available NVIDIA drivers along with recommendations | 450 | 451 | ### How to Install CUDA 452 | - `sudo apt-get update` 453 | - `sudo apt-get install -y build-essential cmake unzip pkg-config` 454 | - `sudo apt-get install -y libxmu-dev libxi-dev libglu1-mesa libglu1-mesa-dev` 455 | - `sudo apt-get install -y libjpeg-dev libpng-dev libtiff-dev` 456 | - `sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev libv4l-dev` 457 | - `sudo apt-get install -y libxvidcore-dev libx264-dev` 458 | - `sudo apt-get install -y libgtk-3-dev` 459 | - `sudo apt-get install -y libopenblas-dev libatlas-base-dev liblapack-dev gfortran` 460 | - `sudo apt-get install -y libhdf5-serial-dev graphviz` 461 | - `sudo apt-get install -y python3-dev python3-tk python-imaging-tk` 462 | - `sudo apt-get install -y linux-image-generic linux-image-extra-virtual` 463 | - `sudo apt-get install -y linux-source linux-headers-generic` 464 | - `sudo apt-get purge nvidia*` (remove any nvidia drivers already installed) 465 | - `sudo add-apt-repository ppa:graphics-drivers/ppa` (add graphic drivers ppa) 466 | - `sudo apt-get update` 467 | - `ubuntu-drivers devices` (search for available drivers). The output will be something like this: 468 | ``` 469 | == /sys/devices/pci0000:00/0000:00:03.0/0000:03:00.0 == 470 | 471 | vendor   : NVIDIA Corporation 472 | 473 | model    : GM200 [GeForce GTX TITAN X] 474 | 475 | modalias : pci:v000010DEd000017C2sv000010DEsd00001132bc03sc00i00 476 | 477 | driver   : nvidia-415 - third-party free 478 | 479 | driver   : nvidia-430 - third-party free recommended 480 | 481 | driver   : nvidia-418 - third-party free 482 | 483 | driver   : nvidia-410 - third-party free 484 | 485 | driver   : nvidia-384 - distro non-free 486 | 487 | driver   : xserver-xorg-video-nouveau - distro free builtin 488 | ``` 489 | - `sudo apt-get install nvidia-driver-430` (install the driver with the best version). The result was `unable to locate package`. Run `sudo apt-get install nvidia-430` instead, and it will work! 490 | - `sudo reboot` (before the reboot, `nvidia-smi` won't work. It will say something other than `command not found` which means a driver is there, but it will not work) 491 | - To install tensorflow for a conda env: First activate it, and then run `conda install -c anaconda tensorflow-gpu` (install `tensorflow-gpu`) (while installing this, cuda-toolkit and cudnn will also be installed) 492 | - `apt install nvidia-cuda-toolkit` (run as root and the base conda env) 493 | - Run `nvcc -V` to get the version of the cuDNN! (Now it should work!) 494 | 495 | ### What if `nvidia-smi` hangs with no output? 496 | 497 | Uninstall both NVIDIA and CUDA using the built-in uninstallation scripts and install another driver. 498 | 499 | ## Screen (Do Something while I'm gone) 500 | [Back to top](#) 501 | 502 | | Command | Description | 503 | |-|-| 504 | | `screen -S arman` | Start a screen with name `arman`. You can detach from the screen (get out of it) by using `ctrl+a` and then pressing `d` | 505 | | `screen -r arman` | Resume a screen named `arman` | 506 | | `screen killall` | Kill all screens | 507 | | `screen -ls` | List all running screens | 508 | | `screen -r -d 29284` | Resume a screen with ID 29284 | 509 | | `screen -dmS diary bash -c 'source virtualenv/diary/3.11/bin/activate; cd diary; python main.py'` | Start a screen named `diary` in detached mode and run 3 commands inside it | 510 | 511 | ## Server 512 | [Back to top](#) 513 | | | | 514 | |-|-| 515 | | apt install ubuntu-desktop | install a desktop on an Ubuntu server | 516 | 517 | ## Docker 518 | [Back to top](#) 519 | | | | 520 | |-|-| 521 | | docker ps | List all running containers with their ID and name | 522 | | docker ps -a | List all containers with their ID and name | 523 | | docker stop | Stop a container with a given ID | 524 | | docker rm | Remove a container with a given ID | 525 | | `docker run --rm -it arman/web:v2 pip list` | create and run a temporary container from the arman/web:v2 image, run pip list inside it, then remove the container after execution | 526 | | docker attach | Attach to a running container | 527 | | `CTRL+P` followed by `CTRL+Q` | Detach from a running container | 528 | | `docker run -d :` | Run a Container in Detached Mode | 529 | | `docker run --gpus all -it -v ~/path/to/host_folder:/out_path -p 8002:8889 --entrypoint /bin/bash lorenzopapa5/cuda11.6-python3-pytorch1.12.0:latest` | Run a docker named `cuda11.6-python3-pytorch1.12.0:latest` uploaded by a user called `lorenzopapa5` (available on Dockerhub) while giving it access to all gpus available on the host machine. This command also makes a folder called `out_path` in the docker files and maps it to the real path `/path/to/host_folder` on the host machine. Moreover, it maps the docker port `8889` to the real port `8002` on the host machine. | 530 | | docker stop | Stop a Running Container | 531 | | docker start | Start a Stopped Container | 532 | | docker exec -it | Execute a Command in a Running Container | 533 | | docker logs | View Container Logs | 534 | | docker system df | Get a summary of all Docker disk usage | 535 | | docker system df --verbose | Get a detailed report on all Docker disk usage | 536 | 537 | ### How to install the docker on Ubuntu Linux 538 | 1. Run `sudo apt update`. 539 | 2. Install the docker using `sudo apt install -y docker.io`. 540 | 3. Start the docker: `sudo systemctl start docker`. 541 | 4. Enable the docker: `sudo systemctl enable docker`. 542 | 5. Verify Installation: `docker --version`. 543 | 544 | ### How to get a docker image from docker hub and use it 545 | 1. Download the image from docker hub: `docker pull /:`. 546 | 2. To run the image interactively and get access to the bash shell, use the `-it` flags: `docker run -it /: /bin/bash`. 547 | 3. When the container starts, you’ll be dropped into its bash shell. You can now run any commands interactively inside the container. 548 | 4. When you're done, type `exit` to leave the container. This will also stop the container unless you run it with `--rm` to remove it automatically. 549 | 550 | ### How to push your own docker container to docker hub 551 | 1. Run `docker ps` to get its ID 552 | 2. Use the `docker commit` command to create a new image. Replace with the ID or name of your running container and with the desired name for your new image. Run `docker commit :` (Choose an image name and a tag, .e.g, `docker commit 00784f83a867 torch112cu116:latest`) 553 | 3. Run `docker images` to make sure the image has been created. 554 | 4. (Optional) Save the Image: If you want to back up or transfer the image to another system, you can save it as a tar file by running `docker save -o .tar :` (e.g., `docker save -o my_new_image.tar my_new_image:latest`). Then, you can load it using `docker load -i .tar`. 555 | 5. Run `docker login` to log into the docker hub. 556 | 6. Docker Hub requires images to be tagged with your Docker Hub username and repository name. To do this, run `docker tag : /:` (e.g., `docker tag torch112cu116:latest armanmalekzadeh/gpulinux:latest`). 557 | 7. Push the tagged image to Docker Hub by running `docker push armanmalekzadeh/gpulinux:latest`. 558 | 559 | ### How to change the registry mirrors if your network can't reach Dockerhub directly 560 | 1. Run `sudo nano /etc/docker/daemon.json` 561 | 2. Assuming your mirror has the address `https://yourmirrorfordocker.com`, add the following lines to the file: 562 | ``` 563 | { 564 | "registry-mirrors": ["https://yourmirrorfordocker.com"] 565 | } 566 | ``` 567 | 3. Run `sudo systemctl daemon-reload` 568 | 4. Run `sudo systemctl restart docker` 569 | 570 | ## Common Problems 571 | [Back to top](#) 572 | 573 | ### `sudo apt-get update` fails 574 | 575 | This is usually due to a corrupted `sources.list.d` file. 576 | 577 | ``` 578 | sudo mv /etc/apt/sources.list{,.bk} 579 | sudo mkdir /etc/apt/sources.list.d 580 | sudo cp /usr/share/doc/apt/examples/sources.list /etc/apt/sources.list 581 | sudo apt-get update 582 | ``` 583 | --------------------------------------------------------------------------------