Avoiding NPM global install using .bash_profile and “postinstall” script

帅比萌擦擦* 提交于 2019-12-03 21:44:31

I'll go through your 3 questions one by one:

(1) Is this a good idea?

No. Changing user's private files automatically is never a good idea and I see several things that can go horribly wrong if you do that - from a pure annoyance of users having to clean after your programs, to breaking user's system config, to serious security problems.

(2) Are there any projects that do something similar and how?

I hope not. I would never run any program that messes with my .bash_profile - even though I don't have it. I have .profile and .bashrc. And that's another problem for you - are you sure you even know what to edit? What if I use dash which I use sometimes, or zsh or some other shell?

(3) I an not great with bash scripting, how do you write a bash script that can recursively look for node_modules/.bin/gulp if you the dev runs the gulp command from a directory that is within the project but not in the root?

If you are not great with bash scripting then your definitely should not edit user's private files automatically.

What you can do is to provide a certain alias or bash function in a separate file for user's convenience and explain how users can source your file inside of their .bashrc if they want to.

But never make that decision for them. If anything goes wrong this can even have legal consequences for you.

Examples of functions

Answering your questions posted in the comments, I'll add few words on how functions work in Bash.

In my collection of script on GitHub I have few functions with instructions on how to install them and how to use them. Their source code is available here.

An example function in that collection is ok - this is its source code:

ok() {
  # prints OK or ERROR and exit status of previous command
  s=$?
  if [[ $s = 0 ]]; then
    echo OK
  else
    echo ERROR: $s
  fi
}

You can download it (with some other related functions) from:

If you save it as ~/ok-functions then you can either run:

source ~/ok-functions

to have them available in that session, or you can put that line in .profile or .bashrc to have it available after every login. You can use it as if it was a normal command or program like this:

ls /bin; ok
ls /binn; ok

Working example of preventing global install

I wrote a Bash function that does what you are trying to do - it stops global installation of a certain module - called modname in this example. Save it to some file - e.g. to ~/no-global-restricted-module - of course you can change the restricted-module name in n and the warning message in w to suit your needs:

npm() {
  n=restricted-module
  w="Please don't install $n globally - see: http://example.com/"
  i=0
  g=0
  m=0
  for a in "$@"; do
    case $a in
      i|install)
        i=1;;
      -g|--global)
        g=1;;
      $n)
        m=1;;
    esac
  done
  if (( $i == 1 && $g == 1 && $m == 1 )); then
    echo $w >&2
    return 1
  else
    `which npm` "$@"
  fi
}

And then add this line to your ~/.profile or ~/.bashrc:

source ~/no-global-restricted-module

Now when you log in again, or when you open a new terminal window, you can try running this in your command line:

npm install --global restricted-module

You should see a warning and no installation will be started. If you enter some other module name or you omit the --global switch then the installation should proceed as usual. This also works with the shortcuts of i instead of install and -g instead of --global.

This is pretty much what you are trying to do. You can include that function in your documentation with instructions on how to use it. I am hereby releasing it under the terms of the MIT license so you can use it freely. I published it on GitHub with some more options for configuration and information on how to use it, see:

See also

See also this answer for a much better explanation of writing, installing and using Bash functions on the example of playing various sounds in the terminal.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!