One-liners: Difference between revisions

Add Bash is Better section
Line 75: Line 75:
split --lines=10000 --numeric-suffixes --additional-suffix='.txt' BIG_FILE.txt little_file.
split --lines=10000 --numeric-suffixes --additional-suffix='.txt' BIG_FILE.txt little_file.
</source>
</source>
{{References}}
 
== "BASH is better" ==
Most job postings that focus on DevOps have requirements for [[Python]], [[Go]] programming or some other programming language. I disagree that a [[DevOps]] Engineer should also be a programmer. I prioritize quality and workmanship (craftsmanship) which is '''informed''' by broad experience, but '''honed''' by specialization. As a construction analogy, I prefer individual skilled trades over the general handyman approach. Simply put: DevOps is DevOps, it is not programming.  Worse, the requirement for the hot language of the day is a bigger tell-tale sign that the company is either posturing or doesn't know what they're doing. Back when when I first learned Perl (which isn't the hot new language anymore), there was a hilarious t-shirt that said "Be careful or I'll replace you with a line of code"<ref>Dave Jacoby agrees with me on the broad point that (programming) languages are just different domain dialects, and also cites the ThinkGeek t-shirt phrase "Go Away Or I Will Replace You With a Small Shell Script"
 
https://jacoby.github.io/2021/11/16/i-will-replace-you-with-a-small-shell-script.html</ref>. Although you ''could'' write the Python example more concisely, it is a real-world example of code that I found that does the same thing as 5 lines of BASH that I wrote.
 
[[BASH]] code to concatenate [[certbot]] certificates:<syntaxhighlight lang="bash">
#!/bin/bash
 
# $RENEWED_DOMAINS will contain a space-delimited list of renewed
# certificate domains (for example, "example.com www.example.com"
# loop through a dynamic list of directories in 'live'
# for SITE in $(find /etc/letsencrypt/live -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
# $RENEWED_LINEAGE will contain the live subdirectory
for SITE in $RENEWED_DOMAINS
do
        # move to correct let's encrypt directory
        cd $RENEWED_LINEAGE
        # cat files to make combined .pem for haproxy
        cat fullchain.pem privkey.pem > /etc/haproxy/certs/$SITE.pem
done
# reload haproxy
# systemctl reload haproxy
</syntaxhighlight>Python code to concatenate certbot certificates:<syntaxhighlight lang="python3">
#!/usr/bin/env python3
 
import os
import re
import sys
 
# Certbot sets an environment variable RENEWED_LINEAGE, which points to the
# path of the renewed certificate. We use that path to determine and find
# the files for the currently renewed certificated
lineage=os.environ.get('RENEWED_LINEAGE')
 
# If nothing renewed, exit
if not lineage:
    sys.exit()
 
# From the linage, we strip the 'domain name', which is the last part
# of the path.
result = re.match(r'.*/live/(.+)$', lineage)
 
# If we can not recognize the path, we exit with 1
if not result:
    sys.exit(1)
 
# Extract the domain name
domain = result.group(1)
 
# Define a path for HAproxy where you want to write the .pem file.
deploy_path="/etc/haproxy/ssl/" + domain + ".pem"
 
# The source files can be found in below paths, constructed with the lineage
# path
source_key = lineage + "/privkey.pem"
source_chain = lineage + "/fullchain.pem"
 
# HAproxy requires to combine the key and chain in one .pem file
with open(deploy_path, "w") as deploy, \
        open(source_key, "r") as key, \
        open(source_chain, "r") as chain:
    deploy.write(key.read())
    deploy.write(chain.read())
 
# Here you can add your service reload command. Which will be executed after
# every renewal, which is fine if you only have a few domains.
 
# Alternative is to add the reload to the --post-hook. In that case it is only
# run once after all renewals. That would be the use-case if you have a large
# number of different certificates served by HAproxy.
</syntaxhighlight>{{References}}


[[Category:Bash]]
[[Category:Bash]]
[[Category:System Administration]]
[[Category:System Administration]]
[[Category:Files]]
[[Category:Files]]