0

Is there a native way (no installing or downloading extra stuff) to read a Unix executable file? I just need to read file to see what's in it and learn what I can use it for.

What I'm really trying to do is learn what the Wireless Diagnostics app does, or rather how it does it. I'm looking to build my own network diagnostics app for my mac. So, I was wanting to read what the Wireless Diagnostics app (location: /System/Library/CoreServices/Applications/Wireless Diagnostics.app) so I found the executable file in the app to see if I could glean anything. That's what I'm looking to get out of this.

  • Thanks. That did it. Is there a re better way (even if I have to download something extra) to get output in a readable format? The strings command outputs code mixed up and every word on its line. – masterninja01 Apr 05 '15 at 21:00
  • objdump will dump an entire program, but I hope you know assembly. gdb is excellent (and if you have source code even better). The way your question reads though you want man pages, but from what you said about @jasonwryan suggests otherwise. – SailorCire Apr 05 '15 at 23:29

2 Answers2

2

If we're talking about a command you can run at the shell prompt, there should be a manual page:

$ man someprogram

If you get back something like No manual entry for foo, you can try GNU info instead:

$ info someprogram

Not all Unix and Unix-like OSes have GNU info on them, but a lot do, and it often gives more information about a given command than the classic man page does.

If you do have info and it doesn't know about the command, you will get something like No menu item 'someprogram' in node '(dir)Top' at the bottom of the screen. Press Q to leave info.

Programs are often owned by some package manager on such systems, and you can also ask the package manager about the program. For the sake of example, we will say that you are interested in someprogram, and you're using a shell with the which command. If the latter isn't available, you can give the path to the executable manually, like /usr/bin/someprogram.

RPM-Based Linuxes (RHEL, Fedora, CentOS...)

First find out which package the program belongs to:

$ rpm -qf `which someprogram`
somepackage-1.2.3-4

Then ask RPM about the package:

$ rpm -qi somepackage
Name      : somepackage
Version   : 1.2.3
Release   : 4
...etc...

DEB-Based Linuxes (Debian, Ubuntu, Mint...)

The pattern is the same as for RPM. First, find out who owns the file:

$ dpkg -S `which someprogram`
somepackage: /usr/bin/someprogram

Then ask about the package itself:

$ dpkg -s somepackage
Package: somepackage
Essential: no
Status: install ok installed
...etc...

Mac OS X

The "native" OS X package manager is somewhat of a hidden OS feature, and it isn't used for everything, but it's worth a try. The pattern is the same as above:

$ pkgutil --file-info `which someprogram`
volume: /
path: /usr/bin/someprogram
pkgid: com.example.bundles.somepackage
pkg-version: 1.2.3
...etc...

Then to get more info about somepackage:

$ pkgutil --pkg-info com.example.bundles.somepackage
$ pkgutil --files com.example.bundles.somepackage
...etc...

If you have installed one of the third-party package managers (Homebrew, MacPorts, or Fink) there are similar commands to get information about packages they own.

If you're dealing with a program installed outside any of these systems, you're probably dealing with a GUI program that is happy to tell you all about itself using internal mechanisms. (About box, Help, etc.)

FreeBSD

Classically, the BSDs haven't used formal package managers, but over the past several years, FreeBSD has been slowly moving toward the use of pkg, a.k.a. PkgNG.

It, too, shares the same usage pattern as the above systems:

$ pkg which `which someprogram`
/usr/bin/someprogram was installed by package somepackage-1.2.3-4
$ pkg info somepackage
somepackage-1.2.3-4
Name :           somepackage
Version :        1.2.3-4
...etc...

Perhaps someday the vast majority of programs installed on a FreeBSD box will be installed via pkg, but not today.

If you have a program installed via Ports, and you can figure out which Port installed it, you can probably get what you want with this:

 $ cd /usr/ports
 $ ls -d */somepackage
 net/somepackage
 $ cat net/somepackage/pkg-descr
Warren Young
  • 72,032
  • 1
    Just FYI, "The $(...) form has superseded backticks for command substitution." http://tldp.org/LDP/abs/html/commandsub.html#CSPARENS – iyrin Apr 05 '15 at 22:23
  • @iyrin: Nonsense. Yes, $(...) is safer in some ways, but to say that it has "superceded" backticks suggests that no one should be using backticks any more, and that they may go away someday. Backticks work just as well in 2015 as they did in 1977, when they were introduced by the original Bourne shell. By all means, use the POSIX shell extension where it makes sense. But don't yell at people when they use backticks in a perfectly sensible way, as above. To do otherwise is to make a religious issue out of a technical one. – Warren Young Apr 05 '15 at 22:28
  • Perhaps "superseded" implies that backticks are deprecated, which they are not. In which case the author should edit that. It still remains good info for users to have in 2015. SORRY I DIDN'T MEAN TO YELL – iyrin Apr 05 '15 at 22:39
  • @iyrin: No, it's not "good info," because it doesn't even give a single example of a case where backticks can fail, where $(...) would succeed. It just baldly states the author's opinion that backticks shouldn't be used any more, which you have parroted. The newer style isn't universally better. It takes twice as many keystrokes, if you count the Shift. If those extra keystrokes don't buy you anything, I say go ahead and continue to use backticks. – Warren Young Apr 05 '15 at 22:48
  • When an experienced member told me about it in a comment here, I found it to be a helpful, often preferred, alternative I've used many times since. I'm just paying it forward. Users can make their own decision. – iyrin Apr 05 '15 at 23:13
  • @iyrin: If you are writing a shell script and aren't certain about what the sub-shell will print, or aren't certain about the context it will be inserted into, you should certainly use $(...) unless you cannot count on a POSIX shell, for some reason. (e.g. embedded Linux, ancient Unix, really early in the boot process, highly portable scripts such as configure, etc.) When you are writing one-off commands as above, backticks are usually fine, and easy to recover from when not fine. (Notice that that's five examples of cases where backticks can/must be used right there, by the way.) – Warren Young Apr 05 '15 at 23:43
2

od -tx1 somefile | less lets you browse a binary (well, hexadecimal) dump of the file. That tells you what's in the file, but of course not in a language readable by normal humans. As a rule, binary executables aren't readable by humans. Even scripts are not readable by most humans.

Here are a few ways you can get information from executables:

  • file myprogram tells you what kind of file it is, e.g. what kind of machine it's for.
  • ./myprogram --help may show you some usage information. But it's a convention which the author of the program may or may not have followed, not an obligation. If ./myprogram --help complains that --help is not a valid option, it might suggest something else, like ./myprogram -h, ./myprogram -help, ./myprogram -?, or running the program with no argument.
  • ldd myprogram, for a dynamically linked executable, tells you what library it loads.
  • strings myprogram lists all the bits of the file that consist of ASCII printable characters. Not all of these are meaningful, because nothing in the file distinguishes meaningful strings from sequences of bytes that coincidentally are printable characters.
  • objdump -d myprogram disassembles the executable, or at least attempts to.

Really, there's no magic way to get the information you seem to expect. It's just not there (unless the output of myprogram --help satisfies you in this particular case). Executables are intended to be read by computers, not by humans.

Warren Young
  • 72,032