How would you write this script?

I’ve started putting together my own script to customize my Linux installations just the way I like them. It’s been a long time coming. For the most part it’s easy, since the script is just an apt install with a big list of packages but some software I have to fetch from the web and this is the process/script in question.

I use Reaper for all my audio/music recording & editing. Reaper
But I’m using cut with hard coded values to extract the download link from the html. I think this is not very future proof. What would you folks use to parse this data out in a way that wouldn’t break if a single character changes?

#!/usr/bin/env bash

#Base URL

#Download link relative to Base URL
dlURL=$(curl | grep -i x86_64.tar | cut -c 12-50)

#Bare filename of file
filename=$(cut -c 10-39 <<< $dlURL)

#Download directory

#Installer directory

#echo $baseURL$dlURL

#Base URL plus relative path to file, saved to "download" directory
wget $baseURL$dlURL --directory-prefix=$ddir

#Extract the file
tar -xvf $ddir$filename

#Run the install script

Either of the following will future proof against version changes.

with sed:

dlURL=$(curl | grep -i x86_64.tar | sed -e 's/^.*href="\(files.*.tar.xz\).*/https:\/\/\/\1/')
filename=$(echo $dlURL | sed -e 's/^.*\/\(.*\)/\1/')

with awk:

dlURL=$(curl | grep -i x86_64.tar | awk -F"\"" ' { print ""$2 } ')
filename=$(echo $dlURL | awk -F"/" ' { print $6 } ')

Let me know if any of this needs unpacked for you – or modified.

BTW you just gotta love this regular expression: 's/^.*\/\(.*\)/\1/'


I’d do something like this.

BASH can do almost everything grep, awk and sed can but often considerably faster because BASH is already running and also doesn’t need to be re-run for every parsing operation.

A lot more people know grep, awk and sed though so it can make your script more accessible and it’s good for learning POSIX friendly tools should you need to write something for dash or some other Bourne shell derivative.

#!/usr/bin/env bash

	printf '%s\n' "$2" 1>&2
	[ $1 -gt 0 ] && exit $1

# Set primitives

# Fetch HTML
printf '%s\n' 'Fetching HTML: '"$DownloadUrl"
Html=$(curl --silent "$DownloadUrl")
[[ $? > 0 ]] && Err 1 'Err, download failed for: '"$DownloadUrl"

# Search for link
printf '%s\n' 'Searching HTML for link...'
Re='<a href="([0-9a-Z./-]+_linux_x86_64.tar.xz)">'
if [[ $Html =~ $Re ]]; then
	# Filename=${Href##*/} # <== If you wanted the filename

	# If the Reaper directory exists then remove it
	[[ -d $ReaperDir ]] && rm -rf "$ReaperDir"

	# Make a new Reaper directory
	mkdir -p "$ReaperDir"

	# Download reaper file
	printf '%s\n\n' 'Downloading: '"$BaseUrl/$Href"' to '"$CompressedFilePath"
	wget "$BaseUrl/$Href" -O "$CompressedFilePath"
	[[ $? > 0 ]] && Err 1 'Err, download failed for: '"$BaseUrl/$Href"
	Err 1 'Err, no link found in HTML'

# Extract Reaper
printf '\n%s\n\n' 'Extracting: '"$CompressedFilePath"
tar -xvf "$CompressedFilePath" --directory "$ReaperDir"
[[ $? > 0 ]] && Err 1 'Err, tar extraction failed for: '"$CompressedFilePath"

# Run Reaper
printf '\n%s\n\n' 'Running: '"$ScriptFilePath"
[[ $? > 0 ]] && Err 1 'Err, script failed to run: '"$ScriptFilePath"

Nice error checking. Excellent work.

Feels like Christmas 'round here!

I’m going to put that on a shirt!

I like how different both approaches are. sed or awk make this quite simple as long as you know any regex, which I don’t. The pure BASH method really fascinates me though.

Thank you both very much!

1 Like

If it were me, I’d use Ansible, but shell scripting can handle this just fine as the previous commenters noted.

You can script the curl cmd, but, if a repo is available, you can also script adding that repo to make updates easier.

While awk and sed are awesome tools, they can take some time to learn. If you do decide to use regex, I can highly suggest a good regex testing site:

1 Like