Planet Collab

๐Ÿ”’
โŒ About FreshRSS
There are new articles available, click to refresh the page.
Before yesterdayYour RSS feeds

Introduction to Python Network Automation: The first journey, 2nd edition & a new title, โ€œIntroduction to Ansible Network Automation: KISSโ€ in the works

February 25th 2023 at 00:35

I am honored to have been offered the opportunity to prepare and write the second edition of my original book, โ€œIntroduction to Python Network Automation: The first journeyโ€.

According to a 2018 article published by Publishers Weekly, the percentage of submitted manuscripts that are eventually published in traditional paper publication can vary widely depending on the publisher and the genre. However, on average, it is estimated that only about 1% of manuscripts submitted to publishers are eventually published. In this day and age, itโ€™s difficult to determine an exact percentage, as it may vary by field, publisher, and individual book. But, according to the statistics provided by Bowker, a company that provides bibliographic information and management solutions, less than 30% of nonfiction books are ever revised or updated. This includes technical books.


Furthermore, I am thrilled to announce that I will be submitting a second proposal for a new book, which will serve as a sequel to my previous book. The working title for this new book is โ€œIntroduction to Ansible Network Automation: KISSโ€, and it will be co-authored by my ex-colleague, Erwin Medina. I had the pleasure of mentoring Erwin and introducing him to the fascinating world of Network Automation, and I am grateful that he has agreed to join me in this endeavor. By working together, our writing process will be significantly less arduous, and we will be able to share the joy of our success with others. After all, sharing happiness multiplies it, and sharing pain divides it. ๐Ÿ˜€ย #writingย #automationย #happinessย #pythonย #researchย #networkย #shareย #ansible #2ndedition

Replace Youtube-dl with yt-dlp, speed up your download

February 21st 2023 at 12:33

About 3 days ago, youtube-dl stopped downloading youtube files and I had to download some API tutorials to digest more on the topic. Canโ€™t wait until the developer makes the changes to fix the YouTube related issue. Time to move to yt-dlp and speed up the download and forget about any youtube-dlโ€™s current issue or any future issues.

Step 1. Install Scoop on your Windows PC. Perform this task in your PowerShell window. Scoop is a command-line installer for Windows. With Scoop, you can install programs and plugins for your terminal.ย 

Run the following code inside PowerShell:

iwr -useb get.scoop.sh | iex

Step 2. Use scoop command o install yt-dlp on your Windows machine.

scoop install yt-dlp

To update, run:

scoop update yt-dlp

Source: https://github.com/yt-dlp/yt-dlp/wiki/Installation

You can now download your favouriate videos in MP4 or songs in MP3.

For MP4 videos:

PS C:\Users\brend> yt-dlp -S res,ext:mp4:m4a โ€“recode mp4 https://www.youtube.com/watch?v=Ed9AvZRrNbcโ€&โ€list=PLwvLLrEXDvnoVNEbnVtpeQ7iNVtvZbGJ_โ€&โ€index=14

For MP3 music files:

PS C:\Users\brend> yt-dlp -f โ€˜baโ€™ -x โ€“audio-format mp3 https://www.youtube.com/watch?v=UHSQrFyO8dw

Regular Expressions 01 โ€“ ask chatGPT to teach you Regular Expression

February 18th 2023 at 11:59

Regular expressions (also known as regex) are a powerful tool for working with text data in a wide variety of programming languages, including Python, Java, and JavaScript. They allow you to match and manipulate text based on patterns of characters, which can be very useful for tasks such as data validation, text extraction, and string manipulation.

Here is a brief overview of the syntax and some common use cases for regular expressions:

  1. Basic syntax
    • Regular expressions are typically defined as a string that contains a pattern of characters.
    • Characters in the pattern represent either themselves or special instructions for matching a certain type of character.
    • Special characters are typically indicated with a backslash (), such as โ€œ\dโ€ for any digit character or โ€œ\sโ€ for any whitespace character.
  2. Character classes
    • Character classes are sets of characters that can be matched by a single pattern character.
    • Common character classes include โ€œ\dโ€ for any digit character, โ€œ\wโ€ for any word character (letter, digit, or underscore), and โ€œ\sโ€ for any whitespace character.
    • You can use square brackets to create custom character classes, such as โ€œ[aeiou]โ€ to match any vowel character.
  3. Quantifiers
    • Quantifiers indicate how many times a pattern should be repeated.
    • Common quantifiers include โ€œ+โ€ to match one or more of the preceding pattern, โ€œ*โ€ to match zero or more of the preceding pattern, and โ€œ?โ€ to match zero or one of the preceding pattern.
    • You can also use curly braces to indicate a specific number of repetitions, such as โ€œ{3}โ€ to match exactly three repetitions of the preceding pattern.
  4. Alternatives
    • Alternatives allow you to match multiple patterns using the pipe character (โ€œ|โ€).
    • For example, the pattern โ€œcat|dogโ€ will match either โ€œcatโ€ or โ€œdogโ€.
  5. Anchors
    • Anchors allow you to match patterns based on their position in the text.
    • The โ€œ^โ€ character matches the beginning of the text, while the โ€œ$โ€ character matches the end of the text.
    • You can use โ€œ\bโ€ to match word boundaries, which are positions where a word character is adjacent to a non-word character.
  6. Groups
    • Groups allow you to group patterns together and apply quantifiers or alternatives to the group as a whole.
    • You can use parentheses to create groups, such as โ€œ(abc)+โ€ to match one or more repetitions of the pattern โ€œabcโ€.

Here is an example of how to use regular expressions in Python to match a phone number in a string:

mport re

# define the regular expression pattern
pattern = r"\d{4}-\d{3}-\d{3}"

# define the text to search
text = "Please call me at 0414-123-456."

# use the re.search() method to find the phone number
match = re.search(pattern, text)

# check if a match was found and print the result
if match:
    print("Phone number found:", match.group())
else:
    print("No phone number found.")

In this example, we define a regular expression pattern that matches a phone number in the format โ€œXXXX-XXX-XXXโ€, where X is any digit character. We then define the text to search for a phone number and use the re.search() method to find a match for the pattern. Finally, we check if a match was found and print the result.

