5

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?

1 Answer 1

9

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.