So here are some details:
od - This is octal dump. As the name suggests, by default it dumps a file as octal. However, it is a general file analyzer that you can change bases and other representations in. For instance, say I don't want to mess with a graphical hex editor. I want to see 64 bytes at offset 0x1000 in a file, I can do this:
Code: Select all
% od -Ax -txC -j 0x1000 -N 64 smb3.nes
0001000 b0 a1 4c 1b d0 a9 08 9d 61 06 a9 1f 9d 18 05 60
0001010 20 e7 d5 4c 4d d0 20 01 d6 4c 1b d0 20 18 d6 4c
0001020 1b d0 20 f0 d5 4c 1b d0 20 e7 d5 a5 ce d0 35 bd
0001030 eb 06 f0 21 fe eb 06 c9 90 d0 03 4c 32 d4 a9 04
0001040
Or I want to see what characters might be in a string:
Code: Select all
% od -Ax -c -j 0x3FFF0 -N 64 smb3.nes
003fff0 377 377 377 S U P E R M A R I O 3
0040000 \0 \0 l V 003 \0 001 \f 001 - 206 364 0 377 225 367
0040010 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0040030
I've got that information faster than it takes to open a start menu, click on an icon, and wait for the graphical stuff to bootstrap, not to mention the overhead of starting a graphical environment in the first place. My computers don't even start X by default anymore, I issue a "startx" if I need graphics for anything but I mostly just sit in GNU screen at terminals.
This is a UNIX utility too so it uses stdin and stdout, you can use it in pipelines. This is where stuff like sed then really shines, you can dock the addresses with -An and then you just get raw bytes to pipe into other tools, I can do something like this to get a series of bytes printed one hex value per line, capitalized. First, the raw input:
Code: Select all
% od -An -txC -j 0x3FFF3 -N 10 smb3.nes
53 55 50 45 52 20 4d 41 52 49
But I want one per line, so:
Code: Select all
% od -An -txC -j 0x3FFF3 -N 10 smb3.nes | tr "[a-z]" "[A-Z]" | sed -e "/^$/d" -e "s/^[^0-9A-F]*//g" -e "s/\([0-9A-F]*\) */\1\n/g"
53
55
50
45
52
20
4D
41
52
49
So pulled in tr, which does very basic character conversions (iconv is more sophisticated), then sed to snip out unneeded bits and then the result are the bytes I wanted in the format I wanted. I can then put this in a script and I forever have a mechanism to print a file in hex one byte per line, useful for then adding to a script that, for example, adds ".byte $" to the front of each line to rapidly convert a binary BLOB into .byte directives to feed into ca65.
This is just one example, of course, but I am kicking myself for all the years I didn't bother to learn this stuff. I've managed to eliminate most graphical applications from my process. Heck, even my graphics tools only require a desktop for presentation. I've got a couple sets of pipelines for converting CHR graphics to bitmaps and PNGs and you only need a desktop if you want to *view* the results. All the generation is just CLI programs, one for each concern (e.g. decode a display list into a nametable, convert a CHR into a common image format, assemble a set of images in a grid based on a nametable description, etc.) so I can do any one of the jobs independently if need be without having to care about the other parts. One key benefit to this tool-based approach is dependability. If you scope each tool narrowly and it does one job, then you can operate in confidence that your nametable generator will always work, doesn't matter how you hack up your CHR converter under the hood, the nametable generator simply consumes its results, it doesn't care about internal implementation. Doing things this way insulates unrelated items from each others' implementation details.
Lastly just because it's one of my irks, dd has a bit of a reputation as strictly a disk copying tool. That's all I ever see people cite it in the context of, but dd is not by definition a disk tool, however much people have tried to make the names disk dumper and disk duplicator stick. The name dd derives from "data definition", a card type in the IBM mainframe operating systems that sets up I/O properties of an operation. Since it derives from an old IBM JCL command, that is why it doesn't use typical UNIX arguments but the whole if= of= etc. this is directly from the old job card syntax. Ultimately dd is just a read-write loop from standard input (or if=) to standard output (or of=). You are given control over the starting position of the read, starting position of the write, and the size of the data to copy, as well as a couple of configuration parameters like "notrunc". I mention "notrunc" because with this feature, dd can operate as a simple patcher. You simply say pass a "skip" to say where in the first file you want to copy the patch from, "count" to say how much to copy (both can be omitted if you're copying all of input), "seek" can then be used to say where in the output file to print the new bytes, and then "conv=notrunc" tells dd to *not* use its default behavior of truncating anything in the destination file after the write. This is just again an example, but that I came up with this via my own trial and error rather than this being established practice in the world for streaming a set of bytes over an offset in a file is shocking to me. It is just about the lowest level way to do that sort of thing without writing a program, indeed most of my scripts turn to dd for things I would use read, write, and lseek to do in C.
So yeah, my advice there is don't pooh pooh UNIX utilities as old or esoteric, they allow you to get *so* much done without once having to touch a mouse or rely on any amount of graphical toolkits.