Regular expressions can be a very powerful tool for working with text data, but they can also be complex and difficult to read. Itโ€™s important to use them carefully and test your patterns thoroughly to ensure they are working as expected.

Workplace survival 02 โ€“ How to deal with a backstabbing workmate?

February 14th 2023 at 13:28

Iโ€™ve asked chatGPT the above question and it answered.

Dealing with a backstabbing workmate can be difficult, but here are some strategies that may help:

  1. Document everything: Keep a record of any incidents that involve backstabbing, including dates, times, and what was said or done.
  2. Confront the person: Address the behavior directly and professionally, and provide specific examples of the behavior that you find problematic. Be clear about your boundaries and what you expect going forward.
  3. Avoid engaging in gossip or retaliating: Donโ€™t stoop to their level by engaging in gossip or trying to retaliate. Stay focused on your work and your goals.
  4. Build a support network: Cultivate positive relationships with other colleagues who can provide support and help counteract the negative behavior.
  5. Seek help from a manager or HR: If the behavior continues and is impacting your ability to do your job, seek help from a manager or human resources representative to mediate the situation.

Remember, itโ€™s important to remain professional and focus on the behavior, not the person. Document everything, address the behavior directly, and donโ€™t let the negative behavior affect your work or your well-being.

Workplace survival 01 โ€“ How to deal with colleague with bad attitude?

February 14th 2023 at 13:24

I asked chatGPT this question and it answered:

Question: How to deal with colleague with bad attitude?

Dealing with a colleague who has a bad attitude can be challenging, but there are some strategies that may help:

  1. Stay calm and professional: Donโ€™t let their attitude affect your behavior or attitude towards them. Stay calm, polite, and professional.
  2. Communicate directly: Address the behavior with the colleague directly and professionally, and provide specific examples of the behavior that you find problematic.
  3. Focus on the behavior, not the person: Avoid personal attacks and instead focus on the specific behavior that needs to be changed.
  4. Set boundaries: If the behavior continues, set clear boundaries and consequences for further misconduct.
  5. Seek help from a manager or HR: If the situation is not improving, seek help from a manager or human resources representative to mediate the situation.

Remember, the key is to remain professional and focus on the behavior, not the person.

NetBox โ€“ Use REST API to add multiple manufacturers (Using Postman)

February 8th 2023 at 15:56

Use Postman to aadd manufacturer names into NetBox.

Step 1. Set up the variables including the API Key.

Step 2. Add the body type and also authorisation method.

Step 3. Write a JSON list for all the manufacturers. If you want to enter more details, refer to the full JSON list example at the bottom.

JSON format list example for Manufacturers

[

ย ย ย ย {

ย ย ย ย ย ย ย ย โ€œnameโ€:ย โ€œPaloย Altoโ€,ย โ€œslugโ€:ย โ€œpalo-altoโ€

ย ย ย ย },

ย ย ย ย {

ย ย ย ย ย ย ย ย โ€œnameโ€:ย โ€œJuniperโ€,ย โ€œslugโ€:ย โ€œjuniperโ€

ย ย ย ย }

]

ย 

A FULL JSON Example of Manufacturers with the details

