I have a text file where each line is a list of arguments I want to pass to a nodejs script. Here's an example file, file.txt:
"This is the first argument" "This is the second argument"
For demonstration's sake, the node script is simply:
console.log(process.argv.slice(2));
I want to run this node script for every line in the text file, so I made this bash script, run.sh:
while read line; do
node script.js $line
done < file.txt
When I run this bash script, this is what I get:
$ ./run.sh
[ '"This',
'is',
'the',
'first',
'argument"',
'"This',
'is',
'the',
'second',
'argument"' ]
But when I just run the node script directly I get the expected output:
$ node script.js "This is the first argument" "This is the second argument"
[ 'This is the first argument',
'This is the second argument' ]
What's going on here? Is there a more node-ish way to do this?
To invoke a function, simply use the function name as a command. To pass parameters to the function, add space separated arguments like other commands. The passed parameters can be accessed inside the function using the standard positional variables i.e. $0, $1, $2, $3 etc.
In a shell script, you can pass variables as arguments by entering arguments after the script name, for example ./script.sh arg1 arg2 . The shell automatically assigns each argument name to a variable. Arguments are set of characters between spaces added after the script.
$@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.
What's going on here is that $line
isn't getting sent to your program in the way you expect. If you add the -x
flag at the beginning of your script (like #!/bin/bash -x
, for example), you can see every line as it's being interpreted before it gets executed. For your script, the output looks like this:
$ ./run.sh
+ read line
+ node script.js '"This' is the first 'argument"' '"This' is the second 'argument"'
[ '"This',
'is',
'the',
'first',
'argument"',
'"This',
'is',
'the',
'second',
'argument"' ]
+ read line
See all those single-quotes? They're definitely not where you want them to be. You can use eval
to get everything quoted correctly. This script:
while read line; do
eval node script.js $line
done < file.txt
Gives me the correct output:
$ ./run.sh
[ 'This is the first argument', 'This is the second argument' ]
Here's the -x
output too, for comparison:
$ ./run.sh
+ read line
+ eval node script.js '"This' is the first 'argument"' '"This' is the second 'argument"'
++ node script.js 'This is the first argument' 'This is the second argument'
[ 'This is the first argument', 'This is the second argument' ]
+ read line
You can see that in this case, after the eval
step, the quotes are in the places you want them to be. Here's the documentation on eval
from the bash(1)
man page:
eval [arg ...]
The args are read and concatenated together into a single command. This command is then read and executed by the shell, and its exit status is returned as the value of eval. If there are no args, or only null arguments, eval returns 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With