Files
hpr-knowledge-base/hpr_transcripts/hpr2736.txt
Lee Hanken 7c8efd2228 Initial commit: HPR Knowledge Base MCP Server
- MCP server with stdio transport for local use
- Search episodes, transcripts, hosts, and series
- 4,511 episodes with metadata and transcripts
- Data loader with in-memory JSON storage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-26 10:54:13 +00:00

271 lines
16 KiB
Plaintext

Episode: 2736
Title: HPR2736: Response to show 2720
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2736/hpr2736.mp3
Transcribed: 2025-10-19 16:00:14
---
This is HPR episode 2,736 entitled Reponster Show 2,720 and is part of the series Bash
Cripting.
It is hosted by Dave Morris and is about 18 minutes long and carries an explicit flag.
The summary is some suggestions on how to improve a Bash Cript.
This episode of HBR is brought to you by An Honesthost.com.
At 15% discount on all shared hosting with the offer code HPR15, that's HPR15.
Better web hosting that's honest and fair at An Honesthost.com.
Hello everybody, this is Dave Morris, welcome to Hacker Public Radio.
Today I'm doing a show that I've not done before.
I'm responding to show number 2,720.
This was a show that Ken Fallon did on January 4th and he was talking about a script which
he'd written to download YouTube channels using RSS feeds.
He offered up a Bash script called youtuberss.bash and talked about how it worked and stuff.
And I thought it was very cool.
I've not done this sort of thing myself but I've sort of fiddled around in that particular
region of things.
So it was quite an interesting lesson I found.
So one of the things I do, which is, I don't know if it's good or bad, might be irritating,
is when I see a Bash script I just find myself looking at it with an eye to rewriting stuff
to make it fit better with the stuff that I've been learning while I've been doing this
series of Bash tips that I do.
I think it's a useful thing to do because it's a way of understanding a script.
It's also sometimes people have much better ideas than ones I was going to offer so I
can learn from them.
And it's also useful when it comes to my own scripts.
I've been writing Bash scripts since the 1990s when we had Bash on Unix systems, I'll
trick so I think it was.
So I'm always looking at my own scripts thinking that was really, that's not a good way of
doing it.
I could improve on that.
So I do a lot, do this a lot, okay?
So looking at Ken's script, it's needless to say I saw some areas for improvement and
I thought that making a show about it would be a way of sharing my thoughts about them.
As we're quite low on shows as I'm putting this together, it's also motivated me to do
a show rather than just write comments to Ken's show or send him an email.
So in general, there are a few uses of wild loops in the script that I would be inclined
to rewrite.
And I'll probably say a little bit more about them a little bit later.
But since the script works as it stands, then that's, it's more advisory than me saying
you really should change that.
When I did was I grabbed the YouTube RSS script and put it into VIM.
And there I have a tool called Shell Check, which is being run by another tool, which
whose purpose is to examine bash scripts I've mentioned this before.
And quite a lot of issues were thrown up.
Most of them are quite trivial, but a few are a bit more serious.
And in order to give you some sort of taste of what this might mean or how this would
be represented, I did a screenshot of an editor session, which I've turned into an image
for this show.
There's a thumbnail, which you can click in the long notes, which will take you to a picture
of part of the file and the error messages that Shell Check is producing, errors and warnings
really.
So it's worth maybe looking at a few of these.
I could spend ages going into this in depth, but even I'm not that keen to do that.
I'm sure you're not keen to listen to it.
The first one is on line 34.
And Shell Check doesn't like the expression, open, double quotes, dollar, open curly bracket,
log file, close curly bracket, close, double quotes, dot, dollar, open parenthesis, slash
bin, slash date, etc, close parenthesis.
What Ken's doing here is taking the log file variable and he's concatenating that with
a full stop, a dot and the result of running the date command with date stamp, year, month,
day, a minute, second type thing.
Great.
I do these sort of things a lot.
It's really good.
But Shell Check doesn't like it because it's working on the principle that what comes back
from date could have spaces in it, in which case the shell will pass the whole string and
will say, oh, there's spaces in there, it might well split it up in whatever context
it's been used.
If you adjust it to put the quotes around the whole expression, then it's perfectly happy.
Now, think about Shell Check.
I'm going to do a show on it a bit later in any way, but it will be saying things.
It's very clever, but it's not as clever as a human, and so it will be reporting things
that just look like they could be a problem, but aren't necessarily this is not in itself
a problem.
Personally, I fix these things in my own scripts just to shut the thing up.
Second point online is 3948.
There are instances of the read command, but it doesn't use the hyphen R option.
Hyphen R is recommended because it prevents any backslash characters and input from being
mangled.
Not quite clear exactly what happens, but anyway, it's recommendation.
And so Shell Check moans about that.
I found just going and adding them into my copy of it made it stop.
Also, on the same two lines, 3948, there are these wild loops.
And the wild loops are of the form, something or other that generates data, a series of commands
or something, piped into wild.
And then after that, the body of the loop and done.
I've said this in some of my other shows on the bash tips heading.
But if you do that, it means anything that you change in the loop body, that any variables
that you change in the loop body don't get passed back to the main script.
And that can catch you out.
So in general, I avoid loops of that structure.
Now, in tense case, there's no need to do that.
But I'm just saying, and I normally turn them into a wild, read, et cetera, body of the
loop.
And then at the end of the loop, I put a process substitution, which generates the data
for the loop.
And in that case, you're not going to have issues with passing variables back to the main script.
Now, it's not a serious issue with Ken's script.
It's just a thing that's probably a wise habit to get into of not writing loops in a way
that they can't catch you out as they stand in Ken's script that it's not an issue.
But if he were to come back to it at a later stage and put up some some accumulator in there
or something or other happening in there, they wants to use in the main script, he would find
it wouldn't work as the thing structured now.
So it's a good idea just again that I think you may think differently, but it's just about
some hints and tips that I found on my journey.
So I wanted to look at three instances of things I would be inclined to rewrite.
Again, I've referred to them by line within the script as it was downloaded from Ken's show 2720.
First off, it's line 50.
And in this line, Ken's doing an if test.
And the test is in square brackets.
And it consists of, in quotes, the command substitution which uses grep.
And it's comparing a variable called this video with log file.
Log file is a file.
It's going to look for the string this video in the actual file.
If it gets anything back, well whatever it gets back will be counted in a pipe with the WC command, WC minus L,
which will count the number of lines that come back.
So there could be no lines or it could be one or possibly more.
And this expression is then compared with zero.
So this is very convoluted, I would say.
I think I did cover some of these sorts of things in some of the other shows I've done.
What I would do with this is I would rewrite it.
And my rewrite would be to use the fact that grep will return a true false value.
And you can tell it not to return any lines of data.
It's normally grep will pull stuff out of the file that matches whatever you're trying to match.
If there are matches, that is.
That's what Ken was trying to do and he was counting the number that came back.
So you would do if, and you don't need to put this in square brackets at all,
you would use an exclamation mark to invert the result of the grep test.
Then it would be grep space hyphen q.
That means that grep is to not producing output q for quiet.
Then the variable this video in quotes and then the log file name.
So if this video is found in the log file, then the not in front of it,
the exclamation mark will turn that to false if it's not found.
Then it will return true.
So in other words, it's doing the same thing.
It's looking to see if the string in this video is not in the log file.
I think Ken was trying to determine whether he'd already downloaded something on it.
Moving on to line 68, we've got another rather convoluted if statement.
And this particular case is complicated by the fact that the downloadable version of the script
has got a variable called skipCrap, which I think is a great name.
And it's been commented out.
So you're going to find that shell check is going to say,
well, there's no variable called scriptCrap.
How come you're doing using this?
And I imagine it's sort of waving its hands in the air and running around in circles.
But that's just me.
I reenabled this.
This was Ken's plan to check for certain nonsense in the titles of videos coming back.
So what he has here is in double square brackets.
He has a not an exclamation mark.
Then he's got hyphen Z and then the variable skipCrap in quotes and curly brackets.
Because sometimes that's a good idea.
So he's checking to see if the skipCrap variable is zero length.
And then he's reversing the answer.
So he's actually asking to whether it's non-zero length.
So that's a bit, that's a bit back to front, I reckon.
I replaced that with hyphen N and then the variable skipCrap.
That's then followed by double ampersand.
So he's looking for the case where skipCrap is not empty, actively,
because otherwise it's not pointing to the rest of the test.
And the original uses another command substitution dollar open parenthesis.
And here Ken echoes the title, which will be the title of the current video that is being processed,
into eGrep with the hyphen i option,
are using variable skipCrap as the string to compare.
So what that's doing is it's telling eGrep to compare the contents of skipCrap,
which is a regular expression.
It's a bunch of words separated by vertical bars, but it's the type that eGrep can handle.
And comparing that with what comes in on its standard input, which is title,
which has been echoed to it by the previous command in the pipeline.
Then if anything comes from, what everything that comes from back from that is counted with a WC minus L.
And on the completion, the closed parenthesis, the completion of that,
command substitution, there will be a value, which is being compared with zero.
It's a not equal to zero.
So I did a first rewrite, which again echoed title to a changed eGrep,
because shell check was complaining about it.
There is no eGrep command officially anymore.
eGrep is actually Grep space hyphen capital E.
So if you do them, if you look up the man page for eGrep,
you don't find one, it takes you to the Grep one.
Then I told it to be quiet with a hyphen Q, then Ken's hyphen i,
and then the variable skipCrap.
So I changed that.
And I did it outside of the double square brackets, because it's just a pipeline,
which is doing some stuff, and it's returning a true or false value.
So this is a somewhat more tidy.
Well, it's certainly not doing the thing where you're getting Grep to output some stuff,
and then you're counting it, and then you're comparing the result,
the number of lines with a value, because we just want a true or false out of it.
I've already said some of this, so I'll repeat myself.
And so this actually works.
Then I thought, well, really, what's happening here is the string in title
is being compared with the string in skipCrap using a regular expression match,
except it's using Grep or eGrep to do it.
So I thought, what would happen if you use bash as regular expressions?
So I wrote a version of this with everything in the double square brackets
which you have to do for regular expressions, and replaced the pipeline
with dollar title equals tilde dollar skipCrap.
I'm not a great one for the curly brackets, or I don't need them,
but it's up to you how you do that.
So I did a little test.
I copied Ken's skipCrap string into skipCrap on the command line,
created a title, the best bets in the world.
And then I ran the little test against the test string, the regular expression test.
If it matched, it was to echo Crap, otherwise it echoed non-Crap.
And then Ken was looking for best bets stuff, then it worked.
The downside with that answer is that the test is case-sensitive,
whereas with Grep, the hyphen I made it case-insensitive.
But there's a way around that, and the way is to make sure that both title and skipCrap
are forced to lower case just for the test.
So I gave an example of how you would do that, and that works fine.
If I changed the case of the title in my experiment, I didn't put this in the notes,
then it also matches, it matches whatever the case is.
That was what I was intended to do.
The last one, line 88, Ken has a massively long line,
which starts with cat, and then in double quotes, dollar log file, underscore to-do.
This is the case where he doesn't need the curly brackets,
piped into the YouTube DL command with all of its various arguments.
I shall check complaints about this, and says it's what it calls a useless cat,
and the full message are copied into the notes here.
It says useless cat, consider command less than file, piped into something rather,
or command file piped.instead.
So basically it's saying that you can probably replace where you should be replacing that cat,
because all cat is doing is taking a file, squirting it out on a standard out.
So it's caught by the thing down the pipe on its standard input channel, and then processed.
Now I don't know YouTube DL that well.
I would be surprised if you can't give it a file as its argument,
but in the assumption that you can't, and there's expecting stuff on its input channel,
when you can write the string or using YouTube DL to start with, and with all its arguments,
and then at the end of it, use redirection, a less than sign, and the name of the file that you're going to be reading from.
So that would do it. The other way you can do it, and it's perfectly legal,
but it's the thing I personally never do, is to start the whole line with a less than the name of the file,
and then YouTube DL, et cetera, et cetera, et cetera.
There's a Wikipedia article on the use of cat, and there's also a reference to the page UUC,
which stands for useless use of cat.
There was, I think there was some sort of competition for an award for the most useless use of the cat command in Unix.
I'm not sure if it's still alive, I think it's referenced in the Wikipedia article.
The process of removing useless cats is called demogification,
which I'm told is the Britishism, because we tend to call cats moggies,
and I don't know if that's specifically British or what, but that just amazed me.
So, in conclusion, Bash is powerful, but does some things in a secure way.
We know this very well.
She'll check helpful tool, helps you catch scripting errors,
but it can be a little bit of an irritant when it nags about things.
You can shut it up in various ways.
I'm preparing another HPR episode about its use with VIM,
and the use of it with other checkers.
It's really powerful, so I thought people would be mildly interested in that.
Finally, apologies to Ken if it seemed I was making excessive criticisms of his script.
It was meant to be constructive criticism, of course.
And as I said at the start, Ken was asking for constructive criticisms.
So, there we go.
Anyway, I hope you found that useful, and catch you next time.
Okay, bye.
You've been listening to Heka Public Radio at HekaPublicRadio.org.
We are a community podcast network that releases shows every weekday, Monday through Friday.
Today's show, like all our shows, was contributed by an HPR listener like yourself.
If you ever thought of recording a podcast, then click on our contributing to find out how easy it really is.
Heka Public Radio was founded by the digital dog pound and the Infonomicon Computer Club,
and is part of the binary revolution at binrev.com.
If you have comments on today's show, please email the host directly,
leave a comment on the website or record a follow-up episode yourself.
Unless otherwise stated, today's show is released on the creative comments,
distribution, share a light, 3.0 license.