could someone help me understand the difference between running a node script from terminal using ./ [Filename] versus running it with node [filename] ?
Thank you very much.
It's the same as running bash script using ./[Filename] or bash [Filename].
To use ./[Filename] syntax your node script should:
be runable (chmod +x [Filename])
contain proper header (e.g. #!/usr/bin/node or #!/usr/bin/env node)
There is no requirements for running your script with node [Filename].
Related
Normally in node files I just put
#!/usr/bin/env node
at the top and make it executable to create a file that can be run from a bash terminal. However if I do that in a Typescript file, the compiler says "error TS1001: Unexpected character "#"" and refuses to compile it. So how can I make a shell executable node file with Typescript?
See https://github.com/Microsoft/TypeScript/blob/master/bin/tsc for an example. Basically have a dummy file without the .js extension and just require the actual .js file.
E.g. In file named tsc:
#!/usr/bin/env node
require('./tsc.js')
You were right to report the bug to Microsoft, and they were wrong to close it as wontfix.
Until it is fixed, here's a workaround. Paste the following into a text file and save it as shebangify:
#!/usr/bin/env node
var fs = require('fs');
var path = process.argv[2];
var data = "#!/usr/bin/env node\n\n";
data += fs.readFileSync(path);
fs.writeFileSync(path, data);
(N.B. To keep this answer concise, the code above doesn't have any error-checking or other refinements, so use at your own risk or use this instead. Also, see this SO question for more info about prepending to files.)
Make the file executable with by using a terminal to navigate to the file's directory and executing:
$ chmod +x shebangify
Once you have created a Typescript program (e.g. called myscript.ts) that you wish to compile and turn into a shell script (e.g. called myscript), do so by executing a sequence along these lines in your terminal:
$ tsc --out myscript myscript.ts ; ./shebangify myscript ; chmod +x myscript
If you have TypeScript and ts-node installed globally:
npm install typescript ts-node -g
You can now easily do this with:
#!/usr/bin/env ts-node
console.log('Hello world')
I don't have enough reputation points to post a comment, but I'd just thought it'd be good for everyone to know that I opened a new issue on GitHub since that's what the Typescript devs are using to track things like this: https://github.com/Microsoft/TypeScript/issues/2749 .
In case anyone is still struggling with making it work, the ts file should start with #! node instead of #!/usr/bin/env node, and tsc will take care of the rest.
I've never been able to get ts-node to work, so I finally made my own way to write shell scripts in TypeScript. If there were a package manager for Bash I would make a package, but there isn't, so I just put this script in my path as ts-exec:
#!/usr/bin/env bash
file_to_run="$1"
basename=`basename "$1"`
tmp_prefix=`basename "$BASH_SOURCE"`
TMPDIR=`mktemp -d -t "$tmp_prefix-XXXXXXXXXX"`
pushd "$TMPDIR" > /dev/null
cp "$1" "$basename.ts"
tsc "$basename"
node "$basename.js"
popd > /dev/null
rm -rf "$TMPDIR"
And now I can do things like this:
#!/usr/bin/env ts-exec
let greeting: string = "Hello World!";
console.log( greeting );
And it works.
Of course, it does have some limitations
It's only suitable for scripts that are confined to a single file
It doesn't do any error checking
It has implicit dependencies
It doesn't have an installer
... so basically it's for bash nerds who want to use TypeScript for small scripts that would be a pain to write as Bash scripts. I'm still baffled that ts-node doesn't cover this case, and I'd rather not have to futz with temp files that might get left behind and waste space if there's an error, but so far this covers my use-case. (Besides, I've got that cronjob that deletes everything in ~/tmp that's more than 31622400 seconds old every night, so stray temp files can't eat my whole system.)
As of ts-node v8.9.0 it seems like the recommended way to do this is with the following:
#!/usr/bin/env ts-node-script
If you don't want to install TS and ts-node globally and want to make the script runnable by the file path directly, create a file for example cli.ts next to local node_modules and put this as the first line
#!/usr/bin/env ./node_modules/.bin/ts-node
console.log('Wow');
Then execute by calling ./cli.ts
I use two separate shell scripts to run my two server, one is Django and another is npm.
Django Command is: python3 backend/manage.py runserver and npm command is: npm start
I write shell script to run my Django server:
This is my startserver.sh file to run Django server
#!/bin/bash
python3 backend/manage.py runserver $1
and this is my startnode.sh file to run npm server
#!/bin/bash
npm start $1
both are working fine.
I want, when I run ./startserver.sh in terminal, it should run this python3 backend/manage.py runserver command in the current tab of the terminal, in the same time, the script should open another tab in the terminal and run this command: npm start
I mean, in one shell script, I want to run two script in same windows two tab of the terminal.
I will just run ./startserver and it should run above two command in two different tab.
I think this command will be help you.
xterm -e [your_args]
maybe your_args will be startnode.sh
In detail, you can script your startserver.sh
#!/bin/bash
python3 backend/manage.py runserver $1
xterm -e “./startnode.sh”
like this.
[Reference]
Opening new terminal in shell script
Start xterm with different shell and execute commands
Solution 1:
tmux
tmux new-session -d 1.sh \; split-window -h 2.sh \; attach
Solution 2:
gnome terminal
Read : Opening multiple terminal tabs and running command
for i in 1 2; do
options+=($tab -e "bash -c '${cmds[i]} ; bash'" )
done
gnome-terminal "${options[#]}"
Update
Read Terminal Multiplexers
Let's say you have both scripts saved under your home directory called a.sh and b.sh. Then make another script combined.sh with the following
sh ~/a.sh &
sh ~/b.sh
Basically, you're just calling both scripts, but you background the first one to allow continuing execution to the next script.
I'm definitely a command line novice. I have recently lost the ability to execute shell scripts using
./script.sh
I am still able to execute shell scripts using:
sh script.sh
My $PATH is as follows:
/Users/goodguy/.pyenv/shims:/Users/goodguy/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin:/opt/local/sbin:/Users/goodguy/.rvm/bin
I am using MacOS. I'd appreciate any insight into what I may be doing wrong
you can run command chmod 755 script.sh
and then run the script with ./script.sh
I have a node.js executable script which usually starts with:
#!/usr/bin/env node
var ...
In order to use a command line argument --use_strict on the node.js binary, I'd need to change this to
#!/usr/bin/env node --use_strict
which could possibly screw up for other people.
Is there a way to check if --use_strict has been provided when calling the script and then pass it to the node executable?
something like
./myscript --use_strict
---
if --use_strict
#!/usr/bin/env node --use_strict
else
#!/usr/bin/env node
#!/usr/bin/env node will instruct the operating system to call the command after the #! ("shebang") on the file. If your script is in the file your-node-script, the OS basically runs this:
/usr/bin/env node your-node-script
The env command will search for the first argument in your environment and execute it with the remaining arguments. If your node executable is in /usr/bin/node, on your system it will call:
/usr/bin/node your-node-script
To solve your problem, you just write a wrapper script which does the same to call your node script:
#!/bin/bash
/usr/bin/env node --use-strict your-node-script "$#"
Or:
#!/bin/bash
/usr/bin/node --use-strict your-node-script "$#"
(Which only works on systems where node acrually is in /usr/bin.
Edit: Parameters are now forwarded (thanks Etan Reisner).
Normally in node files I just put
#!/usr/bin/env node
at the top and make it executable to create a file that can be run from a bash terminal. However if I do that in a Typescript file, the compiler says "error TS1001: Unexpected character "#"" and refuses to compile it. So how can I make a shell executable node file with Typescript?
See https://github.com/Microsoft/TypeScript/blob/master/bin/tsc for an example. Basically have a dummy file without the .js extension and just require the actual .js file.
E.g. In file named tsc:
#!/usr/bin/env node
require('./tsc.js')
You were right to report the bug to Microsoft, and they were wrong to close it as wontfix.
Until it is fixed, here's a workaround. Paste the following into a text file and save it as shebangify:
#!/usr/bin/env node
var fs = require('fs');
var path = process.argv[2];
var data = "#!/usr/bin/env node\n\n";
data += fs.readFileSync(path);
fs.writeFileSync(path, data);
(N.B. To keep this answer concise, the code above doesn't have any error-checking or other refinements, so use at your own risk or use this instead. Also, see this SO question for more info about prepending to files.)
Make the file executable with by using a terminal to navigate to the file's directory and executing:
$ chmod +x shebangify
Once you have created a Typescript program (e.g. called myscript.ts) that you wish to compile and turn into a shell script (e.g. called myscript), do so by executing a sequence along these lines in your terminal:
$ tsc --out myscript myscript.ts ; ./shebangify myscript ; chmod +x myscript
If you have TypeScript and ts-node installed globally:
npm install typescript ts-node -g
You can now easily do this with:
#!/usr/bin/env ts-node
console.log('Hello world')
I don't have enough reputation points to post a comment, but I'd just thought it'd be good for everyone to know that I opened a new issue on GitHub since that's what the Typescript devs are using to track things like this: https://github.com/Microsoft/TypeScript/issues/2749 .
In case anyone is still struggling with making it work, the ts file should start with #! node instead of #!/usr/bin/env node, and tsc will take care of the rest.
I've never been able to get ts-node to work, so I finally made my own way to write shell scripts in TypeScript. If there were a package manager for Bash I would make a package, but there isn't, so I just put this script in my path as ts-exec:
#!/usr/bin/env bash
file_to_run="$1"
basename=`basename "$1"`
tmp_prefix=`basename "$BASH_SOURCE"`
TMPDIR=`mktemp -d -t "$tmp_prefix-XXXXXXXXXX"`
pushd "$TMPDIR" > /dev/null
cp "$1" "$basename.ts"
tsc "$basename"
node "$basename.js"
popd > /dev/null
rm -rf "$TMPDIR"
And now I can do things like this:
#!/usr/bin/env ts-exec
let greeting: string = "Hello World!";
console.log( greeting );
And it works.
Of course, it does have some limitations
It's only suitable for scripts that are confined to a single file
It doesn't do any error checking
It has implicit dependencies
It doesn't have an installer
... so basically it's for bash nerds who want to use TypeScript for small scripts that would be a pain to write as Bash scripts. I'm still baffled that ts-node doesn't cover this case, and I'd rather not have to futz with temp files that might get left behind and waste space if there's an error, but so far this covers my use-case. (Besides, I've got that cronjob that deletes everything in ~/tmp that's more than 31622400 seconds old every night, so stray temp files can't eat my whole system.)
As of ts-node v8.9.0 it seems like the recommended way to do this is with the following:
#!/usr/bin/env ts-node-script
If you don't want to install TS and ts-node globally and want to make the script runnable by the file path directly, create a file for example cli.ts next to local node_modules and put this as the first line
#!/usr/bin/env ./node_modules/.bin/ts-node
console.log('Wow');
Then execute by calling ./cli.ts