> For the complete documentation index, see [llms.txt](https://sbdevs-organization.gitbook.io/sbdev-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sbdevs-organization.gitbook.io/sbdev-docs/docs/docs-bash.md).

# Bash

GitBook docs section concerning Bash context.

<br>

## Boot Script Linux

#### Using init.d

In the script you put in `/etc/init.d` you have to set it executable and create a symlink to `/etc/rc.d/`:

```bash
chmod +x /etc/init.d/my-script.sh


ln -s /etc/init.d/my-script.sh /etc/rc.d/
```

> Please note that this wil not work as the script have to be LSB compliant (provide, at least, the following actions: start, stop restart, force-reload and status).

<br>

#### Using systemd

File: `/etc/systemd/system/my-startup.service`

```vim
[Unit]
Description=My Startup

[Service]
ExecStart=/usr/local/sbin/my-script.sh

[Install]
WantedBy=multiuser.target
```

```
    linuxspot@linuxspot:~$ sudo nano /etc/systemd/system/my-startup.service
    linuxspot@linuxspot:~$ systemctl status my-startup.service
    ○ my-startup.service - My Startup
        Loaded: loaded (/etc/systemd/system/my-startup.service; disabled; vendor preset: enabled)
        Active: inactive (dead)

    Feb 06 19:35:08 linuxspot systemd[1]: Started My Startup.
    linuxspot@linuxspot:~$ sudo systemctl enable my-startup.service
    Created symlink /etc/systemd/system/multi-user.target.wants/my-startup.service ⇨ /etc/systemd/system/my-startup.service
```

<br>

## Public IP

#### Using dig command (Unix only)

1. Open the Terminal application.
2. Type the following dig (domain information groper) command on a Linux, OS X, or Unix-like operating systems to see public IP address assigned by the ISP:

   ```bash
   dig +short myip.opendns.com @resolver1.opendns.com
   ```

   Or:

   ```bash
   dig TXT +short o-o.myaddr.l.google.com @ns1.google.com
   ```
3. You should see your IP address on screen. This is the fastest way to find out your IP address without using 3rd party site.

<br>

#### Using 3rd party web-sites

1. Open the Terminal application.
2. Type the following curl command to see public IP address assigned by the ISP:

   ```bash
   curl checkip.amazonaws.com
   ```

   Or:

   ```bash
   curl ifconfig.me
   ```
3. You should see your IP address on screen.

<br>

## Static IP Linux

#### Using NETPLAN

Here’s the replacement for editing `/etc/networking/*` in the old system. The whole system now uses YAML configuration files under `/etc/netplan`, and then the [netplan](https://netplan.io/) command applies those configurations to the system.

```bash
vi /etc/netplan/*.yaml
```

```vim
network:
    version: 2
    ethernets:
        eth0:
            dhcp4: true
            optional: true
            # addresses: [192.168.1.101/24]
            # gateway4: 192.168.1.1
            # nameservers:
            #   addresses: [8.8.8.8, 1.1.1.1]
    wifis:
        wlan0:
            dhcp4: false
            dhcp6: false
            addresses: [192.168.1.101/24]
            gateway4: 192.168.1.1
            nameservers:
                addresses: [8.8.8.8, 1.1.1.1]
            access-points:
                "This is Access Point SSID":
                    password: "secret"
```

```bash
netplan apply
```

So now (whether you’re running an older system or a new one) you should now have a static IP address!

<br>

#### Using Network Interfaces

Assign Static IP Address to `eth0` interface editing configuration file `/etc/network/interfaces` to make permanent changes as shown below:

```vim
auto eth0
iface eth0 inet static
address 192.168.1.101
netmask 255.255.255.0
gateway 192.168.1.1
```

Next, restart network services after entering all the details using the following command:

```bash
systemctl restart NetworkManager.service

# Or

/etc/init.d/networking restart
```

<br>

#### Using dhcpcd.conf file

Open `/etc/dhcpcd.conf` with your favorite text editor. scroll down until you see the following commented out lines of code:

```vim
# Example static IP configuration:
#interface eth0
#static ip_address=192.168.11.13
#static routers=192.168.11.1
#static domain_name_servers=8.8.8.8
```

Uncomment the lines above or copy the following snippet and put it right under the code shown above:

```vim
interface wlan0
static ip_address=192.168.11.13
static routers=192.168.11.1
static domain_name_servers=8.8.8.8
```

You will need to set up the static ip\_address and static routers tag to fit your network setup. Don’t forget to save the file.

<br>

## Postfix Linux & Gmail SMTP

Configuring POSTFIX on Linux and Gmail SMTP for sending mail from command line.

1. Let's start with installing Postfix, Mailutils and a series of libraries:

   ```bash
   sudo apt update
   sudo apt upgrade
   sudo apt install postfix mailutils libsasl2-2 libsasl2-modules
   ```

   * as **General Type of Mail Configuration** we'll choose *SATELLITE*
   * as **System Mail Name** we can accept the proposed one or choose one not your domain
   * as **SMTP RELAY HOST** we'll put *smtp.gmail.com:587*
2. After the installation we must go to configure the SASL authentication part. With a text editor we will edit the `/etc/postfix/main.cf` Postfix file. Specifically at the bottom of the file we will add the following lines:

   ```vim
   smtp_use_tls = yes
   smtp_sasl_auth_enable = yes
   smtp_sasl_password_maps = hash:/etc/postfix/sasl/sasl_password
   smtp_sasl_security_options = noanonymous
   smtp_sasl_tls_security_options = noanonymous
   ```

   Now we will have to create the file where to put the Gmail SMTP access password. We create the `/etc/postfix/sasl/sasl_password` file inside which we will put a single row:

   ```vim
   smtp.google.com username:password
   ```

   We create the lookup table db from postfix itself:

   ```bash
   postmap /etc/postfix/sasl/sasl_password
   ```
3. As they are sensitive data, although they will be used encrypted, the file could be read, so let's make sure that only the users root and postfix can handle it:

   ```vim
   chown -R root:postfix /etc/postfix/sasl
   chmod 750 /etc/postfix/sasl
   chmod 640 /etc/postfix/sasl/sasl_password*
   ```
4. We restart the POSTFIX service to apply all the changes:

   ```bash
   sudo service postfix restart
   ```
5. At this point we can send an email from our system to verify the proper functioning:

   ```bash
   echo "send test mail from command line" | mail "sending test" recipient@example.com
   ```

   Any problems can be analyzed in `/var/log/mail.log` and `/var/log/mail.err`.

<br>

## WGET Download Site

Web site full download with WGET command.

```bash
wget --recursive --no-clobber --page-requisites --html-extension --convert-links --restrict-filenames=windows --domains mysite.com --no-parent www.mysite.com
```

<br>

## How to find website's DNS address

To check the current nameservers (DNS) for any domain name from a Linux or Unix/macOS command line:

1. Open the Terminal application
2. Type `host -t ns domain-name-here` to print the current DNS servers of a domain\
   OR\
   Type `dig ns domain-name-here` command
3. to find the delegation path from the root name servers type `dig +trace domain-name-here`

> Above Linux or Unix command will show you detailed information about the domain name, including its nameservers (DNS).

<br>

## Open file with specific app from terminal (macOS)

To open file with specific application from macOS terminal, execute the command below:

```bash
open -a TextEdit file.txt

open -a "App Store"
```

> **Note**: pay attention to the application name that has to be the same as appear in the Application folder (respecting case and spaces format).

> **Tip**: to launch only the application, type the command above without filename.

<br>

## Uninstall commands on Linux

As the `man apt-get` page says:

> **remove** - remove is identical to install execpt that packages are removed instead of installed. Note that removing a package **leave its configuration files on the system**. If a plus sign is appended to the package name (with no intervening space), the identified package will be installed instead of removed.

> **purge** - purge is identical to remove except that packages are removed and purged (**any configuration files are deleted too**).

This of course, does not apply to packages that hold configuration files inside the user's home folder, these files will not be touched.\
\
So for example, if you were to `purge` Firefox or any other that holds some configuration files inside your `/home` folder, these configuration files will stay there.\
\
On the other hand if you were to install Apache, MySQL or any other services similar that save their configuration files in `/etc`, these configuration files will be deleted in you use `purge`.

<br>

## Crontab Linux

Crontab (CRON TABle) is a file which contains the schedule of cron entries to be run and at specified times.

#### Crontab Commands

`export EDITOR=vi;` to specify an editor to open crontab file.\
\
**crontab -e**     Edit crontab file, or create one if it doesn’t already exist.\
**crontab -l**     Crontab list of cronjobs , display crontab file contents.\
**crontab -r**     Remove your crontab file.\
**crontab -v**     Display the last time you edited your crontab file. (This option is only available on a few systems.)

#### Crontab file syntax

A crontab file has five fields for specifying day , date and time followed by the command to be run at that interval.

```txt
*       *       *       *       *       command/to/execute

-       -       -       -       -

|       |       |       |       |
|       |       |       |       + ----- day of week (0 - 6) (Sunday=0)
|       |       |       |
|       |       |       +-------------- month (1 - 12)
|       |       |
|       |       +---------------------- day of month (1 - 31)
|       |
|       +------------------------------ hour (0 - 23)
|
+-------------------------------------- min (0 - 59)
```

#### Example

```vim
# Poweroff every day at 18:00
00 18 * * * /usr/bin/poweroff
```

<br>

## GitHub Repository Quick Setup

First it is possible to create and setup all from the GitHub website, in the user area, `Your repositories` section.

#### ...or create a new repository on the command line

```bash
echo "# <repo_name>" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/<username>/<repo_name>.git
git push -u origin main
```

#### ...or push an existing repository from the command line

```bash
git remote add origin https://github.com/<username>/<repo_name>.git
git branch -M main
git push -u origin main
```

<br>

## GitHub set remote origin

Commands to set the GitHub remote origin for a local git repository

```bash
git remote -v

git remote add origin https://github.com/<username>/<repo_name>.git

git push --force --set-upstream origin main
```

<br>

## How to Securely Copy Files in Linux | scp Command

**scp** (secure copy) command in Linux system is used to copy file(s) between servers in a secure way. The SCP command or secure copy allows the secure transferring of files between the local host and the remote host or between two remote hosts. It uses the same authentication and security as it is used in the `Secure Shell (SSH) protocol`. SCP is known for its simplicity, security, and pre-installed availability.

#### Syntax of `scp` command

```bash
scp [options] [[user@]host1:]source_file_or_directory ... [[user@]host2:]destination
```

In this syntax:

* **options**: These are various options that modify the behavior of the SCP command, such as *-i* for specifying an identity file, *-l* for limiting bandwidth, *-o* for specifying SSH options, *-P* for specifying a custom SSH port, and *-S* for specifying a program to use for the encrypted connection.
* **\[\[user@]host1:]source\_file\_or\_directory**: This represents the source file or directory. It can be local or on a remote machine specified by *user\@host1:*.
* **...**: This indicates that you can specify multiple source files or directories.
* **\[\[user@]host2:]destination**: This is the destination where the files or directories will be copied. It can be local or on a remote machine specified by *user\@host2:*.

#### Options in `scp` command

Most commonly used Options in `scp` command

| options |                                                 Description                                                |
| :-----: | :--------------------------------------------------------------------------------------------------------: |
|  **-P** |             <p><strong>port</strong>: Specifies the port to connect<br>on the remote host.</p>             |
|  **-p** |           <p>Preserves modification times, access times,<br>and modes from the original file.</p>          |
|  **-q** |                                        Disables the progress meter.                                        |
|  **-r** |                                    Recursively copy entire directories.                                    |
|  **-s** | <p>Name of program to use for the encrypted connection.<br>The program must understand ssh(1) options.</p> |

<br>

## Wifi Networks Scan in Linux | nmcli Command

**nmcli** is a command-line tool for controlling NetworkManager and reporting network status. It can be utilized as a replacement for nm-applet or other graphical clients. nmcli is used to create, display, edit, delete, activate, and deactivate network connections, as well as control and display network device status.\
\
To perform a wifi networks scan use the command below:

```bash
nmcli device wifi list
```

Example result:

![screen-nmcli-command](https://3913662071-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYjwP9TiS00NQ46CAYX0d%2Fuploads%2Fgit-blob-e108f4610b8f9f248dd629021fe207b32732cc30%2Fscreen-nmcli-command.png?alt=media)

<br>

## How to check used ports on Linux

To check the listening ports and applications on Linux:

1. Open a terminal shell
2. Run any one of the following command on Linux to see open ports:

   ```bash
   sudo lsof -i -P -n | grep LISTEN
   sudo netstat -tulpn | grep LISTEN
   sudo ss -tulpn | grep LISTEN
   sudo lsof -i:22 ## see a specific port such as 22
   sudo nmap -sTU -O IP-address-Here
   ```
3. For the latest verion of Linux use the `ss` command. For example `ss -tulw`.

<br>

## Manage Git file tracking

`.gitignore` will prevent untracked files from being added (without an `add -f`) to the set of files tracked by Git. However, Git will continue to track any files that are already being tracked.\
\
To stop tracking a file, you need to remove it from the index. This can be achieved with this command.

```bash
git rm --cached <file>
```

If you want to remove a whole folder, you need to remove all files in it recursively.

```bash
git rm -r --cached <folder>
```

> The removal of the file from head revision will happen in the next commit.

**WARNING: while this will not remove the physical file from your local machine, it will remove the files from other developers' machines on their next `git pull`.**

<br>

## KEYMAP Linux Keyboard Layout

A persistent keymap can be set in `/etc/vconsole.conf`, which is read by **systemd** on start-up. The `KEYMAP` varible is used for specifying the keymap. If the variable is empty or not set, the `us` keymap is used as default value. For example:

```vim
/etc/vconsole.conf

KEYMAP=uk
```

For convenience, *localectl* may be used to set the console keymap. It will change the `KEYMAP` variable in `/etc/vconsole.conf` and also se the keymap for the current session:

```bash
localectl set-keymap --no-convert <keymap>
```

The `--no-convert` option can be used to prevent `localectl` from automatically changing the **Xorg keymap** to the nearest match.\
\
If required, the keymap from `/etc/vconsole.conf` can be loaded during early userspace by the `keymap` **mkinitcpio hook**.

<br>

## Download locally entire website | wget Command

GNU **Wget** is a free utility for non-interactive download of files from the Web. It supports HTTP, HTTPS, and FTP protocols, as well as retrieval through HTTP proxies.\
\
Wget is non-interactive, meaning that it can work in the background, while the user is not logged on. This allows you to start a retrieval and disconnect from the system, letting Wget finish the work. By contrast, most of the Web browsers require constant user's presence, which can be a great hindrance when transferring a lot of data.\
\
Wget can follow links in HTML, XHTML, and CSS pages, to create local versions of remote web sites, fully recreating the directory structure of the original site. This is sometimes referred to as "recursive downloading." While doing that, Wget respects the Robot Exclusion Standard (*/robots.txt*). Wget can be instructed to convert the links in downloaded files to point at the local files, for offline viewing.\
\
Wget has been designed for robustness over slow or unstable network connections; if a download fails due to a network problem, it will keep retrying until the whole file has been retrieved. If the server supports regetting, it will instruct the server to continue the download from where it left off.\
\
Code example:

```bash
wget --mirror --convert-links --wait=2 https://mydomain.com
```

<br>

## Create ZIP achive with password protected on Linux | zip Command

Let’s use the `zip` command to create a password protected and compressed archive by using the examples below.

#### Example 1

The `-p` (password) option allows us to specify a password in our `zip` command. The following command will create a password protected zip archive of `file1.txt` and `file2.txt`, using a password of “mypassword” and the zip archive will be called `my_archive.zip`.

```bash
zip -p mypassword my_archive.zip file1.txt file2.txt
```

> **WARNING**: The problem with the `-p` option is that our password can easily be seen by anyone looking at the terminal over our shoulder or perusing the terminal history e.g. with the `history` command. This is generally not a good method to use, but could be employed safely in some scenarios, such as inside of a Bash script, assuming that the user sets the password and the value is stored as a variable.

#### Example 2

A much better method to use is `-e` (encrypt). This will prompt you for a password to use, and it will be hidden in the terminal so that onlookers and those browsing the terminal history will have no idea what you typed for a password. The syntax is as follows:

```bash
zip -e my_archive.zip file1.txt file2.txt
Enter password: 
Verify password: 
    adding: file1.txt (stored 0%)
    adding: file2.txt (stored 0%)
```

As you can see above, we are prompted in the terminal to enter and confirm our password selection, but the input keystrokes are invisible.
