Shutdown Proxmox VM using CLI

SSH into the Proxmox host and run: qm shutdown <VMID> This sends an ACPI shutdown signal to the guest OS for a graceful shutdown. To find the VM ID: qm list If the VM doesn’t respond to the shutdown signal, force it: qm stop <VMID> qm stop is equivalent to pulling the power cable. Use it only when qm shutdown hangs.

17 October 2023 · 1 min · 61 words · Shafiq Alibhai

How to count words in a PDF from the Linux command line

The simplest approach: pdftotext input.pdf - | wc -w pdftotext is in the poppler-utils package (sudo apt install poppler-utils or sudo yum install poppler-utils). The - sends output to stdout instead of a file. Other options pdfminer: pdf2txt.py input.pdf | wc -w Install with pip install pdfminer.six. Python with PyPDF2: import PyPDF2 with open("input.pdf", "rb") as f: reader = PyPDF2.PdfReader(f) total = sum(len(page.extract_text().split()) for page in reader.pages) print(total) Note: PyPDF2’s PdfFileReader and getPage() are deprecated in newer versions — use PdfReader and index into reader.pages instead. ...

5 September 2023 · 1 min · 132 words · Shafiq Alibhai

How to avoid other pods from being scheduled on your node in Kubernetes

Taints on nodes repel pods. Tolerations on pods let them ignore specific taints. Together they give you control over scheduling. Taint effects NoSchedule — pods without a matching toleration won’t be scheduled on the node. PreferNoSchedule — the scheduler avoids the node but will use it if there’s nowhere else. NoExecute — pods without a matching toleration are evicted and won’t be rescheduled there. Applying a taint kubectl taint nodes node1 type=db:NoSchedule This prevents any pod from being scheduled on node1 unless it has a toleration for type=db. ...

13 July 2023 · 1 min · 149 words · Shafiq Alibhai

Remove lines matching a pattern from files recursively in Linux

find . -name "*.md" -type f -exec sed -i '/pattern/d' {} \; This one-liner walks the directory tree, finds every .md file, and strips out any line that matches the given pattern. The sed -i edits each file in place, and the {} gets swapped out for whatever path find hands it. Breaking it down find . -name "*.md" -type f does the walking. The -type f bit is important – without it, find would also match directories and pass them to sed, which would error out. The -exec ... \; at the end runs the command for each file individually. ...

27 April 2023 · 2 min · 299 words · Shafiq Alibhai

Installing PhantomJS on Ubuntu 22.10

PhantomJS is a headless browser, which means it runs without a graphical interface and lets you automate web page interactions through scripting. I needed it for some automated testing at work and ran into a few things worth writing down, mostly because half the guides out there are either outdated or assume you already know what you’re doing. The version we’re installing is 2.1.1, which is the last release. The project has been unmaintained since 2017, but it still does what it needs to do for basic scraping and screenshot tasks. ...

27 April 2023 · 1 min · 199 words · Shafiq Alibhai

Deleting files by content match in Linux

There are two ways to interpret this question, and the answer changes completely depending on which one you mean. Deleting files by filename If you want to nuke every file whose name contains a particular string: find . -type f -name '*string*' -delete The -type f keeps it from touching directories. The -delete flag removes whatever find matches. Simple enough. A word of caution: test without -delete first. Run the same command and replace it with -print to see what would actually get deleted. I’ve lost files to typos in wildcard patterns more times than I care to admit. ...

27 April 2023 · 2 min · 305 words · Shafiq Alibhai

Grabbing an SSL certificate from a remote server

There are moments when you need to inspect the certificate a remote server is presenting – maybe it’s expired and you’re trying to work out why things are breaking, or maybe you need the raw certificate data for some other reason and don’t have access to the server’s configuration. The quickest way is with openssl s_client: openssl s_client -connect {HOSTNAME}:{PORT} -showcerts Replace {HOSTNAME} with the server address and {PORT} with the port (usually 443 for HTTPS). The -showcerts flag dumps the full certificate chain rather than just the leaf certificate. ...

15 June 2021 · 1 min · 149 words · Shafiq Alibhai

Count directories in the current folder with a one-liner

A common question that comes up when you’re first getting comfortable with the command line: how do you count just the directories in your current folder? The quick answer is: ls -1 | wc -l This pipes a one-per-line listing of everything in the current directory into wc -l, which counts lines. Simple enough. But there’s a catch. This counts everything – files, symlinks, hidden items, the lot. If you only want directories, you need to be a bit more selective. ...

14 July 2020 · 1 min · 188 words · Shafiq Alibhai

Count files in a directory with a one-liner

Another quick command line question: how do you count just the files in a directory, excluding subdirectories and other stuff? The classic answer: ls -l . | egrep -c '^-' This lists everything in long format (ls -l), then counts lines that start with a hyphen – which is how ls marks regular files. Directories show up as d, symlinks as l, and so on, so the regex filters them out. It works, but it’s a bit of a trick and relies on understanding ls output format. A more straightforward approach uses find: ...

14 July 2020 · 2 min · 213 words · Shafiq Alibhai

Fix casks with `depends_on` that reference pre-Mavericks

If you get an error like Error: Cask 'hex-fiend-beta' definition is invalid: invalid 'depends_on macos' value: ":lion", where hex-fiend-beta can be any cask name and :lion any macOS release name, run the following command: /usr/bin/find "$(brew --prefix)/Caskroom/"*'/.metadata' -type f -name '*.rb' -print0 | /usr/bin/xargs -0 /usr/bin/perl -i -pe 's/depends_on macos: \[.*?\]//gsm;s/depends_on macos: .*//g' This strips out all depends_on macos references from installed casks. It’s a blunt instrument – you’re editing Homebrew’s metadata files directly – but it gets things working again. ...

18 May 2020 · 1 min · 110 words · Shafiq Alibhai