Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing quoted arguments to node via shell script?

Tags:

bash

node.js

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?

like image 874
Rafael Avatar asked Nov 20 '11 22:11

Rafael


People also ask

How do you pass arguments to a shell script?

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.

Can you pass variables in shell script?

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.

What is $@ in SH?

$@ 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.


1 Answers

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.

like image 196
Carl Norum Avatar answered Sep 29 '22 07:09

Carl Norum