Is it possible to run npm script that is not executable? - node.js

I am having a problem with my PaaS. When I deploy my node application my scripts are losing their executable bit. I know in the long run my PaaS needs to fix this, but for now I am looking for a workaround.
I read this in the npm scripts documentation (https://docs.npmjs.com/misc/scripts#exiting):
Scripts are run by passing the line as a script argument to sh.
If I understand correctly the script run like this:
sh myscript.sh
If that is true the script does not need to be executable. However if I run an npm script that is not executable.
npm run myscript
I get this:
sh: bin/myscript.sh: Permission denied
Is there a way around this?
EDIT: here is my simple script:
#!/bin/bash
echo Hello World

Try in your package.json a line like this:
"myscript": "sh bin/myscript.sh"
I think the fine print here is that npm is running your command as sh -c 'line from package.json here', which if that is just a file path, sh will require it to be executable. However, without -c, sh will run a non-executable shell script without error.
sh -c 'bin/myscript.sh'
sh: bin/myscript.sh: Permission denied
sh -c 'sh bin/myscript.sh'
myscript is running

Related

Execute two node commands from a bash file as Docker CMD

I am trying to run a nodejs app from a file named start.sh.
I am using this file because I want to execute two process in a serial way as a CMD in a Dockerfile.
This is the content:
#!/bin/sh
node /get-secrets.mjs -c /secrets-config.json -t /.env.production
npm run start -p 8000
As you can notice, I want to perform two things:
First execute the get-secrets.mjs file, that is a small script that internally uses commander.js two read the flags -c and -t (--config and --target respectively). These flags receive strings arguments to locate files.
The second command is just the start for my node js app.
I have no idea how should I write this file, because those commands work on my machine but in the container it seems my format is wrong.
This is the problem so far:
How should I pass the arguments to the mjs script?
If someone else fine this useful, I solved my issue using this:
FROM node:16.14-alpine
# Dependencies that my script needs
RUN npm i -g #aws-sdk/client-secrets-manager#3.121.0 commander#9.3.0
# Folder for my source code
WORKDIR /app
# SOME OTHER COMMANDS
# ...
# In this folder I have the start.sh and the get-secrets.mjs files
COPY ${SOURCE_PATH}/server-helpers/* ./
# This was required since I am working on windows
RUN sed -i -e 's/\r$//' start.sh
RUN chmod +x start.sh
ENTRYPOINT ["/app/start.sh" ]

Running a script to connect through ssh then run npm install pm2 results in: 'npm: command not found'

I'm running this command from my local machine:
ssh -tt -i "pem.pem" ec2-user#ec2-IPADDRESS.compute-1.amazonaws.com "sudo su -c 'cd /dir/;npm install pm2'"
It connects, operates as a super users, cds to dir and attempts to run the command but returns that npm is not a command recognized by the system.
However, when I connect "manually" i.e.
ssh -i "pem.pem" ec2-user#ec2-IPADDRESS.compute-1.amazonaws.com
sudo su
cd /dir
npm install pm2
it works.
npm is installed under root and the system can see it.
ssh -tt -i "pem.pem" ec2-user#ec2-IPADDRESS.compute-1.amazonaws.com "sudo su -c 'cd /dir/;whoami'"
and
ssh -i "pem.pem" ec2-user#ec2-IPADDRESS.compute-1.amazonaws.com
sudo su
cd /dir
whoami
both return "root"
Why can't the npm command be found when running on top of an ssh?
When you login, you create an interactive shell, which typically will read a couple of files, including /etc/profile, $HOME/.profile, and $HOME/.bashrc in the case of bash.
Any of these files can add extra elements (paths) to the PATH variable, which affects which commands can be found.
When you run the command line directly, no such initialisation takes place, and the value of $PATH may be limited to just /bin:/usr/bin.
Next there is sudo, which may or may not import the value of PATH when looking for commands.
Solution
Best you can do is find out where npm is installed, and use its full PATH.

How to change shell of npm install

I'm trying to npm install a package in Ubuntu 16.04. I get the following error message:
npm install
...
> padlock#2.0.0-beta.1 bower-install /home/kent/Documents/padlock
> pushd app && bower install && popd app
sh: 1: pushd: not found
My Research
According to /bin/sh: pushd: not found, my problem is clearly that npm install is trying to execute pushd with sh not bash.
However, my default shell is already bash
$ env | grep SHELL
SHELL=/bin/bash
$ echo $SHELL
/bin/bash
$ echo $0
bash
and I'm not sure what I need to change. I've also tried adding SHELL=/bin/bash before I execute pushd app but I have had no luck with that either.
npm-scripts run using sh
Scripts are run by passing the line as a script argument to sh
https://docs.npmjs.com/misc/scripts#exiting
If you want to use bash for your scripts make the script
bash -c 'pushd app && bower install && popd'
Update: As of November 2017 you can now set script-shell in .npmrc to use a custom shell
I was able to work around a similar situation by creating this file in my project directory:
$ cat .npmrc
script-shell=/bin/bash
FWIW, the issue I stumbled upon was relying on bash-specific "curly-brace expansion" commands in the postinstall section of the package.json file for the offending module. That malformed command works in MacOS, but not Linux.

My sh codes don't work, help needed

I'm learning to work with linux but it isn't working out
Script 1, did work until I updated opensuse:
#!/bin/bash
useradd Test
passwd Test123
mkhomedir_helper Test
(It now says that all these commands don't exist)
Script 2, I can only get into my MySql console and he doesn't execute everything:
#!/bin/bash
mysql -u root -ppassword
sleep 3
CREATE USER 'Test'#'localhost' IDENTIFIED BY 'password'
I would really appreciate some help here since I'm new to linux
Run following cmd:
echo $PATH
Output should be list some paths as below
/Usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
If not then run below command:
export PATH="/Usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"
Now try running above script-1, if it still gives same error, then you are missing some packages, install 'pam' package which contains mkhomedir_helper binaries, so run following command to install pam.
zypper in pam
Script 2, to run mysql query from command line or as a shell script you need to use '-e' option, change the script 2 as below:
#!/bin/bash
mysql -u root -ppassword -e 'CREATE USER "Test"#"localhost" IDENTIFIED BY "password"'

Having trouble writing my first bash script

ok I am writing my first bash script in ubuntu 10.04.
The file is on my desktop: /home/myuser/Desktop
The file is called hello-world
The file contains:
#!/bin/bash
echo "Hello World"
I open a command line and run:
/home/myuser/Desktop/hello-world
It tells me permition is denied. So I run it again with sudo, it asks me for my password, I type it in, hit return.
I get this output.
sudo:
/home/myuser/Desktop/hello-world:
command not found
What am I doing wrong?
Your script probably is not set to be executable. Try:
chmod u+x /home/myuser/Desktop/hello-world
If your script is called test.sh then do the following...
$ chmod +x test.sh
followed by
$ ./test.sh
chmod +x hello-world
You need to mark the script as executable. Run chmod +x hello-world to add the executable bit.
You can also do:
sh /home/myuser/Desktop/hello-world
which will execute the script without it needing to be set as executable.

Resources