[

ย ย ย ย ย ย ย  {

ย ย ย ย ย ย ย ย ย ย ย  "id": 1,

ย ย ย ย ย ย ย ย ย ย ย  "url": "https://192.168.188.128:443/api/dcim/manufacturers/1/",

ย ย ย ย ย ย ย ย ย ย ย  "display": "Cisco",

ย ย ย ย ย ย ย ย ย ย ย  "name": "Cisco",

ย ย ย ย ย ย ย ย ย ย ย  "slug": "cisco",

ย ย ย ย ย ย ย ย ย ย ย  "description": "",

ย ย ย ย ย ย ย ย ย ย ย  "tags": [],

ย ย ย ย ย ย ย ย ย ย ย  "custom_fields": {},

ย  ย ย ย ย ย ย ย ย ย ย "created": "2023-02-08T14:18:01.542500Z",

ย ย ย ย ย ย ย ย ย ย ย  "last_updated": "2023-02-08T14:18:01.542525Z",

ย ย ย ย ย ย ย ย ย ย ย  "devicetype_count": 0,

ย ย ย ย ย ย ย ย ย ย ย  "inventoryitem_count": 0,

ย ย ย ย ย ย ย ย ย ย ย  "platform_count": 0

ย ย ย ย ย ย ย  },

ย ย ย ย ย ย ย  {

ย ย ย ย ย ย ย ย ย ย ย  "id": 2,

ย ย ย ย ย ย ย ย ย ย ย  "url": "https://192.168.188.128:443/api/dcim/manufacturers/2/",

ย ย ย ย ย ย ย ย ย ย ย  "display": "Cisco Meraki",

ย ย ย ย ย ย ย ย ย ย ย  "name": "Cisco Meraki",

ย ย ย ย ย ย ย ย ย ย ย  "slug": "cisco-meraki",

ย ย ย ย ย ย ย ย ย ย ย  "description": "",

ย ย ย ย ย ย ย ย ย ย ย  "tags": [],

ย ย ย ย ย ย ย ย ย ย ย  "custom_fields": {},

ย ย ย ย ย ย ย ย ย ย ย  "created": "2023-02-08T14:25:59.014583Z",

ย ย ย ย ย ย ย ย ย ย ย  "last_updated": "2023-02-08T14:25:59.014609Z",

ย ย ย ย ย ย ย ย ย ย ย  "devicetype_count": 0,

ย ย ย ย ย ย ย ย ย ย ย  "inventoryitem_count": 0,

ย ย ย ย ย ย ย ย ย ย ย  "platform_count": 0

ย ย ย ย ย ย ย  },

ย ย ย ย ย ย ย  {

ย ย ย ย ย ย ย ย ย ย ย  "id": 4,

ย ย ย ย ย ย ย ย ย ย ย  "url": "https://192.168.188.128:443/api/dcim/manufacturers/4/",

ย ย ย ย ย ย ย ย ย ย ย  "display": "Juniper",

ย ย ย ย ย ย ย ย ย ย ย  "name": "Juniper",

ย ย ย ย ย ย ย ย ย ย ย  "slug": "juniper",

ย ย ย ย ย ย ย ย ย ย ย  "description": "",

ย ย ย ย ย ย ย ย  ย ย ย "tags": [],

ย ย ย ย ย ย ย ย ย ย ย  "custom_fields": {},

ย ย ย ย ย ย ย ย ย ย ย  "created": "2023-02-08T14:34:54.552427Z",

ย ย ย ย ย ย ย ย ย ย ย  "last_updated": "2023-02-08T14:34:54.552456Z",

ย ย ย ย ย ย ย ย ย ย ย  "devicetype_count": 0,

ย ย ย ย ย ย ย ย ย ย ย  "inventoryitem_count": 0,

ย ย ย ย ย ย ย ย ย ย ย  "platform_count": 0

ย ย ย ย ย ย ย  },

ย ย ย ย ย ย ย  {

ย ย ย ย ย ย ย ย ย ย ย  "id": 3,

ย ย ย ย ย ย ย ย ย ย ย  "url": "https://192.168.188.128:443/api/dcim/manufacturers/3/",

ย ย ย ย ย ย ย ย ย ย ย  "display": "Palo Alto",

ย ย ย ย ย ย ย ย ย ย ย  "name": "Palo Alto",

ย ย ย ย ย ย ย ย ย ย ย  "slug": "palo-alto",

ย ย ย ย ย ย ย ย ย ย ย  "description": "",

ย ย ย ย ย ย ย ย ย ย ย  "tags": [],

ย ย ย ย ย ย ย ย ย ย ย  "custom_fields": {},

ย ย ย ย ย ย ย ย ย ย ย  "created": "2023-02-08T14:34:54.528930Z",

ย ย ย ย ย ย ย ย ย ย ย  "last_updated": "2023-02-08T14:34:54.528954Z",

ย ย ย ย ย ย ย ย ย ย ย  "devicetype_count": 0,

ย ย ย ย ย ย ย ย ย ย ย  "inventoryitem_count": 0,

ย ย ย ย ย ย ย ย ย ย ย  "platform_count": 0

ย ย ย ย ย ย ย  }

Linux post installation software upgade.

February 8th 2023 at 12:55

Immediately after you have installed your Linux on your System, perform a quick software updates and reboot the server at least once. In this example, Ubuntu 22.04.1 upgrade is shown.

First update and check available packages. This command does not upgrade your software.

bchoi@u2204s:~$ sudo apt update

Second, run the following command to upgrade the software to the latest versions.

bchoi@u2204s:~$ sudo apt dist-upgrade

Third, give it a reboot.

bchoi@u2204s:~$ sudo reboot

Now, go ahead and install any software you want and configure the server to your likings. Make your day!

Note, for any Red Hat Distributions (Red Hat/CentOS/Fedora/Rocky linux), simply use โ€˜dnf updateโ€™ and it will upgrade the software with a single command.

Linux to Linux file copy โ€“ Move a single file or all files in a directory (using SCP)

February 8th 2023 at 04:19

To copy a single file from one Linux Server to another.
scp bchoi@10.10.10.9:/opt/netbox/netbox/media/devicetype-images/ASR1001-X.jpeg /home/brendan/devicetype-image/

To copy a single file from one Linux Server to another.
scp -r bchoi@To copy a single file from one Linux Server to another.10.10.10.9:/opt/netbox/netbox/media/devicetype-images/* /home/brendan/devicetype-image/

Install VMware tools on Ubuntu 22.04 Jammy Jellyfish Server

February 6th 2023 at 02:59
Step 1. On UBUNTU 22.04 SERVER terminal console:
$ sudo apt install open-vm-tools

Step 2. Reboot the system
$ reboot

Step 3. After the reboot, check the vmware tools have been installed correctly.
$ lsmod | grep vmw
vmw_vsock_virtio_transport_common    40960  1 vsock_loopback
vmw_vsock_vmci_transport    32768  1
vsock                  49152  5 vmw_vsock_virtio_transport_common,vsock_loopback,vmw_vso                                                                                                                ck_vmci_transport
vmw_balloon            24576  0
vmw_vmci               90112  2 vmw_balloon,vmw_vsock_vmci_transport
vmwgfx                368640  2
ttm                    86016  1 vmwgfx
drm_kms_helper        311296  1 vmwgfx
drm                   622592  5 vmwgfx,drm_kms_helper,ttm

VirtualBox โ€“ Enable SSH on RHEL 9.1 VM to allow login from your Windows Desktop

February 5th 2023 at 16:35

Check the IP address of your server.

Configure Port Forwarding to use โ€œ127.0.0.1โ€ with port id 2214.

From your Windows PC, now you can access the RHEL 9.1 using port 2214.

Wahla!!

RHEL 9.1 โ€“ Developer Tools installation, registeration does not work due to no company name or N/A

February 5th 2023 at 15:52

Issue: You forgot to enter your company information during the Developer Account registeration and cannot register with any organizations.

Use the โ€œsubscription-manager register โ€“username bchoi โ€“password SuperSecretPa55word โ€“auto-attachโ€ command to register your system.

Now, run the โ€œdnf groupinstall โ€œDevelopment Toolsโ€ command and it should allow you to update.

Full command below:

$hostnamectl status
subscription-manager register โ€“username bchoi โ€“password SuperSecretPa55word โ€“auto-attach

subscription-manager register
subscription-manager refresh
subscription-manager attach โ€“auto
subscription-manager attach โ€“pool=
subscription-manager list โ€“available โ€“all
subscription-manager-gui

Source: https://access.redhat.com/discussions/2839261

Linux Cron Job โ€“ Running a Python code to run every minute (CentOS/RHEL)

December 15th 2022 at 02:09

Have you ever wondered how to schedule cron job and run your python code at Midnight every night? Here is how:

This will works on CentOS/Red Hat/Fedora.

# Task A. Check cron is installed.
TIP 1: On CentOS/RHEL, Cron service is known as โ€œcrondโ€ and the installed package name is โ€œcronieโ€.

[brendan@localhost ~]$ rpm -q cronie
cronie-1.5.2-8.el8.x86_64
[brendan@localhost ~]$ crond -V
cronie 1.5.2

โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”-
# CentOS or Red Hat will have cronie installed by default, but if it is missing run the commands below before you start.
[brendan@localhost ~]$ sudo systemctl status crond
[brendan@localhost ~]$ sudo dnf update
[brendan@localhost ~]$ sudo dnf install crontabs
[brendan@localhost ~]$ sudo systemctl start crond.service
[brendan@localhost ~]$ sudo systemctl enable crond.service
โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”-

# Task B. Create a Python file and make it executable. Make sure you include th top Shebang! line for this to tell OS where you expect the Pythong application is located in.


brendan@localhost cron_test]$ cat print_hello.py
#!/usr/bin/env python3
# Print the time and hello
from datetime import datetime
print(datetime.now())
print(โ€œHello friendโ€)

[brendan@localhost cron_test]$ ls -lh
total 4.0K
-rw-rw-rโ€“. 1 brendan brendan 101 Dec 14 19:06 print_hello.py
[brendan@localhost cron_test]$ chmod +x print_hello.py
[brendan@localhost cron_test]$ ls -lh
total 4.0K
-rwxrwxr-x. 1 brendan brendan 101 Dec 14 19:06 print_hello.py

# TIP 2: Unlike Ubuntu/Debian, on CentOS 7/8/9, the cron scheduling is done through /etc/crontab.
# TIP 3: On CentOS, the cron job is usually schedule and ran as a root user.

# Task C. Check the file exists.
brendan@localhost cron_test]$ cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .โ€”โ€”โ€”โ€”โ€”- minute (0 โ€“ 59)
# | .โ€”โ€”โ€”โ€”- hour (0 โ€“ 23)
# | | .โ€”โ€”โ€”- day of month (1 โ€“ 31)
# | | | .โ€”โ€”- month (1 โ€“ 12) OR jan,feb,mar,apr โ€ฆ
# | | | | .โ€”- day of week (0 โ€“ 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed

# Now check the crond service status one more time.
[brendan@localhost cron_test]$ systemctl status crond
โ— crond.service โ€“ Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor prese>
Active: active (running) since Thu 2022-12-15 16:50:23 EST; 21h left
[โ€ฆommitted]

# Task D. Schedule the cron job like this
[brendan@localhost cron_test]$ cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .โ€”โ€”โ€”โ€”โ€”- minute (0 โ€“ 59)
# | .โ€”โ€”โ€”โ€”- hour (0 โ€“ 23)
# | | .โ€”โ€”โ€”- day of month (1 โ€“ 31)
# | | | .โ€”โ€”- month (1 โ€“ 12) OR jan,feb,mar,apr โ€ฆ
# | | | | .โ€”- day of week (0 โ€“ 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed

* * * * * root /home/brendan/cron_test/print_hello.py >> /home/brendan/cron_test/cron.log 2>&1
# TIP 4: * * * * * means run the cron job every minute

0 0 * * * root /home/brendan/cron_test/print_hello.py >> /home/brendan/cron_test/cron.log 2>&1
# TIP 5: 0 0 * * * means run the cron job every night at Mid-nigh (00:00)

# Task E. Check the cron.log to see if your script is running every minute. If you see a similar result as below, it is a success!
[brendan@localhost cron_test]$ cat cron.log
2022-12-14 19:40:01.614946
Hello friend
2022-12-14 19:41:01.640820
Hello friend
2022-12-14 19:42:01.662788
Hello friend
2022-12-14 19:43:01.685712
Hello friend
2022-12-14 19:44:01.708973
Hello friend

ย 

Now you can run any script at a scheduled time.

Cisco NX-OS โ€“ strangely missing โ€œshow ip interface briefโ€ command

December 12th 2022 at 04:26

The โ€œshow ip interface briefโ€ command is a layer 3 command on the Nexus Devices.

If you do not have routing enabled, it does not display anything.
Try using โ€œshow interface briefโ€ or โ€œshow interface descriptionโ€ to get port up/down status.

When L3 routing is enabled.
show ip interface brief

When L3 is not enabled.
show interface description
show interface brief
show int status

Python โ€“ Converting a JavaScript Code into a Python code 2

December 11th 2022 at 02:15

Here is the translated version of the previous code.

Original JavaScript Code:

brendan@LP50C:~/practice-linux$ cat app.js
let index = 0
const words = [
        '๋‚  ์ข…๋ฃŒํ•ด์ค˜',
        '๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜',
        'Ctrl... ๊ทธ๋ฆฌ๊ณ ...',
        '์ฟจ๋Ÿญ',
        'c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ',
        '์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ',
        '์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...',
        '์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค',
        '์ฝœ๋ก์ฝœ๋ก',
        '๋‹ˆ ์™ผ์ชฝ ์†๊ฐ€๋ฝ์œผ๋กœ ์ ค ์•„๋ž˜',
        '์–ด์šฐ ์ข€ ์ฟจ๋Ÿญ ๋๋‚ด๋‹ฌ๋ผ๊ณ '
]

setInterval(
        () => {
                console.log(words[(index++)%words.length])
        },
        1000
)

Run above java code using node.

brendan@LP50C:~/practice-linux$ node app.js
๋‚  ์ข…๋ฃŒํ•ด์ค˜
๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜
Ctrl... ๊ทธ๋ฆฌ๊ณ ...
์ฟจ๋Ÿญ
c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ
์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ
์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...
์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค
์ฝœ๋ก์ฝœ๋ก
๋‹ˆ ์™ผ์ชฝ ์†๊ฐ€๋ฝ์œผ๋กœ ์ ค ์•„๋ž˜
์–ด์šฐ ์ข€ ์ฟจ๋Ÿญ ๋๋‚ด๋‹ฌ๋ผ๊ณ 
๋‚  ์ข…๋ฃŒํ•ด์ค˜
๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜
Ctrl... ๊ทธ๋ฆฌ๊ณ ...
์ฟจ๋Ÿญ
c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ
์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ
์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...
์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค
^C

Now translated version and in Python Script.

brendan@LP50C:~/practice-linux$ cat app1.py
import time
import datetime

words = [
        'Quit this operation.',
        'Please give me a break.',
        'To quit, ',
        'Press Ctrl... and',
        'c, OK?',
        'No, don\'t press c, t, r, l',
        'Press the Ctrl key first...',
        'Press the Ctrl key, you idiot, not c, t, r, l keys',
        'Sigh...',
        'Move your left pinky finger to the bottom of your keyboard.',
        'I beg you to press the Ctrl key and the c key combination.',
        'Thank you my friend!'
]

for i in range(1000):
    for word in words:
        now = datetime.datetime.now()
        date_time = now.strftime("%d/%m/%Y %H:%M:%S")
        print(date_time)
        print(word, end="\n")
        time.sleep(1)
brendan@LP50C:~/practice-linux$ python3 app1.py
11/12/2022 12:11:44
Quit this operation.
11/12/2022 12:11:45
Please give me a break.
11/12/2022 12:11:46
To quit,
11/12/2022 12:11:47
Press Ctrl... and
11/12/2022 12:11:48
c, OK?
11/12/2022 12:11:49
No, don't press c, t, r, l
11/12/2022 12:11:50
Press the Ctrl key first...
11/12/2022 12:11:51
Press the Ctrl key, you idiot, not c, t, r, l keys
11/12/2022 12:11:52
Sigh...
11/12/2022 12:11:53
Move your left pinky finger to the bottom of your keyboard.
11/12/2022 12:11:54
I beg you to press the Ctrl key and the c key combination.
11/12/2022 12:11:55
Thank you my friend!
11/12/2022 12:11:56
Quit this operation.
^CTraceback (most recent call last):
  File "/home/brendan/practice-linux/app1.py", line 25, in <module>
    time.sleep(1)
KeyboardInterrupt

Disable the timedate for cleaner result:

brendan@LP50C:~/practice-linux$ cat app1.py
import time

words = [
        'Quit this operation.',
        'Please give me a break.',
        'To quit, ',
        'Press Ctrl... and',
        'c, OK?',
        'No, don\'t press c, t, r, l',
        'Press the Ctrl key first...',
        'Press the Ctrl key, you idiot, not c, t, r, l keys',
        'Sigh...',
        'Move your left pinky finger to the bottom of your keyboard.',
        'I beg you to press the Ctrl key and the c key combination.',
        'Thank you my friend!'
]

for i in range(1000):
    for word in words:
        print(word, end="\n")
        time.sleep(1)
brendan@LP50C:~/practice-linux$ python3 app1.py
Quit this operation.
Please give me a break.
To quit,
Press Ctrl... and
c, OK?
No, don't press c, t, r, l
Press the Ctrl key first...
Press the Ctrl key, you idiot, not c, t, r, l keys
Sigh...
Move your left pinky finger to the bottom of your keyboard.
I beg you to press the Ctrl key and the c key combination.
Thank you my friend!
Quit this operation.
Please give me a break.
To quit,
Press Ctrl... and
^CTraceback (most recent call last):
  File "/home/brendan/practice-linux/app1.py", line 21, in <module>
    time.sleep(1)
KeyboardInterrupt

Python โ€“ Converting a JavaScript Code into a Python code 1

December 11th 2022 at 02:04

This code was found in one of YALCOโ€™s Youtube tutorial. I wanted to see if I can concert this into a Python code.

let index = 0
const words = [
        '๋‚  ์ข…๋ฃŒํ•ด์ค˜',
        '๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜',
        'Ctrl... ๊ทธ๋ฆฌ๊ณ ...',
        '์ฟจ๋Ÿญ',
        'c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ',
        '์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ',
        '์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...',
        '์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค',
        '์ฝœ๋ก์ฝœ๋ก',
        '๋‹ˆ ์™ผ์ชฝ ์†๊ฐ€๋ฝ์œผ๋กœ ์ ค ์•„๋ž˜',
        '์–ด์šฐ ์ข€ ์ฟจ๋Ÿญ ๋๋‚ด๋‹ฌ๋ผ๊ณ '
]

setInterval(
        () => {
                console.log(words[(index++)%words.length])
        },
        1000
)
import time
#import datetime

words = [
        '๋‚  ์ข…๋ฃŒํ•ด์ค˜',
        '๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜',
        'Ctrl... ๊ทธ๋ฆฌ๊ณ ...',
        '์ฟจ๋Ÿญ',
        'c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ',
        '์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ',
        '์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...',
        '์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค',
        '์ฝœ๋ก์ฝœ๋ก',
        '๋‹ˆ ์™ผ์ชฝ ์†๊ฐ€๋ฝ์œผ๋กœ ์ ค ์•„๋ž˜',
        '์–ด์šฐ ์ข€ ์ฟจ๋Ÿญ ๋๋‚ด๋‹ฌ๋ผ๊ณ '
]

for i in range(1000):
    for word in words:
#        now = datetime.datetime.now()
#        date_time = now.strftime("%d/%m/%Y %H:%M:%S")
        #print(date_time)
        print(word, end="\n")
        time.sleep(1)

The result: The Ctrl+C already is a built-in to Python, so run the above code and get the same result. Also, note, iโ€™ve limited the range to be 1000 times but you can increase this number.

brendan@LP50C:~/practice-linux$ python3 app.py
๋‚  ์ข…๋ฃŒํ•ด์ค˜
๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜
Ctrl... ๊ทธ๋ฆฌ๊ณ ...
์ฟจ๋Ÿญ
c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ
์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ
์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...
์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค
์ฝœ๋ก์ฝœ๋ก
๋‹ˆ ์™ผ์ชฝ ์†๊ฐ€๋ฝ์œผ๋กœ ์ ค ์•„๋ž˜
์–ด์šฐ ์ข€ ์ฟจ๋Ÿญ ๋๋‚ด๋‹ฌ๋ผ๊ณ 
๋‚  ์ข…๋ฃŒํ•ด์ค˜
๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜
Ctrl... ๊ทธ๋ฆฌ๊ณ ...
์ฟจ๋Ÿญ
c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ
์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ
์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...
์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค
์ฝœ๋ก์ฝœ๋ก
๋‹ˆ ์™ผ์ชฝ ์†๊ฐ€๋ฝ์œผ๋กœ ์ ค ์•„๋ž˜
์–ด์šฐ ์ข€ ์ฟจ๋Ÿญ ๋๋‚ด๋‹ฌ๋ผ๊ณ 
๋‚  ์ข…๋ฃŒํ•ด์ค˜
๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜
Ctrl... ๊ทธ๋ฆฌ๊ณ ...
์ฟจ๋Ÿญ
c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ
์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ
^CTraceback (most recent call last):
  File "/home/brendan/practice-linux/app.py", line 24, in <module>
    time.sleep(1)
KeyboardInterrupt

If you enable the timedate module, you can see that it prints one item from the list at 1 second interval.

import time
import datetime

words = [
        '๋‚  ์ข…๋ฃŒํ•ด์ค˜',
        '๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜',
        'Ctrl... ๊ทธ๋ฆฌ๊ณ ...',
        '์ฟจ๋Ÿญ',
        'c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ',
        '์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ',
        '์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...',
        '์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค',
        '์ฝœ๋ก์ฝœ๋ก',
        '๋‹ˆ ์™ผ์ชฝ ์†๊ฐ€๋ฝ์œผ๋กœ ์ ค ์•„๋ž˜',
        '์–ด์šฐ ์ข€ ์ฟจ๋Ÿญ ๋๋‚ด๋‹ฌ๋ผ๊ณ '
]

for i in range(1000):
    for word in words:
        now = datetime.datetime.now()
        date_time = now.strftime("%d/%m/%Y %H:%M:%S")
        print(date_time)
        print(word, end="\n")
        time.sleep(1)


brendan@LP50C:~/practice-linux$ python3 app.py
11/12/2022 12:01:17
๋‚  ์ข…๋ฃŒํ•ด์ค˜
11/12/2022 12:01:18
๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜
11/12/2022 12:01:19
Ctrl... ๊ทธ๋ฆฌ๊ณ ...
11/12/2022 12:01:20
์ฟจ๋Ÿญ
11/12/2022 12:01:21
c ๋ฅผ ๋ˆ„๋ฅด๋ฉด... ๋ผ
11/12/2022 12:01:22
์•„๋‹ˆ c t r l ์ด ์•„๋‹ˆ๋ผ
11/12/2022 12:01:23
์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋จผ์ €...
11/12/2022 12:01:24
์ปจํŠธ๋กค ํ‚ค ์ด์ž์‹์•„ ์ปจํŠธ๋กค ์ปจํŠธ๋กค ์ปจํŠธ๋กค
11/12/2022 12:01:25
์ฝœ๋ก์ฝœ๋ก
11/12/2022 12:01:26
๋‹ˆ ์™ผ์ชฝ ์†๊ฐ€๋ฝ์œผ๋กœ ์ ค ์•„๋ž˜
11/12/2022 12:01:27
์–ด์šฐ ์ข€ ์ฟจ๋Ÿญ ๋๋‚ด๋‹ฌ๋ผ๊ณ 
11/12/2022 12:01:28
๋‚  ์ข…๋ฃŒํ•ด์ค˜
11/12/2022 12:01:29
๋ถ€ํƒ์ด์•ผ, ์•ˆ์‹ํ•˜๊ฒŒ ํ•ด์ค˜
11/12/2022 12:01:30
Ctrl... ๊ทธ๋ฆฌ๊ณ ...
^CTraceback (most recent call last):
  File "/home/brendan/practice-linux/app.py", line 24, in <module>
    time.sleep(1)
KeyboardInterrupt

Linux โ€“ User Management Guide 1b

December 11th 2022 at 00:22

Ubuntu โ€“ Creating a new sudo user, assign previliges, then accessing another userโ€™s home directory


# Create a new user
brendan@LP50C:~/learn_bash$ sudo useradd hugh
[sudo] password for brendan:
brendan@LP50C:~/learn_bash$ sudo passwd hugh
New password:
Retype new password:
passwd: password updated successfully


# Grant sudo user access and also modify the visudo file
brendan@LP50C:~/$ sudo usermod -aG sudo hugh
brendan@LP50C:~/$ sudo visudo

[...ommitted]
# User privilege specification
root    ALL=(ALL:ALL) ALL
brendan ALL=(ALL:ALL) ALL
hugh    ALL=(ALL:ALL) ALL
[...ommitted]

# login as the new user and run the sudo apt-get update command, if runs successfully, the user has root privileges.
brendan@LP50C:~/learn_bash$ su - hugh
Password:
$ sudo apt-get update

# Now try to change directory into another user's home directory. It will spit the dummy and give you this error.
$ cd /home/brendan/
-sh: 1: cd: can't cd to /home/brendan/

# You need execute permission to cd into a directory. Change the directory properties using the chmod o+x command. And try it again.

$ sudo chmod o+x /home/brendan
$ cd /home/brendan
$ pwd
/home/brendan
$ sudo ls
learn_bash

$ sudo chmod o+x /home/brendan/learn_bash
$ cd /home/brendan/learn_bash
$ pwd
/home/brendan/learn_bash

$ sudo ls learn_bash
argument.sh  empty_file.txt      file_test.sh  ifelse.sh  non_empty_file.txt  variables.sh
dir_test.sh  empty_file_test.sh  hw.sh         my_dir     user_inputs.sh

$ sudo ls -ult
total 40
-rwxr-xr-x 1 brendan brendan  158 Dec 11 10:04 hw.sh
drwxr-xr-x 2 brendan brendan 4096 Dec 11 08:54 my_dir
-rw-r--r-- 1 brendan brendan    0 Nov 29 21:40 empty_file.txt
[...ommitted]
$ exit

# Now move back in as yourself and run the ls -ult command. you will see the file accessed time from the most recent to the oldest using 'ls -ult' command.

brendan@LP50C:~/learn_bash$ ls -ult
total 40
-rwxr-xr-x 1 brendan brendan  158 Dec 11 10:04 hw.sh
drwxr-xr-x 2 brendan brendan 4096 Dec 11 08:54 my_dir
-rw-r--r-- 1 brendan brendan    0 Nov 29 21:40 empty_file.txt
[...ommitted]

Linux โ€“ User Management Guide 2 โ€“ Groups

December 1st 2022 at 10:11
Linux Groups allow Linux Admins to give access to a group of users rather than individually give access. This simplifies the process and user access management. The last example is giving SSH user access into the server.

brendan@u22s1:~$ sudo useradd -m hugh
brendan@u22s1:~$ ls /home/
brendan  hugh
brendan@u22s1:~$ groups
brendan adm cdrom sudo dip plugdev lxd
brendan@u22s1:~$ groups hugh
hugh : hugh
brendan@u22s1:~$ sudo useradd -r sysuser
brendan@u22s1:~$ groups sysuser
sysuser : sysuser

brendan@u22s1:~$ tail -n 5 /etc/passwd
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
mysql:x:113:118:MySQL Server,,,:/nonexistent:/bin/false
fwupd-refresh:x:114:119:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
hugh:x:1001:1001::/home/hugh:/bin/sh
sysuser:x:998:998::/home/sysuser:/bin/sh
brendan@u22s1:~$ cat /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:syslog,brendan
tty:x:5:
[...ommitted]
fwupd-refresh:x:119:
hugh:x:1001:
sysuser:x:998:

brendan@u22s1:~$ tail /etc/group
syslog:x:113:
uuidd:x:114:
tcpdump:x:115:
tss:x:116:
landscape:x:117:
brendan:x:1000:
mysql:x:118:
fwupd-refresh:x:119:
hugh:x:1001:
sysuser:x:998:


Explanation of the group setting
brendan:x:1000:

brendan = group name
:x = group password, nobody uses them, nobody should use them.
:1000 = Group ID (GID)
: = users members of the group


Add and remove groups:
brendan@u22s1:~$ sudo groupadd tadpoles
brendan@u22s1:~$ sudo groupdel tadpoles


Primary vs Supplementary (secondary) groups: How groups are assigned makes the difference, there is no primary or secondary groups, it it is assigned to a user, then it is said a primary group.
brendan@u22s1:~$ cat /etc/group | grep 1000
brendan:x:1000:
brendan@u22s1:~$ cat /etc/group | grep 1001
hugh:x:1001:

How to add a user to a group?
brendan@u22s1:~$ sudo groupadd frogs
brendan@u22s1:~$ tail -n 5 /etc/group
fwupd-refresh:x:119:
hugh:x:1001:
sysuser:x:998:
linux-admins:x:1002:
frogs:x:1003:

Assigning a user to a group. -a = append, -G = Group
brendan@u22s1:~$ sudo usermod -aG frogs hugh
brendan@u22s1:~$ groups hugh
hugh : hugh frogs

You can also add the user to a group using gpasswd command.
brendan@u22s1:~$ sudo gpasswd -a hugh frogs
Adding user hugh to group frogs


If you want to change the user's primary group, use -g option like this but this is not something Linux Admins usually do.
brendan@u22s1:~$ sudo usermod -g frogs hugh

Log out and log in to start using the newly assigned user group access.
brendan@u22s1:~$ groups
brendan adm cdrom sudo dip plugdev lxd
brendan@u22s1:~$ groups brendan
brendan : brendan adm cdrom sudo dip plugdev lxd frogs


=========================================
One example of using the group is in SSH config file (/etc/ssh/sshd_config).

You can add new line to allow users like this: This works!

AllowUsers brendan hugh leah caitlin sue 

OR, simply use the group. But this works better!

AllowGroups frogs ssh-users

=========================================
How to remove a user from the group?
brendan@u22s1:~$ sudo groupadd dragonfly
brendan@u22s1:~$ sudo usermod -aG dragonfly hugh
brendan@u22s1:~$ groups hugh
hugh : hugh frogs dragonfly
brendan@u22s1:~$ sudo gpasswd -d hugh dragonfly
Removing user hugh from group dragonfly

Linux โ€“ User Management Guide 1

November 30th 2022 at 23:01
Add a new user without changing the /etc/default/useradd file.

$ sudo useradd hugh

-----------------------------------------------
This is where the useradd default exist. You can modify it to give default settings to the newly created user.

$ sudo nano /etc/default/useradd

-----------------------------------------------
Add a new user after changing the /etc/default/useradd file.

$ sudo useradd leah

-----------------------------------------------
Now, check the details.

$ tail -n 5 /etc/passwd
landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:111:1::/var/cache/pollinate:/bin/false
bchoi:x:1000:1000:,,,:/home/bchoi:/bin/bash
hugh:x:1001:1001::/home/hugh:/bin/sh
leah:x:1002:1002::/home/leah:/bin/bash

User ID always starts with 1000+ number and increases by 1.
New user settings can be changed using the /etc/defaul/useradd file. Note, sometimes this file may not exists depending on Linux OS.

-----------------------------------------------
Be explicite on Linux when you can.
Remove a user

$ sudo userdel hugh
$ ls -l /home
total 4
drwxr-xr-x 5 bchoi bchoi 4096 Dec  1 08:00 bchoi
$ tail -n 5 /etc/passwd
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:111:1::/var/cache/pollinate:/bin/false
bchoi:x:1000:1000:,,,:/home/bchoi:/bin/bash
leah:x:1002:1002::/home/leah:/bin/bash

-----------------------------------------------
Add the user hugh with the home directory.

$ sudo useradd -m hugh
$ ls -l /home
total 8
drwxr-xr-x 5 bchoi bchoi 4096 Dec  1 08:00 bchoi
drwxr-xr-x 2 hugh  hugh  4096 Dec  1 08:16 hugh

-----------------------------------------------
Removing the user and the home directory.

$ sudo userdel -r hugh
userdel: hugh mail spool (/var/mail/hugh) not found
$ ls -l /home
total 4
drwxr-xr-x 5 bchoi bchoi 4096 Dec  1 08:00 bchoi
$ tail -n 5 /etc/passwd
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:111:1::/var/cache/pollinate:/bin/false
bchoi:x:1000:1000:,,,:/home/bchoi:/bin/bash
leah:x:1002:1002::/home/leah:/bin/bash
-----------------------------------------------
Add user back to the system

$ sudo useradd -m hugh
$ # Setting the password
$ passwd
Changing password for bchoi.
Current password:
passwd: Authentication token manipulation error
passwd: password unchanged
$ passwd
Changing password for bchoi.
Current password:
New password:
Retype new password:
Sorry, passwords do not match.
passwd: Authentication token manipulation error
passwd: password unchanged
$ passwd
Changing password for bchoi.
Current password:
New password:
Retype new password:
passwd: password updated successfully
$ sudo passwd hugh
New password:
Retype new password:
passwd: password updated successfully

-----------------------------------------------
# Create a System User, useful for automation. e.g.) run report weekkly, automate process etc. create a System account

$ sudo useradd -r sysuser
$ cat /etc/passwd | grep sysuser
sysuser:x:999:999::/home/sysuser:/bin/bash

Note,the -r option will assign user below user ID 1000.

-----------------------------------------------
Check the full options in useradd manual.

$ man useradd

-----------------------------------------------
Go over the /etc/passwd file.

$ tail -n 5 /etc/passwd
pollinate:x:111:1::/var/cache/pollinate:/bin/false
bchoi:x:1000:1000:,,,:/home/bchoi:/bin/bash
leah:x:1002:1002::/home/leah:/bin/bash
hugh:x:1003:1003::/home/hugh:/bin/bash
sysuser:x:999:999::/home/sysuser:/bin/bash

-----------------------------------------------
-----------------------------------------------
Break down of /etc/passwd

E.g.) hugh:x:1003:1003::/home/hugh:/bin/bash

hugh = password
:x: = This just indicates that an encrypted password is in use, but this is not used these days, this is just a carry over from old practice. We now use hashed user password, but it is not shown here.
:1003: = UID, User ID
:1003: = GID, Group ID
:: = User information field, "a.k.a. gecos field". Used for first and last name, optional config.
:/home/hugh: = Home directory of the user
:/bin/bash = Shell designated to the user

-----------------------------------------------
If a user has the shell deginated like, this they cannot login. Most of the time, the sysuser is configured for this like landscape user shown below.

landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin = Users cannot login

-----------------------------------------------
Check which shell is in use for your logged in user.

$ echo $SHELL
/bin/bash

-----------------------------------------------
===============================================
The actual user's password gets saved on the /etc/shadow file and it uses the Hashed password.

$ cat /etc/shadow
cat: /etc/shadow: Permission denied
$ sudo cat /etc/shadow
[sudo] password for bchoi:
root:*:18858:0:99999:7:::
daemon:*:18858:0:99999:7:::
bin:*:18858:0:99999:7:::
[...ommitted]
bchoi:$6$6Q0aDO6UlQ2iJJ67$RhL384JQ5hHJZCO2zcl1eFhCR0YEMXnSFFoAbFh8zpCpR1YoCdZ6iC6getj5dS9jqJVJdkyslEvPZmbBN59jq1:19326:0:99999:7:::
leah:!:19326:0:99999:7:::
hugh:$6$Th25rwYyFBBh9pzo$MQa2C1HH8XdDW7IBfSp985Ho7.eUXakwm7Bx.5e55vP.iYpY5vZnwg13SFuVDsF4Uq2Tjm1wc8JKQoYUcbyWK0:19326:0:99999:7:::
sysuser:!:19326::::::

-----------------------------------------------
Break down of the hashed password in the shadow file.

$ sudo cat /etc/shadow | grep hugh
hugh:$6$Th25rwYyFBBh9pzo$MQa2C1HH8XdDW7IBfSp985Ho7.eUXakwm7Bx.5e55vP.iYpY5vZnwg13SFuVDsF4Uq2Tjm1wc8JKQoYUcbyWK0:19326:0:99999:7:::

hugh: = user name
$6$Th25rwYyFBBh9pzo$MZa2C1HH8XdDW7IBfTp985Ho7.eUXakwm7Bx.5e55vP.iYpY5vXnwg13SFuVDsF4Uq2Tjm1wc8JKQoYUcbyWK0 = Hashed password, this is not the actual password
:19326 = Refers to the number of day since Unix epoc, Unix epoc is January 1st 1970.
:0 = How many days need to be passed for the user to change their password again. 0 means at anytime.
:99999 = How many days before the password reset is required? 99999 days since the Unix epoc time, which indicates infinit.
:7 = How many days the user will be reminded to change their password.
: = Until, how many days the user password will be locked.
: = How many days the account is disabled.
: = 

===============================================

MySQL 8 on Ubuntu 22.04 LTS โ€“ 3. Import excel file into MySQL using Python Pandas module

November 29th 2022 at 12:54

Follow this instructions to import excel file into MySQL database.

Presumption 1. a database is created following the previous โ€œMySQL 8 on Ubuntu 22.04 LTS โ€“ 2โ€ method.

Presumption 2. a table called sales_record is created using mysql CLI or HeidiSQL User interface or MySQL Workbench.

Follow the steps below to import the data.

Step 1. Install Python packages
$ pip install pandas xlrd sqlalchemy

Step 2. If using MySQL, install python3-mysqldb.
$ sudo apt install python3-mysqldb

Step 3. Write a simple read code and print the read information to the screen.

import pandas as pd

df = pd.read_excel('NameNumbers.xlsx')
print(df.head())


*** TIP: Use HeidiSQL user interface to manage database and tables

Step 4. Have a backup of the data daily. Use append method when you can. This script will overwrite the existing tables, so use it in the lab environment only.

$ nano importsql.py

import pandas as pd
from sqlalchemy import create_engine

df = pd.read_excel('FileNameHere.xlsx')

engine = create_engine('mysql://CHANGE_USERID:CHANGE_PASSWORD@192.168.0.211/my_table')
df.to_sql('sales_record', con=engine)

4a. Run the script created above. 
$ python importsql.py


Step 5. Append method. Use this method in the production so the records are not overwritten each time.

$ nano importsql_if_exist_append.py

import pandas as pd
from sqlalchemy import create_engine

df = pd.read_excel('FileNameHere.xlsx')

engine = create_engine('mysql://CHANGE_USERID:CHANGE_PASSWORD@192.168.0.211/my_table')
df.to_sql('sales_record', con=engine, if_exists='append')


Step 6. Prevent Pandas putting in its own index numbers. When appending, pandas will put in repeating index. 
Let SQL manage its own index.

import pandas as pd
from sqlalchemy import create_engine

df = pd.read_excel('FileNameHere.xlsx')

engine = create_engine('mysql://CHANGE_USERID:CHANGE_PASSWORD@192.168.0.211/my_table')
df.to_sql('sales_record', con=engine, if_exists='append', index=False)

Step 7. Assign IDs to the first database. 
Manually add Index colum, move it to the top. 
Update it with the following values,
Name=id, Datatype=INT, Default=AUTO_INCREMENT, Primary_Key=YES.

Step 8. Now only insert the new table values.


Reference: https://www.youtube.com/watch?v=oN0koUt3SXQ
โŒ