View Single Post
Old 24th October 2020, 19:06   #901  |  Link
Mosu
MKVToolNix author
 
Mosu's Avatar
 
Join Date: Sep 2002
Location: Braunschweig, Germany
Posts: 4,281
Quote:
Originally Posted by Atak_Snajpera View Post
Why do we have to use that @ symbol?
I know you're venting, and I get why. Nevertheless, let me take that opportunity to write a bit about command-line design.

Why do we have to use "--help" instead of "-?"? Why do we have to use "--sync" instead of "-sync"? Why do we have to put file-specific options in front of the file they apply to instead of after them?

Because there isn't a Single Right Way to design command line options. There are a lot of different schemes out there, and have been over the years. I do try to be somewhat consistent, I do try to follow existing conventions where that makes sense (e.g. "--help" is the standard for GNU tools and tools for Linux/Unix in general instead of "-?" which is more at home in the Windows world). But often enough there is no precedent for what I'm implementing. So I invent stuff.

As for a precedent I couldn't really find one. On Linux/Unix we usually don't have a problem with command-line options as the Unix shells have always had a high length limit (usually 32 KB). On top of that Linux/Unix shells don't have that character set dichotomy that Windows has with its ANSI & OEM character sets & that cmd.exe was basically a piece of shit you couldn't rely on, especially when trying to deal with Unicode file names & Unicode text input & output. Therefore Linux/Unix tools didn't really need & didn't really have options for reading additional command-line options from a file. If you wanted to put those into a file, you did that and used syntax such as "program `cat file-with-options.txt`". However, the backticks `…` are interpreted by the shell before the program is executed, meaning that the shell's limit of 32 KB applied. cmd.exe didn't have such a thing such as backticks.

Nowadays cmd.exe is… better. Somewhat.

Anyway, the point was that there wasn't a established, commonly-used precedence for such an option I could follow. I did think about using something like "--options" instead of "@", but "--options" would have been way to general for my taste. I though about "--command-line-options", but that's rather long. So I thought about other ways to signal what to do with the file, and I already had my own precedence of prefixing file names with "+" for signalling that the file should be appended. @ has the nice property of not being a special character in shells (bash, zsh, cmd.exe etc.) and doesn't have to be escaped unlike other candidates such as ` * ! < { [ Back in the day I also favored having short option names over longer but explicitly named ones, an stance I've changed opinions on since (see below).

Next time you cannot get something to work may I kindly suggest you ask a bit earlier before getting all worked up about something that isn't all that important in the grand scheme of things? We are happy to help.

Addendum: here are a couple of things I might design differently if I ever reworked the whole command line interface, in no particular order:
  • Options would not be file-specific anymore. Instead they would always take a file ID and, if appropriate, a track id. That way they would be position-independent. This is one of the things that's still confusing users to this day.
  • I would use JSON instead of XML (chapter & tag files). Back when I designed that stuff, JSON hadn't been invented yet; neither had YAML. Nowadays JSON is ubiquitous, and there are very good libraries available for all languages, making the choice easy. (An aside: I prefer YAML to JSON for the simple reason that you cannot have comments in JSON files, but you can in YAML. Unfortunately working with YAML is much more error-prone due to it using whitespace as structure and interpreting a lot of bare words such as "yes" as special data types instead of strings. What makes YAML totally unsuitable for MKVToolNix, though, is the language support. There are way fewer YAML libraries out there, mostly due to YAML not only being a data serialization format, but an object serialization format — making it much more complicated and much more dangerous to implement fully, especially for languages without introspection support such as C++. End of long aside.)
  • I would use full-fledged option names instead of single-character file name prefixes, e.g. "--append filename.ext" instead of "+filename.ext", and yes, "--command-line-options filename.ext" instead of "@filename.ext". Would make the whole experience much more regular, easier to understand and easier to implement — especially given that some of those special chars such as ( ) have to be escaped in a lot of shells.
  • I would follow GNU-style long option names more closely. This means that you would have single-dash short options followed by a space followed by an argument ("-s 1:150ms") or long, double-dash options followed by either an equals or a space followed by an argument ("--sync=1:150ms" or "--sync 1:150ms"). My tools mostly follow this, but they don't support the variant with the equals. In the Linux/Unix world having long option names with equals is very common, though, and MKVToolNix would have fit in better.
  • At the moment command-line applications that follow a command-suite model are very popular, e.g. "docker container rm abc47110815" and "docker image pull ubuntu/focal". They follow the pattern "application-name [--optional-global-options] topic [--optional-topic-specific-options] [optional-topic-arguments]". I would probably merge all four existing command line apps (mkvmerge, mkvinfo, mkvextract, mkvpropedit) in a single command-suite style application called… "mkvtoolnix" or "mtx" or so, and expose the functionality of each of the four original tools as topics, e.g. "mtx merge -o out.mkv in.mp4" and "mtx info file.mkv". This wouldn't have that much of an advantage for end users, though; it's more a matter of style or taste. I would imagine that it would lead to a more consistent interface between those four tools, though, solely by forcing me to always think about the command-line interfaces of all applications when dealing with one part of it. So it might have a positive impact on after all.
  • I would be more consistent with naming options and making clearer what they apply to (e.g. using "--audio-tracks" instead of "--atracks" even though the latter is shorter).
  • I would treat chapter files like regular source files. The net effect would be that I wouldn't need all those chapter-specific command-line options (e.g. users could simply use "--sync" on a chapter source file instead of "--chapter-sync"). Again, that would make the interface more regular & easier to use (more regular = fewer exceptions/edge cases = less to remember for the end user = easier to use). Actually, this is kind of on my TODO list as it would be possible to retrofit this functionality while keeping the existing options (--chapters, --chapter-charset, --chapter-sync…) for backwards compatibility.
  • File & track would be consistent, both within the same tool (e.g. all track IDs for all file types would always start at 0, no matter the source container) as well as between tools (e.g. mkvpropedit would certainly not start numbering tracks at 1 whereas mkvmerge & mkvextract start at 0). That's one point I regret the most as it's caused so much confusion for users.

The power of hindsight… It sure would have been nice to have all that insight before I started work on the project, all those nearly 18 years ago.
__________________
Latest MKVToolNix is v83.0

If I ever ask you to upload something, please use my file server.
Mosu is offline   Reply With Quote