передача аргументов в кавычках узлу через сценарий оболочки?

У меня есть текстовый файл, где каждая строка представляет собой список аргументов, которые я хочу передать скрипту nodejs. Вот пример файла file.txt:

"This is the first argument" "This is the second argument"

Для демонстрации сценарий узла выглядит просто:

console.log(process.argv.slice(2));

Я хочу запускать этот скрипт node для каждой строки в текстовом файле, поэтому я сделал этот скрипт bash, run.sh:

while read line; do
    node script.js $line
done < file.txt

Когда я запускаю этот bash-скрипт, вот что я получаю:

$ ./run.sh 
[ '"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' ]

Что тут происходит? Есть ли более узловой способ сделать это?


person Rafael    schedule 20.11.2011    source источник


Ответы (1)


Здесь происходит то, что $line не отправляется в вашу программу так, как вы ожидаете. Если вы добавите флаг -x в начале вашего скрипта (например, #!/bin/bash -x), вы сможете увидеть каждую строку в том виде, в каком она интерпретируется, прежде чем она будет выполнена. Для вашего скрипта вывод выглядит так:

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

Видите все эти одинарные кавычки? Они определенно не там, где вы хотите, чтобы они были. Вы можете использовать eval, чтобы все цитировалось правильно. Этот скрипт:

while read line; do
    eval node script.js $line
done < file.txt

Дает мне правильный вывод:

$ ./run.sh 
[ 'This is the first argument', 'This is the second argument' ]

Вот вывод -x для сравнения:

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

Вы можете видеть, что в этом случае после шага eval кавычки находятся там, где вы хотите. Вот документация по eval с bash(1) справочной страницы:

eval [аргумент ...]

аргументы считываются и объединяются в одну команду. Затем эта команда считывается и выполняется оболочкой, и ее статус выхода возвращается как значение eval. Если аргументов нет или есть только нулевые аргументы, eval возвращает 0.

person Carl Norum    schedule 20.11.2011