1. 1

    IIRC there’s either no limit (or a very long limit) to the ‘subject’ field specified in the relevant RFC for ‘emails’, so you could (probably) put your entire message in the subject!

    1. 1

      Oh it’s possible. My uncle does this and it drives me nuts!

    1. 9

      By the time I was ready to ditch the host operating system and install Plan 9 on bare hardware, my desire for the modern web experience had ebbed to an all time low.

      As much as I love Plan 9, not having a modern web browser is a non-starter. Too much of the world depends on that: I need to be able to read the news, video conference, consult reference materials, do my banking, order pizza, and so on…

      1. 14

        Ultimately, the magic of Plan 9 is you can write a file server for the seamless/grubhub API, and then all you need to do is mount your pizza place of choice, and kick off the delivery with

        echo cheese > /n/pizza

        1. 8

          Except someone needs to do the work, which is mostly a waste of time, not to mention api’s for services like that are far from stable.

          1. 6

            Mostly a waste of time?

            Once it’s done, it’s usually done for years. And APIs are getting better, not worse, generally.

            cat /n/pizza/toppings; echo 'pepperoni' >> /n/pizza/order; echo 'done' >> /n/pizza/order

            Actually sounds like a super simple way to order pizza. From here a pretty simple UI could be made.

            My issue with plan 9/9front is as sl says: it just isn’t for me at this time, and maybe never. But the ideas it has, can and have been, used in other places.

            When it comes to powerful text editing, the tools I use work across practically any OS I touch. And to me its those tools that are powerful as long as they remain small (so that they can maintainable, and portable).

            1. 3

              My point is the comment is making it seem unrealistically easy in terms of effort for reward to use ‘magic’ to implement a 9p filesystem for ordering pizza.

              1. 2

                I was joking :). Writing a 9p server isn’t exactly easy, but, to extend indirection’s comment, it would be kind of nice to grep and echo for pizza

                1. 3

                  Writing a 9p server is an hour or so of work, at least with lib9p. Maybe less. Getting it to order pizza is harder.

              2. 2

                Yeah, that sounds like a super simple way to order pizza because its skipping most of the things involved in ordering pizza, like choosing the pizza place and giving them your address and payment info.

                1. 2

                  All that stuff could be done once.

                  echo '1 north pole' > /n/pizza/address; cat /n/pizza/places; echo 'pizzapizza' >> /n/pizza/place; echo 'mypaymentinfosoateuhstaoheus' > /n/pizza/payment or whatever.

                  Not saying the same can’t be done with other systems.

                2. 0

                  username checks out

            2. 5

              i lean hard on my smartphone for some of this. so far, for the same reasons as you, i’ve been unable to avoid either one or the other (using a modern web browser on my pc or carrying a smartphone). what i can do is limit the number of vectors exposing me to harm, as often and as thoroughly as possible. it’s fair to say that if the modern web is a hard requirement then living in plan 9 may not be for you. realize, though, that in spite of the many enticements being offered, it is still perfectly possible to get a lot of computing done without directly transmitting data to surveillance companies.*

              (* sins of the telecom carriers sadly acknowledged.)

              1. 3

                You could do it the other way around and run Plan 9 in a browser, according to this little project:


                1. 2

                  There’s vmx or vnc for when you really need it.

                  1. 1

                    As it mentions, you can install another OS in a vm and run a browser there.

                    1. 1

                      I know, I just hate switching work environments back and forth…

                      1. 2

                        A modern browser is itself a VM.

                        1. 10

                          The browser is the new Emacs

                          1. 14

                            No, the browser is successful.

                            1. 8

                              M-x oh-snap

                              1. 3

                                I actually try this, you know…

                  1. 10

                    C++ is the only language I’ve worked in, where it is completely normal (and often preferred such as in the games industry) to completely ignore the standard library. It’s also the only language I’ve worked in where the standard library is not written in anything resembling a style you’d find nearly any normal code base written in.

                    We have a committee with 300+ members. It seems that essentially every member has a feature or two that they’d like to get into the language, and many have several.

                    This is the problem. I have to study this language constantly to stay up-to-date and know all the in’s and outs of bizarre rules and in that time I could have done so much more with my life.

                    If we are not careful, C++ can still fail

                    It’s already failing. I believe it’s pretty much dead on the table, with current projects keeping it alive. I take a lot of flak from a lot of people I know for still being the “C++” person. I love the power of the language, but can’t honestly recommend anyone use it over any other one. C++11 was a great step in the right direction, but the burden of more and more complexity from pet features while not helping me deal with the real complexity issues (#include’s, build systems, usability issues with the standard library) has me really struggling to keep wanting to put in the effort.

                    1. 2

                      C++ is the only language I’ve worked in, where it is completely normal (and often preferred such as in the games industry) to completely ignore the standard library. It’s also the only language I’ve worked in where the standard library is not written in anything resembling a style you’d find nearly any normal code base written in.

                      This hasn’t been my experience. Other than one place with ancient code that avoided templates, I’ve never worked on a C++ codebase that didn’t use the standard library. I think a few high profile talks at C++ cons popularized the idea that the STL was too slow, but for most use cases it’s not really true.

                      1. 10

                        Gamedev reasons to not use the STL include:

                        • Doesn’t play nice with custom allocators
                        • Insanely bad APIs. C++ committee people love the everything is an iterator model but it’s just crap to use
                        • Insanely bad compile times
                        • Insanely bad debug perf
                        • Insanely bad compile error messages
                        • Insane algorithm choices. e.g. C++11 RNG stuff
                        • Insane implementations
                        • Spec enforced bad runtime perf. e.g. std::unordered_map is specced to be bad so all the implementations have to be bad too
                        • Certain older consoles had “variable” implementation quality
                        • It’s like hundreds to low thousands lines of mostly trivial code to write your own array/string/hashtable/etc so why not
                        1. 1

                          Doesn’t play nice with custom allocators

                          What do you mean by this? Every single collection type in the STL supports custom allocators– what about their implementation is bad?

                          1. 7

                            STL custom allocators are passed in as template parameters so they can’t have state, which makes them pretty much unusable.

                            1. 4

                              It also means containers with the same types but different allocators are different types.

                          2. 0

                            I’m not arguing that it’s a great library, just that most projects don’t bother replacing it. It might be standard practice for game developers, but they’re a small niche.

                            1. 1

                              It might be standard practice for game developers, but they’re a small niche.

                              I’d bet even money that the majority of C++ software written these days is game code.

                              1. 2

                                I’m skeptical, but would be interested to see data if you have any.

                                My own evidence is anecdotal - I’ve worked primarily with C++ for 15 years and have never worked on or even been contacted/recruited by any game companies. I haven’t even worked with anybody (to my knowledge) who’s worked on game software. On the other hand I haven’t been seeking them out, so who knows.

                                1. 1

                                  Steam has a pretty good list of programs.

                                  1. 1

                                    Do they have any numbers on how many of those games are based on Unity? The game logic in Unity-based games is written in C#, so I’m sure that would make up a good chunk of new games code written nowadays.

                          3. 8

                            In my experience, its’ a good point.

                            • When I was at EA, we started using C++ but not STL. This was a long time ago, but I’m NOT sure STL got significantly better for the console use case.
                            • At Google string is not std::string. I think the interfaces were slightly different, although I don’t remember the details. This is tens of millions of lines of code linking against a non-standard string, and it’s one of the most common types in the codebase, etc. As far as I remember, the reason was performance and maybe code bloat.
                            • The fish shell is one of the only shells written in C++, but it explicitly avoids STL. Oil might go that way too. (Right now the only thing we use is std::vector as an implementation detail)

                            STL also uses exceptions, and many codebases compile with those off, e.g. all of Google’s.

                            There was a recent cppcon talk by Herb Sutter which noted that the exceptions issue essentially bifurcates the language. And he surveyed the audience and I think at least half of people had SOME restriction on exceptions in their company.

                            When you write all of your function signatures differently, you’re almost writing in a different language. Those two styles of code are cumbersome to bridge.

                            1. 1

                              STL also uses exceptions, and many codebases compile with those off, e.g. all of Google’s.

                              I’ve never worked with C++ - what does it mean to have exceptions off? You’ve disabled the possibility of raising / catching exceptions in the language? I’ve never worked with a language where something like that would be possible. Is error handling then done through a (result, maybeErr) = someFunction(); if (maybeErr) { ...} pattern?

                              And why do people turn exceptions off? Does it mean you then can’t use any library that uses exceptions (like STL)? Doesn’t that mean lots of libraries can’t be used together with lots of other libraries?

                              1. 3

                                Yes, C++ compilers generally allow you to turn off exception support. All the code that deals with handling exceptions is discarded; any code that attempts to raise an exception instead crashes the entire process.

                                One reason people turn off exceptions is for efficiency - when an exception is thrown, all the local variables allocated up to that point must be deallocated, which means there’s a bunch of bookkeeping that always has to be done, even though it’s almost never used.

                                Another reason people turn off exceptions is for simplicity. If you’re trying to understand what a given function does, you have to understand the control-flow pattern, and more complex patterns are more difficult to understand (Cyclomatic complexity). Exceptions add an extra “exception thrown” edge to the control-flow graph from every line of code to the exit, which makes things much more complex. In garbage-collected languages like Python or Java it’s not as big a deal, because most things will get cleaned up eventually anyway, but C++ expects you to care about more details.

                                Generally C++ code designed for “no exceptions” mode will make functions return error-codes, yes. Libraries that use exceptions aren’t incompatible - they just crash the process when something goes wrong, as I said - but if a project is designed for “no exceptions” then it would probably prefer libraries designed under the same constraint.

                                1. 1

                                  Thanks :)

                                2. 3

                                  Yes if you turn it off then the code just crashes. So you don’t want to use throw anywhere.

                                  C and C++ error handling strategies are very diverse

                                  • errno style which is a global / thread local
                                  • boolean result and out params: bool myfunc(const Input& i1, const Input& i2, Output* o1, Output* i2)
                                  • Result/Maybe objects (this is more “modern C++” that depends on templates)
                                  • Exceptions

                                  People turn off exceptions for at least two reasons:

                                  1. Because they don’t like non-local reasoning. Classic article: https://www.joelonsoftware.com/2003/10/13/13/
                                  2. Because exceptions bloat the generated code with exceptions tables. This may matter on embedded systems.

                                  To answer the other questions:

                                  1. You can use STL, but not in a way that throws an exception. For example, you have to check that a key is in a map first, rather than let it raise an exception.
                                  2. Yes, lots of libraries can’t be used with others. But many codebases are written in a style where exceptions can be “local”. Most big codebases are a hybrid of C and C++, e.g. Firefox, Chrome, I assume Photoshop. So they use C error handling in some places but C++ in others. For example OpenSSL and sqlite are all C, and use C style error handling, but they’re often linked into C++ programs.
                                  1. 1

                                    So, C and C++ error handling strategies are really very different.

                                    errno style is only used in C, and in practice is rare outside of the standard library and other very very old libraries. It’s not used at all in C++.

                                    Return codes are used in both, sure. That’s the bog-standard way to handle errors in C or in C-style C++. Result/maybe objects and exceptions obviously don’t exist in C unless you count setjump/longjmp, which is reasonably obscure and doesn’t give you any opportunity to clean up state.

                                    Result/maybe objects are not used in C++. You might be thinking of Rust. std::optional<T> isn’t a maybe<T> or a result<T, E>, it’s not for error handling but an alternative to using pointers to represent optional values. There’s nothing modern about something like this, it doesn’t ‘depend on templates’ any more than any other C++ code. Templates in C++ are pervasive. There’s nothing unusual or weird about writing or using templates. They’re as much a normal working part of the language as functions are.

                                    1. 1

                                      OK what I meant is “result/error parameterized by type”, of which there are many variations, e.g.


                                      It’s more modern than error codes :) And more modern than exceptions.

                                      1. 0

                                        No, it’s not ‘more modern’ than either. It’s unperformant crap used by people terrified of exceptions because they don’t understand them.

                                    2. 1

                                      Thanks :)

                                3. 4

                                  Bloomberg LP uses their own standard library, called the bde.

                                  I think when Bloomberg adopted C++, there were some licensing issues surrounding the std library, so they implemented their own. I could be wrong about this – I’m not fully sure what the rationale was, but I don’t think the stl was dropped for the sake of speed. I’m a little bummed the README doesn’t have a rationale.

                                  The library is largely compatible with the standard library, with a few key differences. The most important difference is that allocators are passed around as pointers, instead of being specified in templates. Here’s an example of the bsl::vector constructor taking an allocator, here’s an example of a Bloomberg specific bdlcc::Queue taking an allocator. All allocators implement this interface.

                                  The bde also has a unique coding style (which I personally find extremely readable), and an almost absurd amount of comments. It’s one of the few C++ libraries that I think is easier to read than it was to write – which is quite an accomplishment!

                                  The library also has tons of goodies in it, but isn’t as featureful as boost. My personal favorite the use of traits to encode/decode objects to arbitrary formats, in a fashion similar to rust’s serde.

                              1. 19
                                jtm@x1c ~ % ls
                                TODO acme aux bin doc down git go mail mnt music rom www xen 
                                • acme - additional scripts for acme.
                                • aux - synonymous with “junk”.
                                • doc - images, documents, slides, etc.
                                • down - downloads
                                • mail - emails in Maildir format.
                                • www - source code for a static site.
                                • xen - vm configurations.

                                I’ve been meaning to add a cron job to delete anything in down that’s older than three days.. that folder tends to blow up.

                                To keep junk from accumulating in $HOME, I use a shell function called “t” that will automatically cd to a temporary scratch space, so I don’t have to think about cleaning up junk that I don’t intend to keep. I use this almost every day.

                                function t {
                                  cd $(mktemp -d /tmp/$1.XXXX)
                                1. 15

                                  Instead of a t function, I have a ~/tmp folder.

                                  Because ~/tmp is persistent, I end up with stuff in there that I’m afraid to delete, so I made a ~/tmp/tmp for stuff that’s actually temporary.

                                  Because ~/tmp/tmp is persistent, I occasionally end up with stuff in there that I'm afraid to delete. I once just needed a temp folder quickly, but didn't feel like stuff in ~/tmp was safe to delete yet, so I made a ~/tmp/tmp/tmp`.

                                  I should add that t function to my rc.

                                  1. 3

                                    Ooo, I love the t function. I make temp dirs for stuff all the time. So simple, but really helpful - thanks for sharing!

                                    1. 2

                                      I have a similar j function which creates a named (default: junk) subdirectory in the current directory and cds to it. There is a corresponding jjj function which is essentially rm -fr junk. Because the new directory is under the current directory, I find it is easier to reference the original directory with .. rather than using "$OLDPWD".

                                    1. 16

                                      To add to this list, sometimes the same currency is represented in different units in different markets. For example, US bonds are often quoted in fractions, rather than decimals.

                                      US mortgages typically use 32nd’s (or 64th’s) when priced. Tickers will usually represent the price as something like “99-24”, which means 99 and 24/32, or 99.75. Note that this isn’t a price in dollars, but rather a percent of the face value of the bond, which is typically (but not always!) $1000. In other words, 99-24 = $997.50.

                                      There’s also a “+” suffix that means “add 1/64th”, so “99-24+” is $997.65625.

                                      US treasuries also use 32nds, but US municipals use decimal. However, municipals are quoted in percentages as well, so a muni quoted at 99.56 is 99.56% of face value.

                                      There’s also language that comes with it – 1/32 is a “tick”, and 1/100th of 1% is a “bip” (slang for “basis point”).

                                      Different countries have different conventions for the bond market, but the US seems pretty keen on using ticks for some reason. It’s often rumored that confusing units are kept around to frighten lay people, and keep the market an exclusive and elitist place. I don’t necessarily agree, but it’s an amusing idea nonetheless :).

                                      1. 1

                                        For example, US bonds are often quoted in fractions, rather than decimals.

                                        I think this is pretty common in finance, as it helps avoiding to use cross currency valuations.

                                      1. 16

                                        When working with large codebases, I often feel that bad decisions will never be remedied, and legacy code will float around until the end of time.

                                        The work that Firefox devs have done to make this change is incredible. It really restores my faith that large projects can be refactored well if the vision is strong

                                        1. 8

                                          You need both vision and commitment. Often the vision exists but the commitment does not. This is understandable because large long running refactorings are wildly unpredictable in length and come with a high amount of risk. Deciding when it’s time to take the risk is a very difficult call.

                                        1. 2

                                          I like that the readme is a man page!

                                          1. 14

                                            In my opinion, if a C or C++ formatter reorders #includes, that is a bug in the formatter. Remember, #include is just a simple copy-paste macro. Reordering #includes changes the source code in a non-trivial way. Over the years I have seen many headers - even in standard headers that shipped with the compiler - that had a variety of side-effects and even caused errors if the order were any different. Just a simple using namespace std; in your header makes reordering deadly. Or forward declarations. Should you write your headers like that? No. Does it happen in the wild? Yes, all the time.

                                            1. 7

                                              We had some wonderful build issues related to this at my last job.

                                              There was a super old header that #defined a few key constants. This header was usually #included into just about every compilation unit in the company. Sometimes these constants were needed in a protobuf-like layer, so we would end up generating code with enums that had the same name as the #defined constants.

                                              For example:


                                              #define RED 1
                                              #define BLUE 2


                                              enum { RED = 1, BLUE = 2 };


                                              #include <iostream>
                                              // .. a million headers ..
                                              #include <enterprise_fun_time.hpp>   // includes <old.h>
                                              // ... a million more headers ...
                                              #include <proto.hpp>

                                              Compiling the above gives you an error message that "enum { 1 = 1, 2 = 2 }" is just silly. Fixing this was a trick sometimes; it’s hard to trace where transitive includes are coming from. This kind of issue also more common than I’d like to admit :).

                                              I personally like that clang-format rearranges headers. Though yes, it can break your build (or even change your program!). I think encouraging C/C++ developers to do their best to have order-independent headers is a Good Thing™. I suppose it could always be turned off with the IncludeBlocks option in clang-format.

                                            1. 1

                                              I host my own email on an OpenBSD box hosted on Vultr. It was surprisingly easy to set up! OpenSMTP and spamd ship with OpenBSD, and work great.

                                              Though, I have a kind of wonky setup: I fetch mail by rsyncing files from the server to my local computer. The files are deleted from the server once fetched. Mail is also encrypted on the server with a public key, and decrypted locally with the private key. It’s odd, but I think it’s simple and it works well for me. There are no IMAP or POP3 servers in OpenBSD base, but I’ve considered adding IMAP support with dovecot.

                                              1. 23

                                                I think Josh addresses a good point here: systemd provides features that distributions want, but other init systems are actively calling non-features. That’s a classic culture clash, and it shows in the systemd debates - people hate it or love it (FWIW, I love it). I’m also highly sympathetic to systemd’s approach of shipping a software suite.

                                                Still, it’s always important to have a way out of a component. But the problem here seems to be that the scope of an init system is ill-defined and there’s fundamentally different ideas where the Linux world should move. systemd moves away from the “kernel with rather free userspace on top” model, others don’t agree.

                                                1. 17

                                                  Since systemd is Linux-only, no one who wants to be portable to, say, BSD (which I think includes a lot of people) can depend on its features anyway.

                                                  1. 12

                                                    Which is why I wrote “Linux world” and not “Unix world”.

                                                    systemd has a vision for Linux only and I’m okay with that. It’s culture clashing, I agree.

                                                    1. 6

                                                      What I find so confusing - and please know this comes from a “BSD guy” and a place of admitted ignorance - is that it seems obvious the natural conclusion of these greater processes must be that “Linux” is eventually something closer to a complete operating system (not a bazaar of GNU/Linux distributions). This seems to be explicitly the point.

                                                      Not only am I making no value judgement on that outcome, but I already live in that world of coherent design and personally prefer it. I just find it baffling to watch distributions marching themselves towards it.

                                                      1. 6

                                                        But it does create a monoculture. What if you want to run service x on BSD or Redox or Haiku. A lot of Linux tools can be compiled on those operating systems with a little work, sometimes for free. If we start seeing hard dependencies on systemd, you’re also hurting new-OS development. Your service wont’ be able to run in an Alpine docker container either, or on distributions like Void Linux, or default Gentoo (although Gentoo does have a systemd option; it too is in the mess of supporting both init systems).

                                                        1. 7

                                                          We’ve had wildly divergent Unix and Unix-like systems for years. Haiku and Mac OS have no native X11. BSDs and System V have different init systems, OpenBSD has extended libc for security reasons. Many System V based OSes (looking at you, AIX) take POSIX to malicious compliance levels. What do you think ./configure is supposed to do if not but cope with this reality?

                                                      2. 2

                                                        Has anyone considered or proposed something like systemd’s feature set but portable to more than just linux? Are BSD distros content with SysV-style init?

                                                        1. 11

                                                          A couple of pedantic nits. BSDs aren’t distros. They are each district operating systems that share a common lineage. Some code and ideas are shared back and forth, but the big 3, FreeBSD, NetBSD and OpenBSD diverged in the 90s. 1BSD was released in 1978. FreeBSD and NetBSD forked from 386BSD in 1993. OpenBSD from NetBSD in 1995. So that’s about 15 years, give or take, of BSD before the modern BSDs forked.

                                                          Since then there has been 26 years of separate evolution.

                                                          The BSDs also use BSD init, so it’s different from SysV-style. There is a brief overview here: https://en.m.wikipedia.org/wiki/Init#Research_Unix-style/BSD-style

                                                          1. 2

                                                            I think the answer to that is yes and no. Maybe the closets would be (open) solaris smf. Or maybe GNU Shepherd or runit/daemontools.

                                                            But IMNHO there are no good arguments for the sprawl/feature creep of systemd - and people haven’t tried to copy it, because it’s flawed.

                                                        2. 6

                                                          It’s true that systemd is comparatively featureful, and I’ll extend your notion of shipping a software suite by justifying some of its expansion into other aspects of system management in terms of it unifying a number of different concerns that are pretty coupled in practice.

                                                          But, and because of how this topic often goes, I feel compelled to provide the disclaimer that I mostly find systemd just fine to use on a daily basis: as I see it, the problem, though, isn’t that it moves away from the “free userspace” model, but that its expansion into other areas seems governed more by political than by technical concerns, and with that comes the problem that there’s an incentive to add extra friction to having a way out. I understand that there’s a lot of spurious enmity directed at Poettering, but I think the blatant contempt he’s shown towards maintaining conventions when there’s no cost in doing so or even just sneering at simple bug reports is good evidence that there’s a sort of embattled conqueror’s mindset underlying the project at its highest levels. systemd the software is mostly fine, but the ideological trajectory guiding it really worries me.

                                                          1. 1

                                                            I’m also highly sympathetic to systemd’s approach of shipping a software suite.

                                                            What do you mean here? Bulling all distro maintainers until they are forced to setup your software as default, up to the point of provoking the suicide of people who don’t want to? That’s quite a heavy sarcasm you are using here.

                                                            1. 11

                                                              up to the point of provoking the suicide of people who don’t want to


                                                              1. 24

                                                                How was anyone bullied into running systemd? For Arch Linux this meant we no longer had to maintain initscripts anymore and could rely on systemd service files which are a lot nicer. In the end it saved us work and that’s exactly what systemd tries to be a toolkit for initscripts and related system critical services and now also unifying Linux distro’s.

                                                                1. 0

                                                                  huh? Red Hat and Poettering strongarmed distribution after distribution and stuffed the debian developer ballots. This is all a matter of the public record.

                                                                  1. 10

                                                                    stuffed the debian developer ballots

                                                                    Link? This is the first time I am hearing about it.

                                                                    1. 4

                                                                      I’m also confused, I followed the Debian process, and found it very through and good. The documents coming out of it are still a great reference.

                                                                2. 2

                                                                  I don’t think skade intended to be sarcastic or combative. I personally have some gripes with systemd, but I’m curious about that quote as well.

                                                                  I read the quote as being sympathetic towards a more unified init system. Linux sometimes suffers from having too many options (a reason I like BSD). But I’m not sure if that was the point being made

                                                                  Edit: grammar

                                                                  1. 5

                                                                    I value pieces that are intended to work well together and come from the same team, even if they are separate parts. systemd provides that. systemd has a vision and is also very active in making it happen. I highly respect that.

                                                                    I also have gripes with systemd, but in general like to use it. But as long as no other project with an attitude to move the world away from systemd by being better and also by being better at convincing people, I’ll stick with it.

                                                                  2. 2

                                                                    I interpreted it as having fewer edges where you don’t have control. Similar situations happen with omnibus packages that ship all dependencies and the idea of Docker/containers. It makes it more monolithic, but easier to not have to integrate with every logging system or mail system.

                                                                    If your philosophy of Linux is Legos, you probably feel limited by this. If you philosophy is platform, then this probably frees you. If the constraints are doable, they often prevent subtle mistakes.

                                                                1. 1

                                                                  This saved by butt a few times on an awkward corporate setup that had python in /usr/bin/python (via the distribution package manager) and in /opt/bin/python (via the internal company package manager). The confusion was added to by having multiple versions of python and multiple versions of pip :)