在没有全局变量的bash函数之间传递数组/列表

时间:2016-11-25 23:46:23

标签: bash

我在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};

}

希望你能看到我想做的事情并且可以提供帮助,谢谢

3 个答案:

答案 0 :(得分:2)

在下面,我们通过引用传递存储在局部变量中的参数列表:

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <chrono>

int main(int argc, char* argv[])
{
    auto fileIn = std::ifstream{"flip.in"};
    int commandSize;
    std::string commands;
    fileIn >> commandSize >> commands;

    std::vector<char> wordFront;
    std::vector<char> wordBack;
    wordFront.push_back('A');

    auto start = std::chrono::high_resolution_clock::now();
    for (auto v : commands)
    {
        switch(v)
        {
            case 'x':
                wordBack.push_back('A');
                break;
            case 'y':
                wordFront.push_back('B');
                break;
            case 'z':
                std::swap(wordFront, wordBack);
                break;
        }
    }
    auto finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = finish - start;
    std::cout << "Elapsed time (secs): " << elapsed.count() << std::endl;

    auto fileOut = std::ofstream{"flip.out"};

    std::for_each(crbegin(wordFront), crend(wordFront), [&fileOut](auto v){ fileOut << v; });
    std::for_each(cbegin(wordBack), cend(wordBack), [&fileOut](auto v){ fileOut << v; });
}

为什么会有所不同?因为我们也可以通过:

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" ) 将正确传递,正好是一个参数。

答案 1 :(得分:1)

你的解释有点不清楚,但我认为我得到了要点:单词拆分不像你在Bash中预期的那样工作。

您需要将$ {NODE_EXEC_ARGS}参数引用到第二个函数,因为在它是空格的情况下,它将被剥离并且不会形成被调用函数的参数:

__handle_global_suman "${NODE_EXEC_ARGS}" ${ORIGINAL_ARGS}

在您的示例中,$ {ORIGINAL_ARGS} var也是多余的。你应该直接传递“$ @”:

__handle_global_suman "${NODE_EXEC_ARGS}" "$@"

第二个提出的替代解决方案肯定不是必要,绝对是不好的做法,你绝对可以通过Bash函数参数传递实现你想要的。

答案 2 :(得分:0)

这对我有用,感谢@ S.Pinkus的帮助,因为答案中包含的信息是我解决问题所需要的所有答案。请注意以下工作,但@ CDhuffy的答案在理论上更通用,因此更好。

[0.0*, 0.9*]

bash太棒了;)......不是