 In this video we're going to talk about three standard command line utilities that are available on pretty much any GNU Linux distribution. And those standard utilities are CMP, which is the compare program, DIFF, which is the DIFF program to see the differences between two files. Compare and DIFF are actually very similar, but they do have some differences we need to talk about. I'm also going to talk about the TPUT command, which allows you to add some text formatting and coloring to terminal output. And the reason I want to talk about these three programs today is because I used these three standard command line programs in a script that I was writing here recently, because I had this real world problem. So I maintain DTOS, I maintain a repository of software for DTOS. And if I go into this directory on my system here, this is a list of all the packages that I build and maintain for DTOS. And in each one of these folders, every folder is a program name. If I go into the folder, every folder has a package built for that particular program. Now obviously these programs, they get updated every now and then, right? There'll be a new version of Aura, for example, or did you mean, or I think I build Paru, right? Paru sees frequent updates. And every time there's an update, I have to go grab their latest package build or I'd have to manually edit the package builds that I have locally on my system to reflect the new version number. I may have to change the check sums. There's a hash that's also a part of many of these package builds. And it's a pain. Every time there's a new version of any of these packages, I have to change the package build. I have to manually go and get the new package build and make those changes. Well, why don't I automate that process? Now I got to thinking, you know, I'm going to start just, I wanted to write a script that would pull down the latest package build for each of these packages. If Arch has it in their repositories, either in the standard repositories or in the AUR, pull down the package build for name of directory, for example, you know, there'll be a package. And if that package build that you downloaded from Arch and the AUR, if it's different than the one that's hosted locally here on my system, it means the one that's locally on my system is probably out of date. So overwrite my package builds with the one you're downloading, you know, run a diff on it. So actually what we're going to do, actually I think I use compareCMP, but either one would work compare or diff. And let me show you this in action. So I'm going to CD into this DTOS dash package build directory, which hosts all my package builds. And I've got several scripts here that help me build DTOS, kind of automate a lot of this process. And one of the scripts I have is this one here, this package build check. So what this does, if I give it this capital A flag, it's going to go and go through the x8664 folder. And through every single package that I have in that folder, it's going to search the Arch repositories for that package name. And if it exists, it's going to download the package build. And then it's going to compare my package build with the package build it's downloading. If they don't match, it's going to overwrite the one I have with the newer one, which is be the one it downloaded. Let me show you this. And you can see, got some fancy coloring that's going to be done with TPUT, which we'll talk about in a minute. But you can see most of the DTOS dash packages are custom config files that are not found on the Arch repositories. So I've just got that doing nothing. It just spits out package build not available, you know, package is not in the AR. But the ones that are, you can see, it grabbed the latest package build for the did you mean package, but package build has not changed, meaning the one it downloaded from the AUR is also the same as the one locally on my system. So I don't need to rebuild that package. So this really helps me identify which packages need to be rebuilt. If the package build has changed, I'll get some blue coloring and it'll say package build for program name has changed instead of has not changed. But it doesn't look like any of them have changed. So I don't have to rebuild any packages right now for DTOS. So basically what the script is doing, let me CD back into my home directory and clear the screen. The script is essentially running a diff on two files. For example, if I did this diff command here, diff takes two files, right? You run diff on two files. It compares two files and tells you the differences. So if I run diff on my .bashrc and then I had this test directory that also has a bashrc in it, which is actually just a copy of my bashrc. So they're exactly the same. I know these two files are exactly the same. So if I just run that command, I get no output because they're the exact same file. But what if I ran a diff on bashrc and then the other file would be test slash, I don't know what else is in the directory, file one, you know, I get all kinds of stuff. It gives me the actual diff. You can see, these are all the lines that were in my bashrc that are not in file one. And at the end, I think it gave me a line that was in file one that wasn't in the bashrc. There was a lot of output because those files are not even remotely the same file. Now the compare command is very similar. I could compare my .bashrc with the test bashrc as well. Just like diff, I get no output. But what if I did a compare on my .bashrc and then that test slash file one, which are, again, very, very different. You can see now I get output. It says that the bashrc and the test file one differ. And where do they differ? They differ by one line one. So the very first byte. Now you're probably thinking, well, cmp and diff, they seem very, very similar. And they are. The difference is the output that they display. Diff is designed to be run on plain text files. Anything that is written in plain text, diff is perfect because it's going to give you the lines that are different. Right? It's going to give you the diff. Right? cmp, though, doesn't necessarily have to be run on plain text files. You can because I just did it. But cmp is really nice when comparing binaries because it's not going to give you any output. There's really no output that is worth looking at in a binary, right? But cmp, if you ran it on two binary files, right? It's just going to tell you if there's a single byte different or not. That's all it tells you. It's either going to be, yes, these two binaries are the same or they're not. And how you would use either cmp or diff in scripting, they both work very similarly is you'd probably use an if statement. And I probably should switch over to bash if I'm going to script because I was in the fish shell and these if statements, they don't look quite the same in fish syntax. So in your scripting, if you need to compare two files, what you need to do is you need to run a if statement. So if cmp and then file one, file two, or if diff, file one, file two. Let's start with cmp. So if cmp and we'll compare my dot bash rc and then test slash bash rc. We're going to if these two files are exactly the same, then echo true. Else echo false. And then let's end the if statement with fi. And if I run that, you can see true is returned. And now if I compare my dot bash rc with test slash file one, which are totally different, you can see now I get false as the output. Actually, I also get the output from the cmp command as far as they differ at byte one, line one. Now, I probably wouldn't want that. I either want true or false returned. Well, we'd have to suppress the output from cmp. So cmp does have a dash dash quiet flag that you could give it. And now the only thing I get is the echo part from the if statement. So the cmp output is suppressed. And if instead of compare, I wanted to use diff, I could do diff. Diff doesn't have a quiet flag, so I'd have to get rid of that. But it would work the same except I'm going to get output with diff, right? I got all the lines that were different. What I probably do is just redirect the output from diff to slash diff slash null. And then when I run it, I still get false because the two files, they differ, right? But I no longer get all those lines that were different. And if I up arrow and I go back and change this to two files that are definitely the same, now I get true. Now, between cmp and diff, diff is the more powerful command as far as it's got a lot more options. And the reason is diff, again, is designed to be run on text files. So it's got a lot of options on how it displays the text, right? Where cmp, again, that's mostly you'd use it for binaries where you really, there's nothing you want to see as far as the differences in those binaries, you really just want to know they're either the same or they're not. So let's do diff. And I'm going to use some flags here. So I'm going to do a diff on these two files that are exactly the same. And if I do diff dash y, this is the side by side view. If I hit enter, we get the two files side by side. Now, these files are exactly the same. So now if I do the diff dash y and then two files that are not the same, you can see they look very different because all of this that's in the first file, none of that is in the second file. And earlier I mentioned that diff didn't have a quiet flag. Actually, it does. It has a dash q flag where it doesn't give you the output of the lines. It still outputs whether the files are different. So this is just the files either differ or they don't differ, but it's still does output something. So I really couldn't use it in that if statement earlier because I don't even want this line, right? So I would still probably have to send that to the slash diff slash null just to get rid of that if I was doing if then else statement with echoing true or false. Now, probably the way you're used to seeing diffs done is a diff dash u, which is a unified view. So it's one file, right? But it's a combination of the two files. And it tells you where the lines differ. So if I do this on dot bash or see and test slash file one, for example, you can see all the minuses in front of all these lines that were in the first file, they don't exist in the second file. And then the plus symbol, that's the one that does exist in the second file. And this is how you typically see diff files like if those of you that are used to patching suckless software like DWM, D menu, the ST terminal, you're used to seeing these kind of diff files where you've got the lines with the pluses and minuses. That's telling you exactly, hey, these lines, they need to be removed or these lines need to be added, the plus and minuses. One other thing about diff, how it differs from CMP is diff can actually be used recursively, meaning it can be used on directories. For example, let me compare the DTOS dash package build directory that I have on my system with the DTOS dash core repo directory that I have on my system. And it's going to spend out a bunch of information. It's going to tell me that the files exist in either directory or they exist in both directory. You can see only exist in this directory, for example, and that gives me the name of the file. So pretty cool stuff with diff, also pretty cool stuff with CMP. Now that script that I was showing you earlier, let me open up that in Emacs. So that was the script here that I called package build check. And all it does is, this function here is the one I showed you earlier. It CDs into that x8664 folder with all of my locally hosted package builds. And then while it's inside that directory, it runs a paru dash capital G, which is a flag that paru has that allows you to download package builds from any package that's hosted on the arch repos or in the AUR. So I download the package build from AUR and then I compare it to the one that's already in that folder that's already on my system, or the package builds the same or not. And what I do is I use CMP to compare. I could use diff, they would both work exactly the same in this case. And if the package builds have not changed, meaning the one I downloaded is exactly the same as the one locally on my system, I just echo checking the package build colon package build has not changed. Now if they do differ, I echo checking the package build, package build has changed. And then you'll notice I've got these variables here, bold three, bold four. So these are different variables that I assigned up here at the top using the tput command. tput allows you to add colors to a terminal output. So let me zoom in here. If I do tput, set af and this will set foreground color. And I'm going to set that to color three because my terminal color scheme, your terminal color scheme has 16 colors probably defined for it, right? So I'm going to do tput set af three and then I'm going to add and echo high. And you can see high is now this orange color because that is color three of my color scheme or my terminal color scheme. If I set af four using tput, you can see now I get that blue coloring. So that really is all there is to tput is I'm setting that foreground color. If I wanted to set a background color, I could do that as well. I believe it's set AB. Yeah, and now the background color is blue, but it's kind of hard to read there. Other than that, the only other tput command you really need to know is tput sgr zero. What does that do? It resets everything just in case there's any weird side effects left behind from you playing around with setting foreground and background colors. Eventually you want to just reset everything to the default terminal colors the way things should be displayed. So tput space sgr zero. And if you want to see the commands for some of this stuff with cmp or diff or with tput, do you have the tldr package installed on your system? It's kind of like a really simple cheat sheet. It's like a man page, but it's a really short man page. It just shows you the most useful commands with cmp in this case. I do a tldr on diff, get some some diff stuff here. Again, pretty much everything you need to know with diff displayed there and about what seven commands? I did a tldr on tput, really not much to tput and you can see the most useful stuff is this right here tput and then either set AF for foreground or set AB for background and then whatever color code you want to set that to. And then resetting all the terminal attributes is tput sgr zero. So that is all I'm using in this package build check is I'm comparing these two files and then I'm just displaying some information. I'm echoing, yeah, the file is the same or no, the file is not the same. And then I'm coloring some stuff with tput. So I get back into the folder that has that script. They clear the screen. And once again, just to verify that all of that works, I'm going to run the script again. So that's just a little bit of what you can do with cmp, diff and tput. And you also got to see a little bit of what I'm doing with some of my scripting as far as trying to automate me being able to maintain DTOS because it's really challenging because there's so much work involved. You got to automate the process. You've got to script and you've got to automate the process. If you want to especially maintain a repository of software. It's one of the things I really if you see somebody that maintains a Linux distribution or you see people that maybe just contribute free time. There's a lot of package maintainers out there, people that are maintaining packages for Arch and Devian or whatever it happens to be. And if you come across any of these people in real life that are freely giving their time to help maintain packages and some distributions, repositories, give those people a hug, they deserve it. Now, before I go, I need to thank a few special people. I need to thank the producers of this episode. And of course, I'm talking about Gabe James Maxim, a homie's too bald, Matt Mimic, Mitchell Paul, Roy West, Armoredragon, Bech, Potato Chuck, Commander Henry, George Lee, Methos, Nate Erion, Paul P. Sartre and Vador. Probably take Realities for a Less Red Profit, Rollin' Tools, Devler, Willie and Zinnabit. These guys, they're my highest tiered patrons over on Patreon. They are the producers of this episode. I also need to thank each and every one of these fine ladies and gentlemen. All these names you're seeing on the screen right now. These are all my supporters over on Patreon. Without these guys, I wouldn't be able to do what I do. If you like my work and want to see more videos about Linux and free and open source software, including these shell utilities, subscribe to DistroTube over on Patreon. All right, guys. Peace.