0

I have been using the following command to install the Expo CLI package:

sudo npm install expo-cli --global

The command above works successfully to install that package. However, I'm wondering if moving the --global before the package name would work equally to the command above. So, doing this instead:

sudo npm install --global expo-cli

Environment: Ubuntu 18.04.

I looked online for a reference but did not find one (even though there must be one out there somewhere).

13
  • 1
    Normally flags and arguments can be moved around freely. Just try it :-) Commented Aug 13, 2020 at 12:18
  • @ArtemS.Tashkinov Only if the application in question uses GNUs questionable way of rearranging the command line arguments. Options should otherwise always come before operands.
    – Kusalananda
    Commented Aug 13, 2020 at 12:19
  • @Kusalananda I've been running the GNU software stack for close to 25 years now, so perhaps my worldview is somewhat skewed :-) Commented Aug 13, 2020 at 12:20
  • @ArtemS.Tashkinov I was cautious about just trying it - don't want to mess anything up.
    – knot22
    Commented Aug 13, 2020 at 12:21
  • 1
    @knot22 It's a POSIX guideline: pubs.opengroup.org/onlinepubs/9699919799/basedefs/… In this particular case it also matters whether --global is an option to sudo, to npr or to the install sub-command of npr. Moving the option around freely on the command line would definitely make a difference.
    – Kusalananda
    Commented Aug 13, 2020 at 12:26

1 Answer 1

2

The man page for npm(1) shows:

 Synopsis
      npm <command> [args]

It doesn't say much else, so all we can deduce is that install is the <command> and must come before the [args]. The [args] are expo-cli and --global.

Let's inspect the install command to see if we can get more details. npm-install(1) says:

Synopsis
    ...
    npm install [<@scope>/]<name>
    ...

    aliases: npm i, npm add
    common options: [-P|--save-prod|-D|--save-dev|-O|--save-optional] [-E|--save-exact]
                    [-B|--save-bundle] [--no-save] [--dry-run]

It doesn't say anything about order. This starts to make us think order doesn't matter. If we scroll down we see things like:

The  --tag  argument will apply to all of the specified install targets. 
The -g or --global argument will cause npm to install the package globally 
rather than locally.  See npm help folders.

Ok... so order is never mentioned in the man page, but we see that --tag applies to all targets. They felt that it was important to mention in the man page because if someone tries to install several packages and specify a tag, they might assume that the --tag flag applies only to the package before or after. That's not the case, options apply to everything. If options apply to everything, then order is probably not important.

Note that all of the examples they give in the man page put the package before the flag.

You could try it out:

npm install sax --global expo-cli

Check if they are both installed globally (I bet they are).

If you want to install several packages, some local, some global, then I'd suggest taking the safe approach and using two separate commands because it isn't defined in the documentation and therefore behavior could change.

6
  • 2
    With other commands, the order would matter. The trivial example is any command that provides a --quiet and a --verbose option. Usually, a later option would override any earlier conflicting option. I understood the question as if the give command only was an example.
    – Kusalananda
    Commented Aug 13, 2020 at 13:46
  • You're absolutely right. Especially for conflicting arguments like --quiet --verbose, it's best not to make assumptions when things aren't documented and just avoid relying on undocumented behaviour. In this case, I would guess --verbose takes priority, but I have no reason to be confident in that guess.
    – Stewart
    Commented Aug 13, 2020 at 13:48
  • @Kusalananda But why the order matters in case of --verbose? Can you expand a little bit about "override any earlier conflicting option".
    – ado sar
    Commented Jul 28, 2022 at 17:32
  • @adosar A command may provide an option for becoming quiet, -q, or verbose, -v. The command, when invoked as some-command -q -v would then be expected to be verbose, while some-command -v -q would be expected to be quiet. The later option overrides the earlier conflicting option.
    – Kusalananda
    Commented Jul 28, 2022 at 17:37
  • 1
    @adosar Your example is different because the -f option to tar takes an argument. In the first command, tar is asked to extract the archive called v (tar -x -f v). In the second command, tar is given the option -v while -f is missing its argument (tar -x -v -f). This example is not the same as we have discussed in the comments to this answer. It seems to instead be about a misunderstanding of what -f does when used with the tar command, or possibly about the fact that short options may be written together as a single string.
    – Kusalananda
    Commented Jul 28, 2022 at 17:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .