У меня есть эти две функции в сценарии bash. Я просто пытаюсь передавать аргументы напрямую от одной функции к другой без использования глобальных переменных, но, похоже, я не могу этого сделать.

function suman {

  NODE_EXEC_ARGS= "--inspect"; 
  __handle_global_suman "${NODE_EXEC_ARGS}" "$@"

}


function __handle_global_suman {

  # I want $1 to be node exec args and $2 to be args to node script
  node $1 ${Z}/cli.js $2;

}

возникшая у меня проблема : в функции __handle_global_suman значения для $1 и $2, похоже, представляют исходные аргументы, переданные функции suman, а не аргументы, переданные __handle_global_suman! Я хочу иметь доступ к аргументам, передаваемым функции __handle_global_suman.

Одно из решений - использовать следующие глобальные переменные (но в целом это плохое программирование):

NODE_EXEC_ARGS="";  // default
ORIGINAL_ARGS="";  // default

function suman {

  NODE_EXEC_ARGS="--inspect";  
  ORIGINAL_ARGS="$@";  // assume this captures the arguments passed to this function, not the original script...
  __handle_global_suman
}

# ideally there would be a way to make this function truly private
function __handle_global_suman {

  # I want $1 to be node exec args and $2 to be args to node script
  node ${NODE_EXEC_ARGS} ${Z}/cli.js ${ORIGINAL_ARGS};

}

Надеюсь, вы понимаете, что я пытаюсь сделать, и можете помочь, спасибо

0
Alexander Mills 26 Ноя 2016 в 02:46

3 ответа

Лучший ответ

Ниже мы передаем список аргументов, хранящийся в локальной переменной по ссылке:

suman() {
   local -a args=( --inspect --debug-brk )
   __handle_global_suman args "$@"
}

__handle_global_suman() {
   local ref="$1[@]"; shift
   node "${!ref}" "${Z}/cli.js" "$@"
}

Почему это другое? Потому что мы также можем передать:

local -a args=( --inspect --argument-with-spaces="hello cruel world" )

... и --argument-with-spaces=... будет передан правильно, как ровно один аргумент.

2
Charles Duffy 26 Ноя 2016 в 00:50

Ваше объяснение немного неясно, но я думаю, что уловил суть: разделение слов в Bash работает не так, как вы ожидали.

Вам необходимо указать параметр $ {NODE_EXEC_ARGS} для второй функции, поскольку в случае, если это пробел, он будет удален и не будет формировать параметр для вызываемой функции:

__handle_global_suman "${NODE_EXEC_ARGS}" ${ORIGINAL_ARGS}

Также переменная $ {ORIGINAL_ARGS} избыточна в вашем примере. Вы должны просто передать "$ @" напрямую:

__handle_global_suman "${NODE_EXEC_ARGS}" "$@"

Второе предлагаемое альтернативное решение определенно не необходимо, определенно является плохой практикой, и вы определенно можете добиться желаемого с помощью передачи параметров функции Bash.

1
Jonathan Leffler 26 Ноя 2016 в 05:38

Вот что у меня работает, благодаря help @ S.Pinkus, за ответ которого я проголосовал, поскольку информация, содержащаяся в ответе, была всем, что мне нужно, чтобы решить проблему. Обратите внимание, что приведенный ниже вариант работает, но ответ @ CDhuffy теоретически более общий и, следовательно, лучше.

function suman {

   __handle_global_suman "--inspect --debug-brk" "$@"

}

function __handle_global_suman {

   # ${1} is "--inspect --debug-brk"
   # ${2} is whatever I passed to the suman function
   node ${1}  ${Z}/cli.js ${2};

}

Bash классный;) ... не

0
Alexander Mills 26 Ноя 2016 в 01:10