5

Context: I wanted to change a setting inside Xfce and found that the way to do it is via xfconf. My first thought was to install the development files for libxfconf (libxfconf-0-dev) and look into the API. I searched to see if there's an example in some open source project and found a library which, instead of using the libxfconf library directly, just executes the library's CLI, xfconf-query and checks if the command was a success to achieve the same result.

I originally thought of this solution as crude, but after giving it further thought, I saw quite a few advantages:

  • It saves time - especially when the API is complicated or poorly documented.
  • It can be done easily from any programming language.
  • It reduces the complexity of your own binary (in both code and compilation).

On the other hand:

  • It's much slower.
  • It can be error-prone (e.g. are the parameters correctly encapsulated and passed?).
  • The user may have a different version of the CLI installed (or worse yet, may have a different binary with the same name).

Keeping this in mind, assuming a library also offers a CLI, when, if ever, is it a good to just call the CLI binary directly, rather than rely on the library calls?

5
  • 1
    Isn't that one of the core principles of the Unix philosophy?
    – A.Rashad
    Aug 27, 2017 at 23:52
  • 2
    @A.Rashad: using CLI apis is surely quite popular in the Linux/Unix world, especially in shell scripts. So at least this shows it is not so error-prone as this question might pretend. However, if one wants to implement a C program using a command line tool and has the alternative of using a library equivalent, I don't think someone would automatically "prefer the CLI approach" in a Unix/Linux environment, and "prefer the lib approach" in a, lets say, Windows environment.
    – Doc Brown
    Aug 28, 2017 at 11:23
  • In missing critical systems I worked on, we would typically use shared memory, IPC and RPC to have processes communicate. In larger systems, we would use an ESB to connect systems via services. It all depends on the scale of the solution
    – A.Rashad
    Aug 28, 2017 at 11:43
  • 1
    @A.Rashad: absolutely, and one could make a broad discussion what options the various technical of interprocess communication would bring. However, I think it is better to stick to what was asked in the question, it is already broad enough as it is now.
    – Doc Brown
    Aug 28, 2017 at 12:36
  • I had a typo earlier (mission) critical not missing! Sorry
    – A.Rashad
    Aug 28, 2017 at 13:01

1 Answer 1

7

As often, it depends. I had to make this kind of decision several times in the past, so I will try to give some general guidelines from that experience.

First, this makes only sense where a program offers a CLI as well as a library interface. If the only "official" interface to a program is the CLI, then you are probably better off using it. However, for cases where both kind of interfaces are available, it depends on several things. Some popular examples, out of my head:

You already mentioned some pros and cons, here are some additional aspects to consider:

  1. The quality of the APIs (CLI vs. lib API)

  2. "in-process" execution (lib) vs. "out-of-process" execution (CLI)

  3. The kind of communication required between the using application and the called program / library.

  4. licensing issues (for example, if the library/program you want to use is under GPL)

  5. testability

  6. Other factors like already existing code, the target environment, security related issues, know-how issues, and so on.

For some of these programs/libs, the library API and the CLI do not offer exactly the same featureset, so that is most probably the first thing to look for.

IMHO the major differences between a CLI program vs a lib are resulting from the out-of-process/in-process communication. This forces a very different communication approach between your program and the lib/program, and also different error handling. "out-of-process" has the advantage of making the called program run in better isolation and gives one the possibility to handle program crashes in a more graceful way. In case of GPL software, it has also the advantage of avoiding the viral aspects of GPL.

As you already mentioned, running a separate process will typically be slower than calling a library directly. However, if this is really significant for a specific use case depends, well, heavily on the specific use case. For some cases, using out-of-process execution can make things runner faster, because of the implicit parallel execution.

The communication options with a CLI program are typically much more restricted, especially when the command line parameters (and maybe some files) are the only way of feeding input into the program, and a return code and output files are the only way of of getting output. That makes using a library often mandatory when one needs a more complex communication protocol. If the use case requires it to work with data structures returned from lib calls and pass them back to other library functions, or if the use case needs callbacks, a CLI won't make much sense. For example, libxslt/libsml gives you the possibility to acess the whole DOM of an XML file and work with it in your own program. No idea how that should be done in a comparable fashion just using the command line client xsltproc. However, if you just need an xslt script to be executed on some input xml file, and get the resulting file for further processing, using xsltproc may be sufficient or even preferable.

About testability: with ImageMagick I made the experience it may be easier to test singular CLI commands in isolation and then let a program call the CLI then with exactly the same parameters. On the other hand, using a CLI database client to test some SQLs and then using that SQLs directly in conjunction with a DB API in form of a lib has often served me well, too.

About your "user may have a different version of the CLI installed" argument: well, this could also be the case when using a lib, I guess? For libs, the environment may provide you with automatic version checking out-of-the-box, however, lots of CLI programs allow you to ask them for a version number, too, so gives one at least an opportunity to make some sanity checks beforehand.

So, in short, there is no general "right" or "wrong" or "best" solution here, you need to look at the individual case and make a decision for your specific case.

1
  • Re: In Process vs Out of Process - We were using a third party DLL from a Windows C# application (with DLLImport). Because it was so impractical to unload just the DLL from the app domain, some things (hangs) required restarting the entire application. (I understand that there is a way to do this but at the time it appeared to be overly complex and messy.) This was just a DLL, with no CLI. A separate exe wrapper around the DLL, which was then started by the main application as a separate process and communicated with it via named pipes gave us the convenient control over it that was needed. Aug 31, 2017 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.